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

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


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

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

21 22 23 24 25
   Contact Information
   OpenAirInterface Admin: openair_admin@eurecom.fr
   OpenAirInterface Tech : openair_tech@eurecom.fr
   OpenAirInterface Dev  : openair4g-devel@eurecom.fr
  
ghaddab's avatar
ghaddab committed
26
   Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
27

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

/*! \file lte-softmodem.c
Raymond Knopp's avatar
 
Raymond Knopp committed
31
 * \brief main program to control HW and scheduling
32
 * \author R. Knopp, F. Kaltenberger, Navid Nikaein
Raymond Knopp's avatar
 
Raymond Knopp committed
33 34 35
 * \date 2012
 * \version 0.1
 * \company Eurecom
36
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
Raymond Knopp's avatar
 
Raymond Knopp committed
37 38 39
 * \note
 * \warning
 */
Raymond Knopp's avatar
 
Raymond Knopp committed
40
#define _GNU_SOURCE
41 42 43 44 45 46 47 48 49 50
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sched.h>
51
#include <linux/sched.h>
52 53 54
#include <signal.h>
#include <execinfo.h>
#include <getopt.h>
55
#include <syscall.h>
56 57

#include "rt_wrapper.h"
58 59
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all

60
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
61
static int hw_subframe;
Raymond Knopp's avatar
 
Raymond Knopp committed
62
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
63

64
#include "assertions.h"
65 66 67 68 69 70

#ifdef EMOS
#include <gps.h>
#endif

#include "PHY/types.h"
71

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

76
#ifdef EXMIMO
77
#include "openair0_lib.h"
Raymond Knopp's avatar
 
Raymond Knopp committed
78 79 80 81
#else
#include "../../ARCH/COMMON/common_lib.h"
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
82
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
83 84 85

#include "PHY/vars.h"
#include "MAC_INTERFACE/vars.h"
86
//#include "SCHED/defs.h"
87 88 89 90 91 92 93 94 95 96 97 98
#include "SCHED/vars.h"
#include "LAYER2/MAC/vars.h"

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

#ifdef EMOS
#include "SCHED/phy_procedures_emos.h"
#endif

#ifdef OPENAIR2
#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/vars.h"
99
#include "LAYER2/MAC/proto.h"
100 101 102 103 104 105 106 107 108 109 110
#ifndef CELLULAR
#include "RRC/LITE/vars.h"
#endif
#include "PHY_INTERFACE/vars.h"
#endif

#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
111
#include "UTIL/OTG/otg_tx.h"
112
#include "UTIL/OTG/otg_externs.h"
113 114
#include "UTIL/MATH/oml.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
115
#include "UTIL/OPT/opt.h"
116
#include "enb_config.h"
Navid Nikaein's avatar
Navid Nikaein committed
117
//#include "PHY/TOOLS/time_meas.h"
118

119 120
#if defined(ENABLE_ITTI)
# include "intertask_interface_init.h"
121
# include "create_tasks.h"
122 123 124
# if defined(ENABLE_USE_MME)
#   include "s1ap_eNB.h"
# endif
125 126
#endif

127 128 129
#ifdef XFORMS
#include "PHY/TOOLS/lte_phy_scope.h"
#include "stats.h"
130 131 132 133 134
#endif

#define FRAME_PERIOD    100000000ULL
#define DAQ_PERIOD      66667ULL

Raymond Knopp's avatar
 
Raymond Knopp committed
135
#define DEBUG_THREADS 1
Raymond Knopp's avatar
 
Raymond Knopp committed
136

Raymond Knopp's avatar
 
Raymond Knopp committed
137 138
//#define USRP_DEBUG 1

139 140 141 142 143 144 145
struct timing_info_t {
  //unsigned int frame, hw_slot, last_slot, next_slot;
  RTIME time_min, time_max, time_avg, time_last, time_now;
  //unsigned int mbox0, mbox1, mbox2, mbox_target;
  unsigned int n_samples;
} timing_info;

146 147
extern int16_t* sync_corr_ue0;
extern int16_t prach_ifft[4][1024*2];
148 149 150

int init_dlsch_threads(void);
void cleanup_dlsch_threads(void);
151
int32_t init_rx_pdsch_thread(void);
152
void cleanup_rx_pdsch_thread(void);
Raymond Knopp's avatar
 
Raymond Knopp committed
153

154
openair0_config_t openair0_cfg[MAX_CARDS];
Raymond Knopp's avatar
 
Raymond Knopp committed
155

Raymond Knopp's avatar
 
Raymond Knopp committed
156 157
int32_t **rxdata;
int32_t **txdata;
158 159
int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]);
int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]);
160 161

#ifdef XFORMS
162 163 164 165
// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
// at eNB 0, an UL scope for every UE 
FD_lte_phy_scope_ue  *form_ue[NUMBER_OF_UE_MAX];
FD_lte_phy_scope_enb *form_enb[NUMBER_OF_UE_MAX];
166
FD_stats_form                  *form_stats=NULL,*form_stats_l2=NULL;
167
char title[255];
168
unsigned char                   scope_enb_num_ue = 1;
169 170 171
#endif //XFORMS

#ifdef RTAI
172
static SEM                     *mutex;
173 174
//static CND *cond;

175 176
static long                      main_eNB_thread;
static long                      main_ue_thread;
Raymond Knopp's avatar
 
Raymond Knopp committed
177
static SEM *sync_sem; // to sync rx & tx streaming
178

179 180
//static int sync_thread;
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
181 182
pthread_t                       main_eNB_thread;
pthread_t                       main_ue_thread;
183
pthread_attr_t                  attr_dlsch_threads;
184
#ifndef LOWLATENCY
185
struct sched_param              sched_param_dlsch;
186
#endif 
Raymond Knopp's avatar
 
Raymond Knopp committed
187

Raymond Knopp's avatar
 
Raymond Knopp committed
188 189
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
190
int sync_var=-1;
191
#endif
192

Raymond Knopp's avatar
 
Raymond Knopp committed
193
RTIME T0;
194

Raymond Knopp's avatar
 
Raymond Knopp committed
195 196 197 198 199 200
pthread_attr_t                  attr_UE_init_synch;
pthread_attr_t                  attr_UE_thread_tx;
pthread_attr_t                  attr_UE_thread_rx;
struct sched_param              sched_param_UE_init_synch;
struct sched_param              sched_param_UE_thread_tx;
struct sched_param              sched_param_UE_thread_rx;
201 202 203 204

pthread_attr_t                  attr_eNB_proc_tx[MAX_NUM_CCs][10];
pthread_attr_t                  attr_eNB_proc_rx[MAX_NUM_CCs][10];
#ifndef LOWLATENCY
Raymond Knopp's avatar
 
Raymond Knopp committed
205 206
struct sched_param              sched_param_eNB_proc_tx[MAX_NUM_CCs][10];
struct sched_param              sched_param_eNB_proc_rx[MAX_NUM_CCs][10];
207
#endif
208
#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
209
static pthread_t                forms_thread; //xforms
210 211 212 213
#endif
#ifdef EMOS
static pthread_t                thread3; //emos
#endif
214

215 216 217 218
#ifdef SPECTRA
static pthread_t sensing_thread;
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
219 220 221
openair0_device openair0;
openair0_timestamp timestamp;

222
/*
Raymond Knopp's avatar
 
Raymond Knopp committed
223 224 225
  static int instance_cnt=-1; //0 means worker is busy, -1 means its free
  int instance_cnt_ptr_kern,*instance_cnt_ptr_user;
  int pci_interface_ptr_kern;
226 227 228 229
*/
//extern unsigned int bigphys_top;
//extern unsigned int mem_base;

230
int                             card = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
231

232

233
#if defined(ENABLE_ITTI)
234 235
static volatile int             start_eNB = 0;
static volatile int             start_UE = 0;
236
#endif
237 238 239 240 241 242
volatile int                    oai_exit = 0;

//static int                      time_offset[4] = {-138,-138,-138,-138};
//static int                      time_offset[4] = {-145,-145,-145,-145};
static int                      time_offset[4] = {0,0,0,0};

Raymond Knopp's avatar
 
Raymond Knopp committed
243

244
static char                     UE_flag=0;
245
static uint8_t                  eNB_id=0,UE_id=0;
246

247
//uint32_t                        carrier_freq[MAX_NUM_CCs][4] =           {{1907600000,1907600000,1907600000,1907600000}}; /* For UE! */
248 249 250
static uint32_t                 downlink_frequency[MAX_NUM_CCs][4] =     {{1907600000,1907600000,1907600000,1907600000},
									  {1907600000,1907600000,1907600000,1907600000}};
static int32_t                  uplink_frequency_offset[MAX_NUM_CCs][4]= {{0,0,0,0},{0,0,0,0}};
251 252

openair0_rf_map rf_map[MAX_NUM_CCs];
253

254
static char                    *conf_config_file_name = NULL;
255
#if defined(ENABLE_ITTI)
256
static char                    *itti_dump_file = NULL;
Raymond Knopp's avatar
 
Raymond Knopp committed
257 258
#endif

Lionel Gauthier's avatar
Lionel Gauthier committed
259
#ifndef USRP
260 261
double tx_gain[MAX_NUM_CCs][4] = {{20,20,0,0},{20,20,0,0}};
double rx_gain[MAX_NUM_CCs][4] = {{20,20,0,0},{20,20,0,0}};
262
// these are for EXMIMO2 target only
263
/*
264 265 266
static unsigned int             rxg_max[4] =    {133,133,133,133};
static unsigned int             rxg_med[4] =    {127,127,127,127};
static unsigned int             rxg_byp[4] =    {120,120,120,120};
267 268 269 270 271 272 273 274
*/
// these are for EXMIMO2 card 39
static unsigned int             rxg_max[4] =    {128,128,128,126};
static unsigned int             rxg_med[4] =    {122,123,123,120};
static unsigned int             rxg_byp[4] =    {116,117,116,116};
static unsigned int             nf_max[4] =    {7,9,16,12};
static unsigned int             nf_med[4] =    {12,13,22,17};
static unsigned int             nf_byp[4] =    {15,20,29,23};
275
static 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}};
Lionel Gauthier's avatar
Lionel Gauthier committed
276
#else
277
double tx_gain[MAX_NUM_CCs][4] = {{120,0,0,0}};
Raymond Knopp's avatar
 
Raymond Knopp committed
278
double rx_gain[MAX_NUM_CCs][4] = {{125,0,0,0}};
Lionel Gauthier's avatar
Lionel Gauthier committed
279
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
280

Raymond Knopp's avatar
 
Raymond Knopp committed
281 282
double sample_rate=30.72e6;
double bw = 14e6;
283

284
static int                      tx_max_power[MAX_NUM_CCs] =  {0,0};
285

286
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
287 288 289
char ref[128] = "internal";
char channels[128] = "0";

Raymond Knopp's avatar
 
Raymond Knopp committed
290 291 292
unsigned int samples_per_frame = 307200;
unsigned int samples_per_packets = 2048; // samples got every recv or send
unsigned int tx_forward_nsamps;
Raymond Knopp's avatar
 
Raymond Knopp committed
293

Raymond Knopp's avatar
 
Raymond Knopp committed
294 295 296
int sf_bounds_5[10]    = {8, 15, 23, 30, 38, 45, 53, 60, 68, 75};
int sf_bounds_5_tx[10] = {4, 11, 19, 26, 34, 41, 49, 56, 64, 71};

Raymond Knopp's avatar
 
Raymond Knopp committed
297
int sf_bounds_10[10] = {8, 15, 23, 30, 38, 45, 53, 60, 68, 75};
Raymond Knopp's avatar
 
Raymond Knopp committed
298 299
int sf_bounds_10_tx[10] = {4, 11, 19, 26, 34, 41, 49, 56, 64, 71};

Raymond Knopp's avatar
 
Raymond Knopp committed
300
int sf_bounds_20[10] = {15, 30, 45, 60, 75, 90, 105, 120, 135, 150};
Raymond Knopp's avatar
 
Raymond Knopp committed
301 302
int sf_bounds_20_tx[10] = {7, 22, 37, 52, 67, 82, 97, 112, 127, 142};

Raymond Knopp's avatar
 
Raymond Knopp committed
303
int *sf_bounds;
Raymond Knopp's avatar
 
Raymond Knopp committed
304 305
int *sf_bounds_tx;

Raymond Knopp's avatar
 
Raymond Knopp committed
306 307 308 309
int max_cnt;
int tx_delay;

#endif
310
/*
Raymond Knopp's avatar
 
Raymond Knopp committed
311 312 313
  uint32_t rf_mode_max[4]     = {55759,55759,55759,55759};
  uint32_t rf_mode_med[4]     = {39375,39375,39375,39375};
  uint32_t rf_mode_byp[4]     = {22991,22991,22991,22991};
314
*/
Raymond Knopp's avatar
 
Raymond Knopp committed
315 316
//static uint32_t                      rf_mode[4] =        {MY_RF_MODE,0,0,0};
//static uint32_t                      rf_local[4] =       {8255000,8255000,8255000,8255000}; // UE zepto
Raymond Knopp's avatar
 
Raymond Knopp committed
317 318
//{8254617, 8254617, 8254617, 8254617}; //eNB khalifa
//{8255067,8254810,8257340,8257340}; // eNB PETRONAS
319

Raymond Knopp's avatar
 
Raymond Knopp committed
320 321 322 323 324
//static uint32_t                      rf_vcocal[4] =      {910,910,910,910};
//static uint32_t                      rf_vcocal_850[4] =  {2015, 2015, 2015, 2015};
//static uint32_t                      rf_rxdc[4] =        {32896,32896,32896,32896};
//static uint32_t                      rxgain[4] =         {20,20,20,20};
//static uint32_t                      txgain[4] =         {20,20,20,20};
325 326 327

static runmode_t                mode;
static int                      rx_input_level_dBm;
328
static int                      online_log_messages=0;
329
#ifdef XFORMS
330
extern int                      otg_enabled;
331
static char                     do_forms=0;
332
#else
333
int                             otg_enabled;
334
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
335
//int                             number_of_cards =   1;
Raymond Knopp's avatar
 
Raymond Knopp committed
336
#ifndef USRP
337 338
static int                      mbox_bounds[20] =   {8,16,24,30,38,46,54,60,68,76,84,90,98,106,114,120,128,136,144, 0}; ///boundaries of slots in terms ob mbox counter rounded up to even numbers
//static int                      mbox_bounds[20] =   {6,14,22,28,36,44,52,58,66,74,82,88,96,104,112,118,126,134,142, 148}; ///boundaries of slots in terms ob mbox counter rounded up to even numbers
Raymond Knopp's avatar
 
Raymond Knopp committed
339
#endif
340

Raymond Knopp's avatar
 
Raymond Knopp committed
341
static LTE_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
342

Raymond Knopp's avatar
 
Raymond Knopp committed
343
int multi_thread=1;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
344
uint32_t target_dl_mcs = 28; //maximum allowed mcs
345
uint32_t target_ul_mcs = 10;
346 347
uint8_t exit_missed_slots=1;
uint64_t num_missed_slots=0; // counter for the number of missed slots
348

349 350 351 352
time_stats_t softmodem_stats_mt; // main thread
time_stats_t softmodem_stats_hw; //  hw acquisation
time_stats_t softmodem_stats_tx_sf[10]; // total tx time 
time_stats_t softmodem_stats_rx_sf[10]; // total rx time 
Navid Nikaein's avatar
Navid Nikaein committed
353 354
void reset_opp_meas(void);
void print_opp_meas(void);
355
int transmission_mode=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
356

Lionel Gauthier's avatar
 
Lionel Gauthier committed
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
int16_t           glog_level         = LOG_DEBUG;
int16_t           glog_verbosity     = LOG_MED;
int16_t           hw_log_level       = LOG_DEBUG;
int16_t           hw_log_verbosity   = LOG_MED;
int16_t           phy_log_level      = LOG_DEBUG;
int16_t           phy_log_verbosity  = LOG_MED;
int16_t           mac_log_level      = LOG_DEBUG;
int16_t           mac_log_verbosity  = LOG_MED;
int16_t           rlc_log_level      = LOG_DEBUG;
int16_t           rlc_log_verbosity  = LOG_MED;
int16_t           pdcp_log_level     = LOG_DEBUG;
int16_t           pdcp_log_verbosity = LOG_MED;
int16_t           rrc_log_level      = LOG_DEBUG;
int16_t           rrc_log_verbosity  = LOG_MED;
# if defined(ENABLE_USE_MME)
int16_t           gtpu_log_level     = LOG_DEBUG;
int16_t           gtpu_log_verbosity = LOG_MED;
int16_t           udp_log_level      = LOG_DEBUG;
int16_t           udp_log_verbosity  = LOG_MED;
#endif
377 378 379 380
#if defined (ENABLE_SECURITY)
int16_t           osa_log_level      = LOG_INFO;
int16_t           osa_log_verbosity  = LOG_MED;
#endif 
381

382
unsigned int build_rflocal(int txi, int txq, int rxi, int rxq)
383
{
Raymond Knopp's avatar
 
Raymond Knopp committed
384
  return (txi + (txq<<6) + (rxi<<12) + (rxq<<18));
385 386 387
}
unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
388
  return (dcoff_i_rxfe + (dcoff_q_rxfe<<8));
389 390
}

391 392 393 394 395 396 397 398 399 400 401 402
#ifdef LOWLATENCY
int sched_setattr(pid_t pid, const struct sched_attr *attr, unsigned int flags) {

  return syscall(__NR_sched_setattr, pid, attr, flags);
}


int sched_getattr(pid_t pid,struct sched_attr *attr,unsigned int size, unsigned int flags){

  return syscall(__NR_sched_getattr, pid, attr, size, flags);
}
#endif 
403
#if !defined(ENABLE_ITTI)
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418
void signal_handler(int sig)
{
  void *array[10];
  size_t size;

  if (sig==SIGSEGV) {
    // get void*'s for all entries on the stack
    size = backtrace(array, 10);
    
    // print out all the frames to stderr
    fprintf(stderr, "Error: signal %d:\n", sig);
    backtrace_symbols_fd(array, size, 2);
    exit(-1);
  }
  else {
419
    printf("trying to exit gracefully...\n"); 
420
    oai_exit = 1;
421 422
  }
}
423
#endif
424 425 426

void exit_fun(const char* s)
{
427
  if (s != NULL) {
428
    printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s);
429 430 431 432 433
  }

  oai_exit = 1;

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

  //rt_sleep_ns(FRAME_PERIOD);

  //exit (-1);
}

Raymond Knopp's avatar
 
Raymond Knopp committed
443 444 445
static int latency_target_fd = -1;
static int32_t latency_target_value = 0;
/* Latency trick - taken from cyclictest.c 
Raymond Knopp's avatar
 
Raymond Knopp committed
446 447 448 449 450 451 452 453 454
 * if the file /dev/cpu_dma_latency exists,
 * open it and write a zero into it. This will tell
 * the power management system not to transition to
 * a high cstate (in fact, the system acts like idle=poll)
 * When the fd to /dev/cpu_dma_latency is closed, the behavior
 * goes back to the system default.
 *
 * Documentation/power/pm_qos_interface.txt
 */
Raymond Knopp's avatar
 
Raymond Knopp committed
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
static void set_latency_target(void)
{
  struct stat s;
  int ret;
  if (stat("/dev/cpu_dma_latency", &s) == 0) {
    latency_target_fd = open("/dev/cpu_dma_latency", O_RDWR);
    if (latency_target_fd == -1)
      return;
    ret = write(latency_target_fd, &latency_target_value, 4);
    if (ret == 0) {
      printf("# error setting cpu_dma_latency to %d!: %s\n", latency_target_value, strerror(errno));
      close(latency_target_fd);
      return;
    }
    printf("# /dev/cpu_dma_latency set to %dus\n", latency_target_value);
  }
}
Raymond Knopp's avatar
 
Raymond Knopp committed
472
 
473
#ifdef XFORMS
474 475 476 477

void reset_stats(FL_OBJECT *button, long arg) {
  int i,j,k;
  PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[0][0];
478 479 480 481 482 483 484 485 486 487 488 489
  for (i=0;i<NUMBER_OF_UE_MAX;i++) {
    for (k=0;k<8;k++) {//harq_processes
      for (j=0;j<phy_vars_eNB->dlsch_eNB[i][0]->Mdlharq;j++) {
	phy_vars_eNB->eNB_UE_stats[i].dlsch_NAK[k][j]=0;
	phy_vars_eNB->eNB_UE_stats[i].dlsch_ACK[k][j]=0;
	phy_vars_eNB->eNB_UE_stats[i].dlsch_trials[k][j]=0;
      }
      phy_vars_eNB->eNB_UE_stats[i].dlsch_l2_errors[k]=0;
      phy_vars_eNB->eNB_UE_stats[i].ulsch_errors[k]=0;
      phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors=0;
      for (j=0;j<phy_vars_eNB->ulsch_eNB[i]->Mdlharq;j++) {
	phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[k][j]=0;
490 491 492
      phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts_last[k][j]=0;
      phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors[k][j]=0;
      phy_vars_eNB->eNB_UE_stats[i].ulsch_round_fer[k][j]=0;
493
      }
494
    }
495 496 497
    phy_vars_eNB->eNB_UE_stats[i].dlsch_sliding_cnt=0;
    phy_vars_eNB->eNB_UE_stats[i].dlsch_NAK_round0=0;
    phy_vars_eNB->eNB_UE_stats[i].dlsch_mcs_offset=0;
498 499 500
  }
}

501
static void *scope_thread(void *arg) {
Raymond Knopp's avatar
 
Raymond Knopp committed
502
  char stats_buffer[16384];
503
# ifdef ENABLE_XFORMS_WRITE_STATS
Raymond Knopp's avatar
 
Raymond Knopp committed
504 505
  FILE *UE_stats, *eNB_stats;
  int len = 0;
506
# endif
Raymond Knopp's avatar
 
Raymond Knopp committed
507
  struct sched_param sched_param;
508

Raymond Knopp's avatar
 
Raymond Knopp committed
509 510
  sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1; 
  sched_setscheduler(0, SCHED_FIFO,&sched_param);
511

Raymond Knopp's avatar
 
Raymond Knopp committed
512
  printf("Scope thread has priority %d\n",sched_param.sched_priority);
513
    
514 515
# ifdef ENABLE_XFORMS_WRITE_STATS
  if (UE_flag==1) 
Raymond Knopp's avatar
 
Raymond Knopp committed
516
    UE_stats  = fopen("UE_stats.txt", "w");
517
  else 
Raymond Knopp's avatar
 
Raymond Knopp committed
518
    eNB_stats = fopen("eNB_stats.txt", "w");
519
#endif
520
    
Raymond Knopp's avatar
 
Raymond Knopp committed
521 522
  while (!oai_exit) {
    if (UE_flag==1) {
523
# ifdef ENABLE_XFORMS_WRITE_STATS
Raymond Knopp's avatar
 
Raymond Knopp committed
524
      len =
525
# endif
526
	dump_ue_stats (PHY_vars_UE_g[0][0], stats_buffer, 0, mode,rx_input_level_dBm);
Raymond Knopp's avatar
 
Raymond Knopp committed
527
      fl_set_object_label(form_stats->stats_text, stats_buffer);
528

Raymond Knopp's avatar
 
Raymond Knopp committed
529
      phy_scope_UE(form_ue[UE_id], 
530
		   PHY_vars_UE_g[UE_id][0],
Raymond Knopp's avatar
 
Raymond Knopp committed
531 532
		   eNB_id,
		   UE_id,7);
533
            
Raymond Knopp's avatar
 
Raymond Knopp committed
534
    } else {
535
# ifdef ENABLE_XFORMS_WRITE_STATS
Raymond Knopp's avatar
 
Raymond Knopp committed
536
      len =
537
# endif
538 539
      dump_eNB_l2_stats (stats_buffer, 0);
      fl_set_object_label(form_stats_l2->stats_text, stats_buffer);
540 541 542 543 544 545 546

# ifdef ENABLE_XFORMS_WRITE_STATS
      len =
# endif
	dump_eNB_stats (PHY_vars_eNB_g[0][0], stats_buffer, 0);
      fl_set_object_label(form_stats->stats_text, stats_buffer);

Raymond Knopp's avatar
 
Raymond Knopp committed
547 548
      for(UE_id=0;UE_id<scope_enb_num_ue;UE_id++) {
	phy_scope_eNB(form_enb[UE_id], 
Raymond Knopp's avatar
 
Raymond Knopp committed
549
		      PHY_vars_eNB_g[eNB_id][0],
Raymond Knopp's avatar
 
Raymond Knopp committed
550 551
		      UE_id);
      }
552 553
              
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
554
    //printf("doing forms\n");
Florian Kaltenberger's avatar
Florian Kaltenberger committed
555 556
    //usleep(100000); // 100 ms
    sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
557
  }
558 559

  printf("%s",stats_buffer);
560
    
561
# ifdef ENABLE_XFORMS_WRITE_STATS
562 563 564 565 566 567 568 569 570 571 572 573 574 575
  if (UE_flag==1) {
    if (UE_stats) {
      rewind (UE_stats);
      fwrite (stats_buffer, 1, len, UE_stats);
      fclose (UE_stats);
    }
  }
  else {
    if (eNB_stats) {
      rewind (eNB_stats);
      fwrite (stats_buffer, 1, len, eNB_stats);
      fclose (eNB_stats);
    }
  }
576
# endif
577
    
Raymond Knopp's avatar
 
Raymond Knopp committed
578
  pthread_exit((void*)arg);
579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603
}
#endif

#ifdef EMOS
#define NO_ESTIMATES_DISK 100 //No. of estimates that are aquired before dumped to disk

void *emos_thread (void *arg)
{
  char c;
  char *fifo2file_buffer, *fifo2file_ptr;

  int fifo, counter=0, bytes;

  FILE  *dumpfile_id;
  char  dumpfile_name[1024];
  time_t starttime_tmp;
  struct tm starttime;
  
  int channel_buffer_size;
  
  time_t timer;
  struct tm *now;

  struct gps_data_t *gps_data = NULL;
  struct gps_fix_t dummy_gps_data;
604 605 606 607 608 609 610

  struct sched_param sched_param;
  
  sched_param.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; 
  sched_setscheduler(0, SCHED_FIFO,&sched_param);
  
  printf("EMOS thread has priority %d\n",sched_param.sched_priority);
611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
 
  timer = time(NULL);
  now = localtime(&timer);

  memset(&dummy_gps_data,1,sizeof(struct gps_fix_t));
  
  gps_data = gps_open("127.0.0.1","2947");
  if (gps_data == NULL) 
    {
      printf("[EMOS] Could not open GPS\n");
      //exit(-1);
    }
#if GPSD_API_MAJOR_VERSION>=4
  else if (gps_stream(gps_data, WATCH_ENABLE,NULL) != 0)
#else
  else if (gps_query(gps_data, "w+x") != 0)
#endif
    {
      //sprintf(tmptxt,"Error sending command to GPS, gps_data = %x", gps_data);
      printf("[EMOS] Error sending command to GPS\n");
      //exit(-1);
    }
633 634
  else 
    printf("[EMOS] Opened GPS, gps_data=%p\n");
635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679
  
  if (UE_flag==0)
    channel_buffer_size = sizeof(fifo_dump_emos_eNB);
  else
    channel_buffer_size = sizeof(fifo_dump_emos_UE);

  // allocate memory for NO_FRAMES_DISK channes estimations
  fifo2file_buffer = malloc(NO_ESTIMATES_DISK*channel_buffer_size);
  fifo2file_ptr = fifo2file_buffer;

  if (fifo2file_buffer == NULL)
    {
      printf("[EMOS] Cound not allocate memory for fifo2file_buffer\n");
      exit(EXIT_FAILURE);
    }

  if ((fifo = open(CHANSOUNDER_FIFO_DEV, O_RDONLY)) < 0)
    {
      fprintf(stderr, "[EMOS] Error opening the fifo\n");
      exit(EXIT_FAILURE);
    }


  time(&starttime_tmp);
  localtime_r(&starttime_tmp,&starttime);
  snprintf(dumpfile_name,1024,"/tmp/%s_data_%d%02d%02d_%02d%02d%02d.EMOS",
	   (UE_flag==0) ? "eNB" : "UE",
	   1900+starttime.tm_year, starttime.tm_mon+1, starttime.tm_mday, starttime.tm_hour, starttime.tm_min, starttime.tm_sec);

  dumpfile_id = fopen(dumpfile_name,"w");
  if (dumpfile_id == NULL)
    {
      fprintf(stderr, "[EMOS] Error opening dumpfile %s\n",dumpfile_name);
      exit(EXIT_FAILURE);
    }


  printf("[EMOS] starting dump, channel_buffer_size=%d ...\n",channel_buffer_size);
  while (!oai_exit)
    {
      bytes = rtf_read_timed(fifo, fifo2file_ptr, channel_buffer_size,100);
      if (bytes==0)
	continue;

      /*
Raymond Knopp's avatar
 
Raymond Knopp committed
680
	if (UE_flag==0)
681
	printf("eNB: count %d, frame %d, read: %d bytes from the fifo\n",counter, ((fifo_dump_emos_eNB*)fifo2file_ptr)->frame_tx,bytes);
Raymond Knopp's avatar
 
Raymond Knopp committed
682
	else
683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743
	printf("UE: count %d, frame %d, read: %d bytes from the fifo\n",counter, ((fifo_dump_emos_UE*)fifo2file_ptr)->frame_rx,bytes);
      */

      fifo2file_ptr += channel_buffer_size;
      counter ++;

      if (counter == NO_ESTIMATES_DISK)
        {
          //reset stuff
          fifo2file_ptr = fifo2file_buffer;
          counter = 0;

          //flush buffer to disk
	  if (UE_flag==0)
	    printf("[EMOS] eNB: count %d, frame %d, flushing buffer to disk\n",
		   counter, ((fifo_dump_emos_eNB*)fifo2file_ptr)->frame_tx);
	  else
	    printf("[EMOS] UE: count %d, frame %d, flushing buffer to disk\n",
		   counter, ((fifo_dump_emos_UE*)fifo2file_ptr)->frame_rx);


          if (fwrite(fifo2file_buffer, sizeof(char), NO_ESTIMATES_DISK*channel_buffer_size, dumpfile_id) != NO_ESTIMATES_DISK*channel_buffer_size)
            {
              fprintf(stderr, "[EMOS] Error writing to dumpfile\n");
              exit(EXIT_FAILURE);
            }
	  if (gps_data)
	    {
	      if (gps_poll(gps_data) != 0) {
		printf("[EMOS] problem polling data from gps\n");
	      }
	      else {
		printf("[EMOS] lat %g, lon %g\n",gps_data->fix.latitude,gps_data->fix.longitude);
	      }
	      if (fwrite(&(gps_data->fix), sizeof(char), sizeof(struct gps_fix_t), dumpfile_id) != sizeof(struct gps_fix_t))
		{
		  printf("[EMOS] Error writing to dumpfile, stopping recording\n");
		  exit(EXIT_FAILURE);
		}
	    }
	  else
	    {
	      printf("[EMOS] WARNING: No GPS data available, storing dummy packet\n");
	      if (fwrite(&(dummy_gps_data), sizeof(char), sizeof(struct gps_fix_t), dumpfile_id) != sizeof(struct gps_fix_t))
		{
		  printf("[EMOS] Error writing to dumpfile, stopping recording\n");
		  exit(EXIT_FAILURE);
		}
	    } 
        }
    }
  
  free(fifo2file_buffer);
  fclose(dumpfile_id);
  close(fifo);
  
  pthread_exit((void*) arg);

}
#endif

744 745 746 747 748 749 750 751 752 753 754 755 756
#ifdef SPECTRA
void *sensing (void *arg)
{
  struct sched_param sched_param;
  
  sched_param.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; 
  sched_setscheduler(0, SCHED_FIFO,&sched_param);
  
  printf("[SPECTRA] sensing thread started with priority %d\n",sched_param.sched_priority);
 
  while (oai_exit==0) {

    
757 758 759
    openair0_cfg[0].rx_freq[2]+= 5e6;
    if (openair0_cfg[0].rx_freq[2] >= 750000000)
      openair0_cfg[0].rx_freq[2] = 727500000;
760 761
    

762
    //LOG_I(HW,"[SPECTRA] changing frequency to %u \n",(uint32_t)openair0_cfg[1].rx_freq[0]);
763 764 765

    openair0_reconfig(&openair0_cfg[0]);

766
    usleep(200000);
767 768 769 770 771 772 773 774 775 776
    //sleep(1);
    
  }

  pthread_exit((void*) arg);

}
#endif


777
#if defined(ENABLE_ITTI)
778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795
static void wait_system_ready (char *message, volatile int *start_flag)
{
  /* Wait for eNB application initialization to be complete (eNB registration to MME) */
  {
    static char *indicator[] = {".    ", "..   ", "...  ", ".... ", ".....",
                                " ....", "  ...", "   ..", "    .", "     "};
    int i = 0;

    while ((!oai_exit) && (*start_flag == 0)) {
      LOG_N(EMU, message, indicator[i]);
      i = (i + 1) % (sizeof(indicator) / sizeof(indicator[0]));
      usleep(200000);
    }
    LOG_D(EMU,"\n");
  }
}
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
796
#if defined(ENABLE_ITTI)
797
void *l2l1_task(void *arg)
798
{
Raymond Knopp's avatar
 
Raymond Knopp committed
799 800 801 802 803
  MessageDef *message_p = NULL;
  int         result;

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
804

Raymond Knopp's avatar
 
Raymond Knopp committed
805 806
  if (UE_flag == 0) {
    /* Wait for the initialize message */
807
    do {
Raymond Knopp's avatar
 
Raymond Knopp committed
808 809 810 811
      if (message_p != NULL) {
	result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
	AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
      }
812 813 814
      itti_receive_msg (TASK_L2L1, &message_p);

      switch (ITTI_MSG_ID(message_p)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
815 816 817 818 819 820 821 822 823 824 825 826 827 828
      case INITIALIZE_MESSAGE:
	/* Start eNB thread */
	LOG_D(EMU, "L2L1 TASK received %s\n", ITTI_MSG_NAME(message_p));
	start_eNB = 1;
	break;

      case TERMINATE_MESSAGE:
	oai_exit=1;
	itti_exit_task ();
	break;

      default:
	LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
	break;
829
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851
    } while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE);
    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;
852

Raymond Knopp's avatar
 
Raymond Knopp committed
853 854 855 856 857 858 859 860 861 862 863 864
    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);
  } while(1);
865

Raymond Knopp's avatar
 
Raymond Knopp committed
866
  return NULL;
867 868 869
}
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
870

Raymond Knopp's avatar
 
Raymond Knopp committed
871
void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) {
Raymond Knopp's avatar
 
Raymond Knopp committed
872 873 874 875

  unsigned int aa,slot_offset, slot_offset_F;
  int dummy_tx_b[7680*4] __attribute__((aligned(16)));
  int i, tx_offset;
Raymond Knopp's avatar
 
Raymond Knopp committed
876
  int slot_sizeF = (phy_vars_eNB->lte_frame_parms.ofdm_symbol_size)*
Raymond Knopp's avatar
 
Raymond Knopp committed
877
    ((phy_vars_eNB->lte_frame_parms.Ncp==1) ? 6 : 7);
Raymond Knopp's avatar
 
Raymond Knopp committed
878 879 880

  slot_offset_F = (subframe<<1)*slot_sizeF;
    
Raymond Knopp's avatar
 
Raymond Knopp committed
881 882
  slot_offset = subframe*phy_vars_eNB->lte_frame_parms.samples_per_tti;

Raymond Knopp's avatar
 
Raymond Knopp committed
883 884
  if ((subframe_select(&phy_vars_eNB->lte_frame_parms,subframe)==SF_DL)||
      ((subframe_select(&phy_vars_eNB->lte_frame_parms,subframe)==SF_S))) {
Raymond Knopp's avatar
 
Raymond Knopp committed
885
    //	  LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot);
Raymond Knopp's avatar
 
Raymond Knopp committed
886

Raymond Knopp's avatar
 
Raymond Knopp committed
887
    
Raymond Knopp's avatar
 
Raymond Knopp committed
888 889 890 891 892 893 894 895 896 897
    for (aa=0; aa<phy_vars_eNB->lte_frame_parms.nb_antennas_tx; aa++) {
      if (phy_vars_eNB->lte_frame_parms.Ncp == EXTENDED){ 
	PHY_ofdm_mod(&phy_vars_eNB->lte_eNB_common_vars.txdataF[0][aa][slot_offset_F],
		     dummy_tx_b,
		     phy_vars_eNB->lte_frame_parms.log2_symbol_size,
		     6,
		     phy_vars_eNB->lte_frame_parms.nb_prefix_samples,
		     phy_vars_eNB->lte_frame_parms.twiddle_ifft,
		     phy_vars_eNB->lte_frame_parms.rev,
		     CYCLIC_PREFIX);
Raymond Knopp's avatar
 
Raymond Knopp committed
898 899 900 901 902 903 904 905
	PHY_ofdm_mod(&phy_vars_eNB->lte_eNB_common_vars.txdataF[0][aa][slot_offset_F+slot_sizeF],
		     dummy_tx_b+(phy_vars_eNB->lte_frame_parms.samples_per_tti>>1),
		     phy_vars_eNB->lte_frame_parms.log2_symbol_size,
		     6,
		     phy_vars_eNB->lte_frame_parms.nb_prefix_samples,
		     phy_vars_eNB->lte_frame_parms.twiddle_ifft,
		     phy_vars_eNB->lte_frame_parms.rev,
		     CYCLIC_PREFIX);
Raymond Knopp's avatar
 
Raymond Knopp committed
906 907 908 909 910 911
      }
      else {
	normal_prefix_mod(&phy_vars_eNB->lte_eNB_common_vars.txdataF[0][aa][slot_offset_F],
			  dummy_tx_b,
			  7,
			  &(phy_vars_eNB->lte_frame_parms));
Raymond Knopp's avatar
 
Raymond Knopp committed
912 913 914 915
	normal_prefix_mod(&phy_vars_eNB->lte_eNB_common_vars.txdataF[0][aa][slot_offset_F+slot_sizeF],
			  dummy_tx_b+(phy_vars_eNB->lte_frame_parms.samples_per_tti>>1),
			  7,
			  &(phy_vars_eNB->lte_frame_parms));
Raymond Knopp's avatar
 
Raymond Knopp committed
916
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
917 918

      for (i=0; i<phy_vars_eNB->lte_frame_parms.samples_per_tti; i++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935
	tx_offset = (int)slot_offset+time_offset[aa]+i;
	if (tx_offset<0)
	  tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->lte_frame_parms.samples_per_tti;
	if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->lte_frame_parms.samples_per_tti))
	  tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->lte_frame_parms.samples_per_tti;
	((short*)&phy_vars_eNB->lte_eNB_common_vars.txdata[0][aa][tx_offset])[0]=
	  ((short*)dummy_tx_b)[2*i]<<4;
	((short*)&phy_vars_eNB->lte_eNB_common_vars.txdata[0][aa][tx_offset])[1]=
	  ((short*)dummy_tx_b)[2*i+1]<<4;
      }
    }
  }
}


int eNB_thread_tx_status[10];
static void * eNB_thread_tx(void *param) {
Raymond Knopp's avatar
 
Raymond Knopp committed
936 937 938

  //unsigned long cpuid;
  eNB_proc_t *proc = (eNB_proc_t*)param;
Raymond Knopp's avatar
 
Raymond Knopp committed
939
  //  RTIME time_in,time_out;
Raymond Knopp's avatar
 
Raymond Knopp committed
940 941
#ifdef RTAI
  RT_TASK *task;
942
  char task_name[8];
943 944 945 946
#else 
#ifdef LOWLATENCY
  struct sched_attr attr;
  unsigned int flags = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
947
#endif
948
#endif 
Raymond Knopp's avatar
 
Raymond Knopp committed
949 950

 
Florian Kaltenberger's avatar
Florian Kaltenberger committed
951 952
/*#if defined(ENABLE_ITTI)
  // Wait for eNB application initialization to be complete (eNB registration to MME)
Raymond Knopp's avatar
 
Raymond Knopp committed
953
  wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
954
#endif*/
Raymond Knopp's avatar
 
Raymond Knopp committed
955

Raymond Knopp's avatar
 
Raymond Knopp committed
956
#ifdef RTAI
957
  sprintf(task_name,"TXC%dS%d",proc->CC_id,proc->subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
958 959 960
  task = rt_task_init_schmod(nam2num(task_name), 0, 0, 0, SCHED_FIFO, 0xF);

  if (task==NULL) {
Raymond Knopp's avatar
 
Raymond Knopp committed
961
    LOG_E(PHY,"[SCHED][eNB] Problem starting eNB_proc_TX thread_index %d (%s)!!!!\n",proc->subframe,task_name);
Raymond Knopp's avatar
 
Raymond Knopp committed
962 963 964
    return 0;
  }
  else {
965 966
    LOG_I(PHY,"[SCHED][eNB] eNB TX thread CC %d SF %d started with id %p\n",
	  proc->CC_id,
Raymond Knopp's avatar
 
Raymond Knopp committed
967
	  proc->subframe,
968
	  task);
Raymond Knopp's avatar
 
Raymond Knopp committed
969
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
970
#else
971 972 973 974 975 976
#ifdef LOWLATENCY
  attr.size = sizeof(attr);
  attr.sched_flags = 0;
  attr.sched_nice = 0;
  attr.sched_priority = 0;
  
Navid Nikaein's avatar
Navid Nikaein committed
977
  /* This creates a 1ms reservation every 10ms period*/
978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993
  attr.sched_policy = SCHED_DEADLINE;
  attr.sched_runtime = 1 * 1000000;  // each tx thread requires 1ms to finish its job
  attr.sched_deadline =1 * 1000000; // each tx thread will finish within 1ms
  attr.sched_period = 1 * 10000000; // each tx thread has a period of 10ms from the starting point
  
  if (sched_setattr(0, &attr, flags) < 0 ){
  perror("[SCHED] eNB tx thread: sched_setattr failed\n");
  exit(-1);
}
  LOG_I(HW,"[SCHED] eNB TX deadline thread %d(id %ld) started on CPU %d\n",
    proc->subframe, gettid(),sched_getcpu());
#else 
  LOG_I(HW,"[SCHED] eNB TX thread %d started on CPU %d\n",
	  proc->subframe,sched_getcpu());
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
994 995 996 997 998 999 1000 1001 1002 1003 1004 1005
#endif

  mlockall(MCL_CURRENT | MCL_FUTURE);

  //rt_set_runnable_on_cpuid(task,1);
  //cpuid = rtai_cpuid();

#ifdef HARD_RT
  rt_make_hard_real_time();
#endif

  while (!oai_exit){
Raymond Knopp's avatar
 
Raymond Knopp committed
1006
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1007
    vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_TX0+(2*proc->subframe),0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1008
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1009 1010
    //LOG_I(PHY,"Locking mutex for eNB proc %d (IC %d,mutex %p)\n",proc->subframe,proc->instance_cnt,&proc->mutex);
    //    printf("Locking mutex for eNB proc %d (subframe_tx %d))\n",proc->subframe,proc->subframe_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1011

Raymond Knopp's avatar
 
Raymond Knopp committed
1012 1013
    if (pthread_mutex_lock(&proc->mutex_tx) != 0) {
      LOG_E(PHY,"[SCHED][eNB] error locking mutex for eNB TX proc %d\n",proc->subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
1014
      oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1015 1016
    }
    else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1017
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1018 1019
      while (proc->instance_cnt_tx < 0) {
	//	LOG_I(PHY,"Waiting and unlocking mutex for eNB proc %d (IC %d,lock %d)\n",proc->subframe,proc->instance_cnt,pthread_mutex_trylock(&proc->mutex));
Raymond Knopp's avatar
 
Raymond Knopp committed
1020
	//printf("Waiting and unlocking mutex for eNB proc %d (subframe_tx %d)\n",proc->subframe,subframe_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1021
	
Raymond Knopp's avatar
 
Raymond Knopp committed
1022
	pthread_cond_wait(&proc->cond_tx,&proc->mutex_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1023
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1024 1025 1026
      //      LOG_I(PHY,"Waking up and unlocking mutex for eNB proc %d\n",proc->subframe);
      if (pthread_mutex_unlock(&proc->mutex_tx) != 0) {	
	LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for eNB TX proc %d\n",proc->subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
1027
	oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1028 1029
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1030
    vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_TX0+(2*proc->subframe),1);    
Raymond Knopp's avatar
 
Raymond Knopp committed
1031
    vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB, proc->frame_tx);
1032 1033
    start_meas(&softmodem_stats_tx_sf[proc->subframe]);

Raymond Knopp's avatar
 
Raymond Knopp committed
1034
    if (oai_exit) break;
Raymond Knopp's avatar
 
Raymond Knopp committed
1035

Raymond Knopp's avatar
 
Raymond Knopp committed
1036 1037 1038 1039 1040 1041 1042
    
    if ((((PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms.frame_type == TDD)&&
	  (subframe_select(&PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms,proc->subframe_tx)==SF_DL))||
	 (PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms.frame_type == FDD))) {
      
      phy_procedures_eNB_TX(proc->subframe,PHY_vars_eNB_g[0][proc->CC_id],0,no_relay,NULL);
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1043
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1044 1045
    if ((subframe_select(&PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms,proc->subframe_tx)==SF_S)) {
      phy_procedures_eNB_TX(proc->subframe,PHY_vars_eNB_g[0][proc->CC_id],0,no_relay,NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
1046
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1047
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1048
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1049
    do_OFDM_mod_rt(proc->subframe_tx,PHY_vars_eNB_g[0][proc->CC_id]);  
Raymond Knopp's avatar
 
Raymond Knopp committed
1050
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1051 1052
    if (pthread_mutex_lock(&proc->mutex_tx) != 0) {
      printf("[openair][SCHED][eNB] error locking mutex for eNB TX proc %d\n",proc->subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
1053
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1054 1055
    else {
      proc->instance_cnt_tx--;
Raymond Knopp's avatar
 
Raymond Knopp committed
1056
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1057 1058 1059 1060
      if (pthread_mutex_unlock(&proc->mutex_tx) != 0) {	
	printf("[openair][SCHED][eNB] error unlocking mutex for eNB TX proc %d\n",proc->subframe);
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1061

Raymond Knopp's avatar
 
Raymond Knopp committed
1062
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1063 1064 1065
    proc->frame_tx++;
    if (proc->frame_tx==1024)
      proc->frame_tx=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1066

Raymond Knopp's avatar
 
Raymond Knopp committed
1067
  }    
1068
  stop_meas(&softmodem_stats_tx_sf[proc->subframe]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1069 1070 1071 1072
  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_TX0+(2*proc->subframe),0);        
#ifdef HARD_RT
  rt_make_soft_real_time();
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1073
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1074 1075 1076 1077 1078 1079 1080 1081 1082 1083
#ifdef DEBUG_THREADS
  printf("Exiting eNB thread TX %d\n",proc->subframe);
#endif
  // clean task
#ifdef RTAI
  rt_task_delete(task);
#else
  eNB_thread_tx_status[proc->subframe]=0;
  pthread_exit(&eNB_thread_tx_status[proc->subframe]);
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1084
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097
#ifdef DEBUG_THREADS
  printf("Exiting eNB TX thread %d\n",proc->subframe);
#endif
}

int eNB_thread_rx_status[10];
static void * eNB_thread_rx(void *param) {

  //unsigned long cpuid;
  eNB_proc_t *proc = (eNB_proc_t*)param;
  //  RTIME time_in,time_out;
#ifdef RTAI
  RT_TASK *task;
1098
  char task_name[8];
1099 1100 1101 1102 1103
#else
#ifdef LOWLATENCY
  struct sched_attr attr;
  unsigned int flags = 0;
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1104 1105
#endif

Florian Kaltenberger's avatar
Florian Kaltenberger committed
1106 1107
/*#if defined(ENABLE_ITTI)
  // Wait for eNB application initialization to be complete (eNB registration to MME) 
Raymond Knopp's avatar
 
Raymond Knopp committed
1108
  wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1109
#endif*/
Raymond Knopp's avatar
 
Raymond Knopp committed
1110 1111

#ifdef RTAI
1112
  sprintf(task_name,"RXC%1dS%1d",proc->CC_id,proc->subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
1113 1114 1115 1116 1117 1118 1119
  task = rt_task_init_schmod(nam2num(task_name), 0, 0, 0, SCHED_FIFO, 0xF);

  if (task==NULL) {
    LOG_E(PHY,"[SCHED][eNB] Problem starting eNB_proc_RX thread_index %d (%s)!!!!\n",proc->subframe,task_name);
    return 0;
  }
  else {
1120 1121
    LOG_I(PHY,"[SCHED][eNB] eNB RX thread CC_id %d SF %d started with id %p\n", /*  on CPU %d*/
	  proc->CC_id,
Raymond Knopp's avatar
 
Raymond Knopp committed
1122
	  proc->subframe,
1123
	  task); /*,rtai_cpuid()*/
Raymond Knopp's avatar
 
Raymond Knopp committed
1124 1125
  }
#else
1126 1127 1128 1129 1130 1131
#ifdef LOWLATENCY
  attr.size = sizeof(attr);
  attr.sched_flags = 0;
  attr.sched_nice = 0;
  attr.sched_priority = 0;
  
Navid Nikaein's avatar
Navid Nikaein committed
1132
  /* This creates a 2ms reservation every 10ms period*/
1133
  attr.sched_policy = SCHED_DEADLINE;
Navid Nikaein's avatar
Navid Nikaein committed
1134 1135 1136
  attr.sched_runtime  = 1 * 2000000;  // each rx thread must finish its job in the worst case in 2ms
  attr.sched_deadline = 1 * 2000000; // each rx thread will finish within 2ms
  attr.sched_period   = 1 * 10000000; // each rx thread has a period of 10ms from the starting point
1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148
  
  if (sched_setattr(0, &attr, flags) < 0 ){
    perror("[SCHED] eNB RX sched_setattr failed\n");
    exit(-1);
  }
  LOG_I(HW,"[SCHED] eNB RX deadline thread %d(id %ld) started on CPU %d\n",
	  proc->subframe, gettid(),sched_getcpu());
#else 
  LOG_I(HW,"[SCHED][eNB] eNB RX thread %d started on CPU %d\n",
	  proc->subframe,sched_getcpu());
#endif
 
Raymond Knopp's avatar
 
Raymond Knopp committed
1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162
#endif

  mlockall(MCL_CURRENT | MCL_FUTURE);

  //rt_set_runnable_on_cpuid(task,1);
  //cpuid = rtai_cpuid();

#ifdef HARD_RT
  rt_make_hard_real_time();
#endif

  while (!oai_exit){

    vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX0+(2*proc->subframe),0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1163
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1164 1165 1166 1167 1168 1169 1170 1171 1172 1173
    //    LOG_I(PHY,"Locking mutex for eNB proc %d (IC %d,mutex %p)\n",proc->subframe,proc->instance_cnt,&proc->mutex);
    if (pthread_mutex_lock(&proc->mutex_rx) != 0) {
      LOG_E(PHY,"[SCHED][eNB] error locking mutex for eNB RX proc %d\n",proc->subframe);
    }
    else {
        
      while (proc->instance_cnt_rx < 0) {
	//	LOG_I(PHY,"Waiting and unlocking mutex for eNB proc %d (IC %d,lock %d)\n",proc->subframe,proc->instance_cnt,pthread_mutex_trylock(&proc->mutex));

	pthread_cond_wait(&proc->cond_rx,&proc->mutex_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1174
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1175 1176 1177
      //      LOG_I(PHY,"Waking up and unlocking mutex for eNB proc %d\n",proc->subframe);
      if (pthread_mutex_unlock(&proc->mutex_rx) != 0) {	
	LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for eNB RX proc %d\n",proc->subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
1178 1179
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1180
    vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX0+(2*proc->subframe),1);    
Raymond Knopp's avatar
 
Raymond Knopp committed
1181
    vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, proc->frame_rx);
1182 1183
    start_meas(&softmodem_stats_rx_sf[proc->subframe]);
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1184 1185
    if (oai_exit) break;
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1186 1187 1188
    if ((((PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms.frame_type == TDD )&&(subframe_select(&PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms,proc->subframe_rx)==SF_UL)) ||
	 (PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms.frame_type == FDD))){
      phy_procedures_eNB_RX(proc->subframe,PHY_vars_eNB_g[0][proc->CC_id],0,no_relay);
Raymond Knopp's avatar
 
Raymond Knopp committed
1189
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1190 1191
    if ((subframe_select(&PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms,proc->subframe_rx)==SF_S)){
      phy_procedures_eNB_S_RX(proc->subframe,PHY_vars_eNB_g[0][proc->CC_id],0,no_relay);
Raymond Knopp's avatar
 
Raymond Knopp committed
1192 1193 1194 1195
    }
      
    if (pthread_mutex_lock(&proc->mutex_rx) != 0) {
      printf("[openair][SCHED][eNB] error locking mutex for eNB RX proc %d\n",proc->subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
1196 1197
    }
    else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1198
      proc->instance_cnt_rx--;
Raymond Knopp's avatar
 
Raymond Knopp committed
1199
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1200 1201
      if (pthread_mutex_unlock(&proc->mutex_rx) != 0) {	
	printf("[openair][SCHED][eNB] error unlocking mutex for eNB RX proc %d\n",proc->subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
1202 1203
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1204 1205 1206 1207

    proc->frame_rx++;
    if (proc->frame_rx==1024)
      proc->frame_rx=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1208
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1209
  }
1210
  stop_meas(&softmodem_stats_rx_sf[proc->subframe]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1211
  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX0+(2*proc->subframe),0);        
Raymond Knopp's avatar
 
Raymond Knopp committed
1212
#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224
  rt_make_soft_real_time();
#endif

#ifdef DEBUG_THREADS
  printf("Exiting eNB thread RX %d\n",proc->subframe);
#endif
  // clean task
#ifdef RTAI
  rt_task_delete(task);
#else
  eNB_thread_rx_status[proc->subframe]=0;
  pthread_exit(&eNB_thread_rx_status[proc->subframe]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1225 1226
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1227 1228 1229
#ifdef DEBUG_THREADS
  printf("Exiting eNB RX thread %d\n",proc->subframe);
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1230 1231 1232 1233
}



Raymond Knopp's avatar
 
Raymond Knopp committed
1234

1235
void init_eNB_proc(void) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1236 1237

  int i;
Raymond Knopp's avatar
 
Raymond Knopp committed
1238 1239 1240 1241
  int CC_id;

  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    for (i=0;i<10;i++) {
1242
      /*set the stack sizw */ 
Raymond Knopp's avatar
 
Raymond Knopp committed
1243
      pthread_attr_init (&attr_eNB_proc_tx[CC_id][i]);
1244 1245 1246 1247 1248 1249 1250 1251
      if (pthread_attr_setstacksize(&attr_eNB_proc_tx[CC_id][i],OPENAIR_THREAD_STACK_SIZE) != 0)
	perror("[ENB_PROC_TX] setting thread stack size failed\n");

      pthread_attr_init (&attr_eNB_proc_rx[CC_id][i]);
      if (pthread_attr_setstacksize(&attr_eNB_proc_rx[CC_id][i],OPENAIR_THREAD_STACK_SIZE) != 0)
	perror("[ENB_PROC_RX] setting thread stack size failed\n");
      /* set the kernel scheduling policy and priority */
#ifndef LOWLATENCY
Raymond Knopp's avatar
 
Raymond Knopp committed
1252 1253 1254 1255 1256 1257 1258 1259
      //attr_dlsch_threads.priority = 1;
      sched_param_eNB_proc_tx[CC_id][i].sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY;
      pthread_attr_setschedparam  (&attr_eNB_proc_tx[CC_id][i], &sched_param_eNB_proc_tx[CC_id][i]);
      pthread_attr_setschedpolicy (&attr_eNB_proc_tx[CC_id][i], SCHED_FIFO);
      //attr_dlsch_threads.priority = 1;
      sched_param_eNB_proc_rx[CC_id][i].sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY;
      pthread_attr_setschedparam  (&attr_eNB_proc_rx[CC_id][i], &sched_param_eNB_proc_rx[CC_id][i]);
      pthread_attr_setschedpolicy (&attr_eNB_proc_rx[CC_id][i], SCHED_FIFO);
1260
#endif       
Raymond Knopp's avatar
 
Raymond Knopp committed
1261
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273
      PHY_vars_eNB_g[0][CC_id]->proc[i].instance_cnt_tx=-1;
      PHY_vars_eNB_g[0][CC_id]->proc[i].instance_cnt_rx=-1;
      PHY_vars_eNB_g[0][CC_id]->proc[i].subframe=i;
      PHY_vars_eNB_g[0][CC_id]->proc[i].CC_id = CC_id;
      pthread_mutex_init(&PHY_vars_eNB_g[0][CC_id]->proc[i].mutex_tx,NULL);
      pthread_mutex_init(&PHY_vars_eNB_g[0][CC_id]->proc[i].mutex_rx,NULL);
      pthread_cond_init(&PHY_vars_eNB_g[0][CC_id]->proc[i].cond_tx,NULL);
      pthread_cond_init(&PHY_vars_eNB_g[0][CC_id]->proc[i].cond_rx,NULL);
      pthread_create(&PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_tx,NULL,eNB_thread_tx,(void*)&PHY_vars_eNB_g[0][CC_id]->proc[i]);
      pthread_create(&PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_rx,NULL,eNB_thread_rx,(void*)&PHY_vars_eNB_g[0][CC_id]->proc[i]);
      PHY_vars_eNB_g[0][CC_id]->proc[i].frame_tx = 0;
      PHY_vars_eNB_g[0][CC_id]->proc[i].frame_rx = 0;
1274
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1275 1276
      PHY_vars_eNB_g[0][CC_id]->proc[i].subframe_rx = (i+9)%10;
      PHY_vars_eNB_g[0][CC_id]->proc[i].subframe_tx = (i+1)%10;
Raymond Knopp's avatar
 
Raymond Knopp committed
1277
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1278 1279
      PHY_vars_eNB_g[0][CC_id]->proc[i].subframe_rx = i;
      PHY_vars_eNB_g[0][CC_id]->proc[i].subframe_tx = (i+2)%10;
Raymond Knopp's avatar
 
Raymond Knopp committed
1280
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1281 1282 1283
    }
  
  
1284
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1285 1286
    // TX processes subframe + 1, RX subframe -1
    // Note this inialization is because the first process awoken for frame 0 is number 1 and so processes 9 and 0 have to start with frame 1
Raymond Knopp's avatar
 
Raymond Knopp committed
1287
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1288
    //PHY_vars_eNB_g[0][CC_id]->proc[0].frame_rx = 1023;
Raymond Knopp's avatar
 
Raymond Knopp committed
1289 1290
    PHY_vars_eNB_g[0][CC_id]->proc[9].frame_tx = 1;
    PHY_vars_eNB_g[0][CC_id]->proc[0].frame_tx = 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1291
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1292 1293
    // TX processes subframe +2, RX subframe
    // Note this inialization is because the first process awoken for frame 0 is number 1 and so processes 8,9 and 0 have to start with frame 1
Raymond Knopp's avatar
 
Raymond Knopp committed
1294
    //    PHY_vars_eNB_g[0][CC_id]->proc[7].frame_tx = 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1295 1296
    PHY_vars_eNB_g[0][CC_id]->proc[8].frame_tx = 1;
    PHY_vars_eNB_g[0][CC_id]->proc[9].frame_tx = 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1297
    //    PHY_vars_eNB_g[0][CC_id]->proc[0].frame_tx = 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1298
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1299 1300
  }
}
Raymond Knopp's avatar
 
Raymond Knopp committed
1301

1302
void kill_eNB_proc(void) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1303 1304

  int i;
1305
  void *status_tx,*status_rx;
Raymond Knopp's avatar
 
Raymond Knopp committed
1306
  int CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1307

Raymond Knopp's avatar
 
Raymond Knopp committed
1308 1309 1310
  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) 
    for (i=0;i<10;i++) {
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1311
#ifdef DEBUG_THREADS
Raymond Knopp's avatar
 
Raymond Knopp committed
1312
      printf("Killing TX CC_id %d thread %d\n",CC_id,i);
Raymond Knopp's avatar
 
Raymond Knopp committed
1313
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1314 1315
      PHY_vars_eNB_g[0][CC_id]->proc[i].instance_cnt_tx=0; 
      pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[i].cond_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1316
#ifdef DEBUG_THREADS
1317
      printf("Joining eNB TX CC_id %d thread %d...\n",CC_id,i);
Raymond Knopp's avatar
 
Raymond Knopp committed
1318
#endif
1319
      pthread_join(PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_tx,&status_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1320
#ifdef DEBUG_THREADS
1321
      if (status_tx) printf("status %p...\n",status_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1322 1323
#endif
#ifdef DEBUG_THREADS
Raymond Knopp's avatar
 
Raymond Knopp committed
1324
      printf("Killing RX CC_id %d thread %d\n",CC_id,i);
Raymond Knopp's avatar
 
Raymond Knopp committed
1325
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1326 1327
      PHY_vars_eNB_g[0][CC_id]->proc[i].instance_cnt_rx=0; 
      pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[i].cond_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1328
#ifdef DEBUG_THREADS
1329
      printf("Joining eNB RX CC_id %d thread %d...\n",CC_id,i);
Raymond Knopp's avatar
 
Raymond Knopp committed
1330
#endif
1331
      pthread_join(PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_rx,&status_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1332
#ifdef DEBUG_THREADS 
1333
      if (status_rx) printf("status %p...\n",status_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1334
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1335 1336 1337 1338 1339
      pthread_mutex_destroy(&PHY_vars_eNB_g[0][CC_id]->proc[i].mutex_tx);
      pthread_mutex_destroy(&PHY_vars_eNB_g[0][CC_id]->proc[i].mutex_rx);
      pthread_cond_destroy(&PHY_vars_eNB_g[0][CC_id]->proc[i].cond_tx);
      pthread_cond_destroy(&PHY_vars_eNB_g[0][CC_id]->proc[i].cond_rx);
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1340 1341 1342
}


Raymond Knopp's avatar
 
Raymond Knopp committed
1343 1344


Raymond Knopp's avatar
 
Raymond Knopp committed
1345 1346
  
/* This is the main eNB thread. */
Raymond Knopp's avatar
 
Raymond Knopp committed
1347 1348
int eNB_thread_status;

Raymond Knopp's avatar
 
Raymond Knopp committed
1349

Raymond Knopp's avatar
 
Raymond Knopp committed
1350

1351 1352 1353 1354
static void *eNB_thread(void *arg)
{
#ifdef RTAI
  RT_TASK *task;
1355 1356 1357 1358 1359 1360
#else 
#ifdef LOWLATENCY
  struct sched_attr attr;
  unsigned int flags = 0;
  unsigned long mask = 1; /* processor 0 */
#endif
1361
#endif
1362

1363 1364
#ifdef EXMIMO
  unsigned char slot=0;
1365 1366
#else
  unsigned char slot=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1367
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1368
  int frame=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1369
  int CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1370

1371
  RTIME time_in, time_diff;
Raymond Knopp's avatar
 
Raymond Knopp committed
1372

Raymond Knopp's avatar
 
Raymond Knopp committed
1373
  int sf;
1374
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1375
  volatile unsigned int *DAQ_MBOX = openair0_daq_cnt();
Raymond Knopp's avatar
 
Raymond Knopp committed
1376 1377
  int mbox_target=0,mbox_current=0;
  int hw_slot,delay_cnt;
Raymond Knopp's avatar
 
Raymond Knopp committed
1378 1379
  int diff;
  int ret;
1380
  int first_run=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1381
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1382 1383
  unsigned int rx_cnt = 0;
  unsigned int tx_cnt = tx_delay;
Raymond Knopp's avatar
 
Raymond Knopp committed
1384
  //  int tx_offset;
Raymond Knopp's avatar
 
Raymond Knopp committed
1385 1386
  void *rxp[2],*txp[2];
  int i;
Raymond Knopp's avatar
 
Raymond Knopp committed
1387

Raymond Knopp's avatar
 
Raymond Knopp committed
1388
  hw_subframe = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1389
#endif
1390

1391
  /*
1392
#if defined(ENABLE_ITTI)
1393
  // Wait for eNB application initialization to be complete (eNB registration to MME) 
1394
  wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
1395
#endif
1396
  */
1397

1398
#ifdef RTAI
1399 1400 1401 1402 1403 1404 1405 1406
   task = rt_task_init_schmod(nam2num("TASK0"), 0, 0, 0, SCHED_FIFO, 0xF);
#else 
#ifdef LOWLATENCY
   attr.size = sizeof(attr);
   attr.sched_flags = 0;
   attr.sched_nice = 0;
   attr.sched_priority = 0;
   
Navid Nikaein's avatar
Navid Nikaein committed
1407
   /* This creates a .5 ms  reservation */
1408
   attr.sched_policy = SCHED_DEADLINE;
Navid Nikaein's avatar
Navid Nikaein committed
1409 1410 1411
   attr.sched_runtime  = 1 * 1000000;
   attr.sched_deadline = 1 * 1000000;
   attr.sched_period   = 1 * 1000000;
1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425
   
   /* pin the eNB main thread to CPU0*/
   /* if (pthread_setaffinity_np(pthread_self(), sizeof(mask),&mask) <0) {
        perror("[MAIN_ENB_THREAD] pthread_setaffinity_np failed\n");
	}*/
   
   if (sched_setattr(0, &attr, flags) < 0 ){
     perror("[SCHED] main eNB thread: sched_setattr failed\n");
     exit_fun(-1);
   } else {
     LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %ld started on CPU %d\n",
	    gettid(),sched_getcpu());
   }
#endif
1426 1427 1428 1429
#endif

  if (!oai_exit) {
#ifdef RTAI
1430
    printf("[SCHED][eNB] Started eNB main thread (id %p)\n",task);
Raymond Knopp's avatar
 
Raymond Knopp committed
1431
#else
1432
    printf("[SCHED][eNB] Started eNB main thread on CPU %d\n",
Raymond Knopp's avatar
 
Raymond Knopp committed
1433
	   sched_getcpu());
1434 1435 1436
#endif

#ifdef HARD_RT
1437
    rt_make_hard_real_time();
1438 1439
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1440
    printf("eNB_thread: mlockall in ...\n");
1441
    mlockall(MCL_CURRENT | MCL_FUTURE);
Raymond Knopp's avatar
 
Raymond Knopp committed
1442
    printf("eNB_thread: mlockall out ...\n");
1443

1444 1445 1446 1447
    timing_info.time_min = 100000000ULL;
    timing_info.time_max = 0;
    timing_info.time_avg = 0;
    timing_info.n_samples = 0;
1448

1449
    printf("waiting for sync (eNB_thread)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1450 1451 1452
#ifdef RTAI
    rt_sem_wait(sync_sem);
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1453
    pthread_mutex_lock(&sync_mutex);
1454 1455
    while (sync_var<0)
      pthread_cond_wait(&sync_cond, &sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
1456
    pthread_mutex_unlock(&sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
1457 1458 1459
#endif
    //    printf("starting eNB thread @ %llu\n",get_usrp_time(&openair0));

Raymond Knopp's avatar
 
Raymond Knopp committed
1460
    while (!oai_exit) {
1461
      start_meas(&softmodem_stats_mt);
1462
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1463 1464
      hw_slot = (((((volatile unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15;
      //        LOG_D(HW,"eNB frame %d, time %llu: slot %d, hw_slot %d (mbox %d)\n",frame,rt_get_time_ns(),slot,hw_slot,((unsigned int *)DAQ_MBOX)[0]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1465 1466
      vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME, hw_slot>>1);
      vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, frame);
Raymond Knopp's avatar
 
Raymond Knopp committed
1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478
      //this is the mbox counter where we should be
      mbox_target = mbox_bounds[slot];
      //this is the mbox counter where we are
      mbox_current = ((volatile unsigned int *)DAQ_MBOX)[0];
      //this is the time we need to sleep in order to synchronize with the hw (in multiples of DAQ_PERIOD)
      if ((mbox_current>=135) && (mbox_target<15)) //handle the frame wrap-arround
	diff = 150-mbox_current+mbox_target;
      else if ((mbox_current<15) && (mbox_target>=135))
	diff = -150+mbox_target-mbox_current;
      else
	diff = mbox_target - mbox_current;
      
1479 1480 1481 1482 1483
      //when we start the aquisition we want to start with slot 0, so we rather wait for the hardware than to advance the slot number (a positive diff will cause the programm to go into the second if clause rather than the first)
      if (first_run==1) {
	first_run=0;
	if (diff<0)
	  diff = diff +150;
1484
	LOG_I(HW,"eNB Frame %d, time %llu: slot %d, hw_slot %d, diff %d\n",frame, rt_get_time_ns(), slot, hw_slot, diff);
1485 1486
      } 

Raymond Knopp's avatar
 
Raymond Knopp committed
1487 1488
      if (((slot%2==0) && (diff < (-14))) || ((slot%2==1) && (diff < (-7)))) {
	// at the eNB, even slots have double as much time since most of the processing is done here and almost nothing in odd slots
1489
	LOG_D(HW,"eNB Frame %d, time %llu: missed slot, proceeding with next one (slot %d, hw_slot %d, mbox_current %d, mbox_target %d, diff %d)\n",frame, rt_get_time_ns(), slot, hw_slot, mbox_current, mbox_target, diff);
Raymond Knopp's avatar
 
Raymond Knopp committed
1490
	slot++;
1491 1492 1493 1494 1495 1496 1497
	if (exit_missed_slots==1){
	  stop_meas(&softmodem_stats_mt);
	  exit_fun("[HW][eNB] missed slot");
	}else{
	  num_missed_slots++;
	  LOG_W(HW,"[eNB] just missed slot (total missed slots %ld)\n", num_missed_slots);
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
1498 1499 1500 1501
      }
      if (diff>8)
	LOG_D(HW,"eNB Frame %d, time %llu: skipped slot, waiting for hw to catch up (slot %d, hw_slot %d, mbox_current %d, mbox_target %d, diff %d)\n",frame, rt_get_time_ns(), slot, hw_slot, mbox_current, mbox_target, diff);
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1502
      vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *DAQ_MBOX);
Raymond Knopp's avatar
 
Raymond Knopp committed
1503 1504 1505 1506 1507 1508 1509 1510 1511 1512
      vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DIFF, diff);
      
      delay_cnt = 0;
      while ((diff>0) && (!oai_exit)) {
	time_in = rt_get_time_ns();
	//LOG_D(HW,"eNB Frame %d delaycnt %d : hw_slot %d (%d), slot %d, (slot+1)*15=%d, diff %d, time %llu\n",frame,delay_cnt,hw_slot,((unsigned int *)DAQ_MBOX)[0],slot,(((slot+1)*15)>>1),diff,time_in);
	//LOG_D(HW,"eNB Frame %d, time %llu: sleeping for %llu (slot %d, hw_slot %d, diff %d, mbox %d, delay_cnt %d)\n", frame, time_in, diff*DAQ_PERIOD,slot,hw_slot,diff,((volatile unsigned int *)DAQ_MBOX)[0],delay_cnt);
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RT_SLEEP,1);
	ret = rt_sleep_ns(diff*DAQ_PERIOD);
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RT_SLEEP,0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1513
	vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *DAQ_MBOX);
Raymond Knopp's avatar
 
Raymond Knopp committed
1514 1515 1516 1517 1518 1519
	if (ret)
	  LOG_D(HW,"eNB Frame %d, time %llu: rt_sleep_ns returned %d\n",frame, time_in);
	hw_slot = (((((volatile unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15;
	//LOG_D(HW,"eNB Frame %d : hw_slot %d, time %llu\n",frame,hw_slot,rt_get_time_ns());
	delay_cnt++;
	if (delay_cnt == 10) {
1520
	  stop_meas(&softmodem_stats_mt);
Raymond Knopp's avatar
 
Raymond Knopp committed
1521 1522 1523 1524 1525
	  LOG_D(HW,"eNB Frame %d: HW stopped ... \n",frame);
	  exit_fun("[HW][eNB] HW stopped");
	}
	mbox_current = ((volatile unsigned int *)DAQ_MBOX)[0];
	if ((mbox_current>=135) && (mbox_target<15)) //handle the frame wrap-arround
Raymond Knopp's avatar
 
Raymond Knopp committed
1526
	  diff = 150-mbox_current+mbox_target;
Raymond Knopp's avatar
 
Raymond Knopp committed
1527
	else if ((mbox_current<15) && (mbox_target>=135))
Raymond Knopp's avatar
 
Raymond Knopp committed
1528
	  diff = -150+mbox_target-mbox_current;
Raymond Knopp's avatar
 
Raymond Knopp committed
1529
	else
Raymond Knopp's avatar
 
Raymond Knopp committed
1530
	  diff = mbox_target - mbox_current;
Raymond Knopp's avatar
 
Raymond Knopp committed
1531
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1532

1533
#else  // EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1534 1535
      vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME, hw_subframe);
      vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, frame);
Raymond Knopp's avatar
 
Raymond Knopp committed
1536 1537
      while (rx_cnt < sf_bounds[hw_subframe]) {

Raymond Knopp's avatar
 
Raymond Knopp committed
1538 1539
	openair0_timestamp time0,time1;
	unsigned int rxs;
Raymond Knopp's avatar
 
Raymond Knopp committed
1540
#ifndef USRP_DEBUG
Raymond Knopp's avatar
 
Raymond Knopp committed
1541
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1542

Raymond Knopp's avatar
 
Raymond Knopp committed
1543 1544
	vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_TXCNT,tx_cnt);
	vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_RXCNT,rx_cnt*samples_per_packets);
1545

1546
	//	printf("hw_subframe %d: rx_cnt %d\n",hw_subframe,rx_cnt);
Raymond Knopp's avatar
 
Raymond Knopp committed
1547 1548 1549

	for (i=0;i<PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_rx;i++)
	  rxp[i] = (void*)&rxdata[i][rx_cnt*samples_per_packets];
1550
	start_meas(&softmodem_stats_hw);
Raymond Knopp's avatar
 
Raymond Knopp committed
1551 1552
	rxs = openair0.trx_read_func(&openair0, 
				     &timestamp, 
Raymond Knopp's avatar
 
Raymond Knopp committed
1553 1554 1555
				     rxp, 
				     samples_per_packets,
				     PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_rx);
1556
	stop_meas(&softmodem_stats_hw);
Raymond Knopp's avatar
 
Raymond Knopp committed
1557 1558
	if (rxs != samples_per_packets)
	  oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1559
 
1560
	//	printf("hw_subframe %d: tx_cnt %d\n",hw_subframe,tx_cnt);
Raymond Knopp's avatar
 
Raymond Knopp committed
1561

Raymond Knopp's avatar
 
Raymond Knopp committed
1562 1563
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,0);

Raymond Knopp's avatar
 
Raymond Knopp committed
1564
	// Transmit TX buffer based on timestamp from RX
Raymond Knopp's avatar
 
Raymond Knopp committed
1565
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1566 1567 1568
	
	for (i=0;i<PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_tx;i++)
	  txp[i] = (void*)&txdata[i][tx_cnt*samples_per_packets];
Raymond Knopp's avatar
 
Raymond Knopp committed
1569 1570
	openair0.trx_write_func(&openair0, 
				(timestamp+samples_per_packets*tx_delay-tx_forward_nsamps), 
Raymond Knopp's avatar
 
Raymond Knopp committed
1571
				txp,
Raymond Knopp's avatar
 
Raymond Knopp committed
1572
				samples_per_packets, 
Raymond Knopp's avatar
 
Raymond Knopp committed
1573
				PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_tx,
Raymond Knopp's avatar
 
Raymond Knopp committed
1574
				1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1575

1576
	stop_meas(&softmodem_stats_mt);
Raymond Knopp's avatar
 
Raymond Knopp committed
1577
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1578 1579 1580 1581 1582 1583 1584 1585 1586
#else
	rt_sleep_ns(1000000);
#endif
	if (rx_cnt == sf_bounds_tx[hw_subframe]) {
	  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
	    if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].mutex_tx) != 0) {
	      LOG_E(PHY,"[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n",hw_subframe,PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].instance_cnt_tx);   
	    }
	    else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1587
	      //	      LOG_I(PHY,"[eNB] Waking up eNB process %d (IC %d,rx_cnt %d)\n",hw_subframe,PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].instance_cnt_tx,rx_cnt); 
Raymond Knopp's avatar
 
Raymond Knopp committed
1588 1589 1590 1591 1592 1593 1594 1595
	      PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].instance_cnt_tx++;
	      pthread_mutex_unlock(&PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].mutex_tx);
	      if (PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].instance_cnt_tx == 0) {
		if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].cond_tx) != 0) {
		  LOG_E(PHY,"[eNB] ERROR pthread_cond_signal for eNB TX thread %d\n",hw_subframe);
		}
	      }
	      else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1596
		LOG_W(PHY,"[eNB] Frame %d, eNB TX thread %d busy!! (rx_cnt %d)\n",PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].frame_tx,hw_subframe,rx_cnt);
Raymond Knopp's avatar
 
Raymond Knopp committed
1597 1598 1599 1600 1601
		oai_exit=1;
	      }
	    }
	  }
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
1602 1603
	rx_cnt++;
	tx_cnt++;
Raymond Knopp's avatar
 
Raymond Knopp committed
1604 1605 1606

	if(tx_cnt == max_cnt)
	  tx_cnt = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1607 1608
      }

Raymond Knopp's avatar
 
Raymond Knopp committed
1609 1610
      if(rx_cnt == max_cnt)
	rx_cnt = 0; 
Raymond Knopp's avatar
 
Raymond Knopp committed
1611
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1612 1613 1614

#endif // USRP
     
Raymond Knopp's avatar
 
Raymond Knopp committed
1615
      if (oai_exit) break;
1616

Raymond Knopp's avatar
 
Raymond Knopp committed
1617

Raymond Knopp's avatar
 
Raymond Knopp committed
1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638
      
      timing_info.time_last = timing_info.time_now;
      timing_info.time_now = rt_get_time_ns();
      
      if (timing_info.n_samples>0) {
	time_diff = timing_info.time_now - timing_info.time_last;
	if (time_diff < timing_info.time_min)
	  timing_info.time_min = time_diff;
	if (time_diff > timing_info.time_max)
	  timing_info.time_max = time_diff;
	timing_info.time_avg += time_diff;
      }
      
      timing_info.n_samples++;
      /*
	if ((timing_info.n_samples%2000)==0) {
	LOG_D(HW,"frame %d (%d), slot %d, hw_slot %d: diff=%llu, min=%llu, max=%llu, avg=%llu (n_samples %d)\n",
	frame, PHY_vars_eNB_g[0]->frame, slot, hw_slot,time_diff,
	timing_info.time_min,timing_info.time_max,timing_info.time_avg/timing_info.n_samples,timing_info.n_samples);
	timing_info.n_samples = 0;
	timing_info.time_avg = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1639
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
1640 1641
      */
      //}
1642
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1643
      if ((slot&1) == 1) {
1644
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1645 1646 1647 1648 1649
	sf = ((slot>>1)+1)%10;
#else
	sf = hw_subframe;
#endif
	//		    LOG_I(PHY,"[eNB] Multithread slot %d (IC %d)\n",slot,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt);
Raymond Knopp's avatar
 
Raymond Knopp committed
1650
	
Raymond Knopp's avatar
 
Raymond Knopp committed
1651
	for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
1652
#ifdef EXMIMO 
Raymond Knopp's avatar
 
Raymond Knopp committed
1653 1654
	  if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_tx) != 0) {
	    LOG_E(PHY,"[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx);   
Raymond Knopp's avatar
 
Raymond Knopp committed
1655
	  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1656 1657 1658 1659 1660 1661 1662
	  else {
	    //		      LOG_I(PHY,"[eNB] Waking up eNB process %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt); 
	    PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx++;
	    pthread_mutex_unlock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_tx);
	    if (PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx == 0) {
	      if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[sf].cond_tx) != 0) {
		LOG_E(PHY,"[eNB] ERROR pthread_cond_signal for eNB TX thread %d\n",sf);
1663
	      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1664 1665 1666 1667 1668
	    }
	    else {
	      LOG_W(PHY,"[eNB] Frame %d, eNB TX thread %d busy!!\n",PHY_vars_eNB_g[0][CC_id]->proc[sf].frame_tx,sf);
	      oai_exit=1;
	    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1669
	  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680
#endif	    
	  if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_rx) != 0) {
	    LOG_E(PHY,"[eNB] ERROR pthread_mutex_lock for eNB RX thread %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx);   
	  }
	  else {
	    //		      LOG_I(PHY,"[eNB] Waking up eNB process %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt); 
	    PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx++;
	    pthread_mutex_unlock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_rx);
	    if (PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx == 0) {
	      if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[sf].cond_rx) != 0) {
		LOG_E(PHY,"[eNB] ERROR pthread_cond_signal for eNB RX thread %d\n",sf);
Raymond Knopp's avatar
 
Raymond Knopp committed
1681
	      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1682 1683 1684 1685
	    }
	    else {
	      LOG_W(PHY,"[eNB] Frame %d, eNB RX thread %d busy!!\n",PHY_vars_eNB_g[0][CC_id]->proc[sf].frame_rx,sf);
	      oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1686
	    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1687
	  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1688
	    
Raymond Knopp's avatar
 
Raymond Knopp committed
1689 1690
	}
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1691 1692
	  
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1693 1694 1695 1696 1697 1698 1699
#ifndef RTAI
      //pthread_mutex_lock(&tti_mutex);
#endif




Raymond Knopp's avatar
 
Raymond Knopp committed
1700
#ifndef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
1701
      slot++;
Raymond Knopp's avatar
 
Raymond Knopp committed
1702 1703 1704 1705
      if (slot == 20) {
	frame++;
	slot = 0;
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1706
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1707 1708 1709
      hw_subframe++;
      slot+=2;
      if(hw_subframe==10) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1710
	hw_subframe = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1711
	frame++;
Raymond Knopp's avatar
 
Raymond Knopp committed
1712
	slot = 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1713
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1714
#endif     
Raymond Knopp's avatar
 
Raymond Knopp committed
1715 1716


1717
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1718
      itti_update_lte_time(frame, slot);
1719
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1720 1721 1722 1723 1724 1725
    }
  }
#ifdef DEBUG_THREADS
  printf("eNB_thread: finished, ran %d times.\n",frame);
#endif
  
1726
#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
1727
  rt_make_soft_real_time();
1728 1729
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1730 1731 1732 1733 1734

#ifdef DEBUG_THREADS
  printf("Exiting eNB_thread ...");
#endif
  // clean task
1735
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
1736 1737 1738 1739
  rt_task_delete(task);
#else
  eNB_thread_status = 0;
  pthread_exit(&eNB_thread_status);
1740
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1741 1742 1743 1744 1745
#ifdef DEBUG_THREADS
  printf("eNB_thread deleted. returning\n");
#endif
  return 0;
}
1746

Raymond Knopp's avatar
 
Raymond Knopp committed
1747 1748 1749
#ifdef USRP_DEBUG
int is_synchronized=1;
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1750
int is_synchronized=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1751
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1752 1753 1754

static void *UE_thread_synch(void *arg) {

1755
  int i,hw_slot_offset,CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1756 1757
  PHY_VARS_UE *UE = arg;

Raymond Knopp's avatar
 
Raymond Knopp committed
1758
  printf("UE_thread_sync in with PHY_vars_UE %p\n",arg);
Raymond Knopp's avatar
 
Raymond Knopp committed
1759
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
1760
  printf("waiting for USRP sync (UE_thread_synch) \n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1761 1762 1763
#ifdef RTAI
  rt_sem_wait(sync_sem);
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1764 1765 1766

  pthread_mutex_lock(&sync_mutex);
  printf("Locked sync_mutex, waiting (UE_sync_thread)\n");
1767 1768
  while (sync_var<0)
    pthread_cond_wait(&sync_cond, &sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
1769 1770
  pthread_mutex_unlock(&sync_mutex);
  printf("unlocked sync_mutex (UE_sync_thread)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1771
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1772
  printf("starting UE synch thread\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789
#endif
  
  while (!oai_exit) {
    
    if (pthread_mutex_lock(&UE->mutex_synch) != 0) {
      LOG_E(PHY,"[SCHED][eNB] error locking mutex for UE initial synch thread\n");
      oai_exit=1;
    }
    else {
      while (UE->instance_cnt_synch < 0) {
	pthread_cond_wait(&UE->cond_synch,&UE->mutex_synch);
      }
      if (pthread_mutex_unlock(&UE->mutex_synch) != 0) {	
	LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for UE Initial Synch thread\n");
	oai_exit=1;
      }
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805
    }  // mutex_lock      
    //    LOG_I(PHY,"[SCHED][UE] Running UE intial synch\n");
    if (initial_sync(PHY_vars_UE_g[0][0],mode)==0) {
      /*
	lte_adjust_synch(&PHY_vars_UE_g[0]->lte_frame_parms,
	PHY_vars_UE_g[0],
	0,
	1,
	16384);
      */
      //for better visualization afterwards
      /*
	for (aa=0; aa<PHY_vars_UE_g[0]->lte_frame_parms.nb_antennas_rx; aa++)
	memset(PHY_vars_UE_g[0]->lte_ue_common_vars.rxdata[aa],0,
	PHY_vars_UE_g[0]->lte_frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int));
      */
Raymond Knopp's avatar
 
Raymond Knopp committed
1806

Raymond Knopp's avatar
 
Raymond Knopp committed
1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820
      T0 = rt_get_time_ns();
      
      is_synchronized = 1;
      PHY_vars_UE_g[0][0]->slot_rx = 0;
      //oai_exit=1;
      //start the DMA transfers
      //LOG_D(HW,"Before openair0_start_rt_acquisition \n");
      //openair0_start_rt_acquisition(0);
      
      hw_slot_offset = (PHY_vars_UE_g[0][0]->rx_offset<<1) / PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti;
      LOG_I(HW,"Got synch: hw_slot_offset %d\n",hw_slot_offset);
      
    }
    else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1821
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1822 1823 1824
      if (openair_daq_vars.freq_offset >= 0) {
	openair_daq_vars.freq_offset += 100;
	openair_daq_vars.freq_offset *= -1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1825 1826
      }
      else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1827 1828 1829
	openair_daq_vars.freq_offset *= -1;
      }
      if (abs(openair_daq_vars.freq_offset) > 7500) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1830 1831
	LOG_I(PHY,"[initial_sync] No cell synchronization found, abandoning\n");
	mac_xface->macphy_exit("No cell synchronization found, abandoning");
Raymond Knopp's avatar
 
Raymond Knopp committed
1832 1833
      }
      else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1834 1835
	LOG_I(PHY,"[initial_sync] trying carrier off %d Hz, rxgain %d\n",openair_daq_vars.freq_offset,
	      PHY_vars_UE_g[0][0]->rx_total_gain_dB);
Raymond Knopp's avatar
 
Raymond Knopp committed
1836 1837 1838 1839
	for (card=0;card<MAX_CARDS;card++) {
	  for (i=0; i<openair0_cfg[card].rx_num_channels; i++) {
	    openair0_cfg[card].rx_freq[i] = downlink_frequency[card][i]+openair_daq_vars.freq_offset;
	    openair0_cfg[card].tx_freq[i] = downlink_frequency[card][i]+uplink_frequency_offset[card][i]+openair_daq_vars.freq_offset;
Raymond Knopp's avatar
 
Raymond Knopp committed
1840
	    openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB-73;  // 65 calibrated for USRP B210 @ 2.6 GHz
Navid Nikaein's avatar
Navid Nikaein committed
1841
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
1842 1843
#ifndef USRP_DEBUG
	    openair0_set_frequencies(&openair0,&openair0_cfg[0]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1844
	    //	    openair0_set_gains(&openair0,&openair0_cfg[0]);
Navid Nikaein's avatar
Navid Nikaein committed
1845
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1846
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1847
	  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865
	}

	//	    openair0_dump_config(&openair0_cfg[0],UE_flag);
	
	//	    rt_sleep_ns(FRAME_PERIOD);
      } // freq_offset
    } // initial_sync=0
    
    if (pthread_mutex_lock(&PHY_vars_UE_g[0][0]->mutex_synch) != 0) {
      printf("[openair][SCHED][eNB] error locking mutex for UE synch\n");
    }
    else {
      PHY_vars_UE_g[0][0]->instance_cnt_synch--;
      
      if (pthread_mutex_unlock(&PHY_vars_UE_g[0][0]->mutex_synch) != 0) {	
	printf("[openair][SCHED][eNB] error unlocking mutex for UE synch\n");
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932
    
  }  // while !oai_exit
  return(0);
}

static void *UE_thread_tx(void *arg) {

  PHY_VARS_UE *UE = (PHY_VARS_UE*)arg;

#ifndef OPENAIR2
  UE->UE_mode[eNB_id]=PUSCH;
  UE->prach_resources[eNB_id] = &prach_resources_local;
  prach_resources_local.ra_RNTI = 0xbeef;
  prach_resources_local.ra_PreambleIndex = 0;
#endif
  UE->instance_cnt_tx=-1;

  mlockall(MCL_CURRENT | MCL_FUTURE);

  while (!oai_exit) {

    if (pthread_mutex_lock(&UE->mutex_tx) != 0) {
      LOG_E(PHY,"[SCHED][eNB] error locking mutex for UE TX\n");
      oai_exit=1;
    }
    else {
      
      while (UE->instance_cnt_tx < 0) {
	pthread_cond_wait(&UE->cond_tx,&UE->mutex_tx);
      }
      if (pthread_mutex_unlock(&UE->mutex_tx) != 0) {	
	LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for UE TX\n");
	oai_exit=1;
      }
    }
  

    if ((subframe_select(&UE->lte_frame_parms,UE->slot_tx>>1)==SF_UL)||
	(UE->lte_frame_parms.frame_type == FDD)){
      phy_procedures_UE_TX(UE,eNB_id,0,mode,no_relay);
    }
    if ((subframe_select(&UE->lte_frame_parms,UE->slot_tx>>1)==SF_S) &&
	((UE->slot_tx&1)==1)) {
      phy_procedures_UE_S_TX(UE,eNB_id,0,no_relay);
    }

    if (pthread_mutex_lock(&UE->mutex_tx) != 0) {
      printf("[openair][SCHED][eNB] error locking mutex for UE TX thread\n");
    }
    else {
      UE->instance_cnt_tx--;
      
      if (pthread_mutex_unlock(&UE->mutex_tx) != 0) {	
	printf("[openair][SCHED][eNB] error unlocking mutex for UE\n");
      }
    }

    UE->slot_tx++;
    if (UE->slot_tx==20) {
      UE->slot_tx=0;
      UE->frame_tx++;
    }
  }
  return(0);
}

static void *UE_thread_rx(void *arg) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1933
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1934
  PHY_VARS_UE *UE = (PHY_VARS_UE*)arg;
Raymond Knopp's avatar
 
Raymond Knopp committed
1935 1936
  int i;
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1937
  UE->instance_cnt_rx=-1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1938
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1939
  mlockall(MCL_CURRENT | MCL_FUTURE);
Raymond Knopp's avatar
 
Raymond Knopp committed
1940
  
1941
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1942 1943 1944 1945 1946 1947
  printf("waiting for USRP sync (UE_thread_rx)\n");
#ifdef RTAI
  rt_sem_wait(sync_sem);
#else
  pthread_mutex_lock(&sync_mutex);
  printf("Locked sync_mutex, waiting (UE_thread_rx)\n");
1948 1949
  while (sync_var<0)
    pthread_cond_wait(&sync_cond, &sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
1950 1951 1952 1953
  pthread_mutex_unlock(&sync_mutex);
  printf("unlocked sync_mutex, waiting (UE_thread_rx)\n");
#endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1954

Raymond Knopp's avatar
 
Raymond Knopp committed
1955
  printf("Starting UE RX thread\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1956

Raymond Knopp's avatar
 
Raymond Knopp committed
1957 1958
  while (!oai_exit) { 
    printf("UE_thread_rx: locking UE RX mutex\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1959 1960 1961 1962 1963 1964
    if (pthread_mutex_lock(&UE->mutex_rx) != 0) {
      LOG_E(PHY,"[SCHED][eNB] error locking mutex for UE RX\n");
      oai_exit=1;
    }
    else {
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1965
      printf("UE_thread_rx: unlocking UE RX mutex (IC %d)\n",UE->instance_cnt_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1966
      while (UE->instance_cnt_rx < 0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1967
	printf("Waiting for cond_rx (%p)\n",(void*)&UE->cond_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1968
	pthread_cond_wait(&UE->cond_rx,&UE->mutex_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1969
	printf("Got UE RX condition, IC %d @ %llu\n",UE->instance_cnt_rx,rt_get_time_ns()-T0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1970 1971 1972 1973 1974
      }
      if (pthread_mutex_unlock(&UE->mutex_rx) != 0) {	
	LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for UE RX\n");
	oai_exit=1;
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991
      
      for (i=0;i<2;i++) {
	printf("UE_thread_rx: processing slot %d (slot rx %d) @ %llu\n",i,UE->slot_rx,rt_get_time_ns()-T0);
	if ((subframe_select(&UE->lte_frame_parms,UE->slot_rx>>1)==SF_DL) ||
	    (UE->lte_frame_parms.frame_type == FDD)){
	  phy_procedures_UE_RX(UE,eNB_id,0,mode,no_relay,NULL);
	}
	if ((subframe_select(&UE->lte_frame_parms,UE->slot_rx>>1)==SF_S) &&
	    ((UE->slot_rx&1)==0)) {
	  phy_procedures_UE_RX(UE,eNB_id,0,mode,no_relay,NULL);
	}
	
	UE->slot_rx++;
	if (UE->slot_rx==20) {
	  UE->slot_rx=0;
	  UE->frame_rx++;
	}    
Raymond Knopp's avatar
 
Raymond Knopp committed
1992
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1993 1994 1995 1996 1997 1998 1999
    }
    
    if (pthread_mutex_lock(&UE->mutex_rx) != 0) {
      printf("[openair][SCHED][eNB] error locking mutex for UE RX\n");
    }
    else {
      UE->instance_cnt_rx--;
Raymond Knopp's avatar
 
Raymond Knopp committed
2000
      
Raymond Knopp's avatar
 
Raymond Knopp committed
2001 2002 2003
      if (pthread_mutex_unlock(&UE->mutex_rx) != 0) {	
	printf("[openair][SCHED][eNB] error unlocking mutex for UE RX\n");
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2004
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
2005
    printf("UE_thread_rx done\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
2006
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
2007
       
Raymond Knopp's avatar
 
Raymond Knopp committed
2008 2009 2010
  return(0);
}

Raymond Knopp's avatar
 
Raymond Knopp committed
2011 2012 2013



2014
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
2015 2016 2017 2018 2019
#define RX_OFF_MAX 10
#define RX_OFF_MIN 5
#define RX_OFF_MID ((RX_OFF_MAX+RX_OFF_MIN)/2)

static void *UE_thread(void *arg) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2020

Raymond Knopp's avatar
 
Raymond Knopp committed
2021 2022 2023
  LTE_DL_FRAME_PARMS *frame_parms=&PHY_vars_UE_g[0][0]->lte_frame_parms;

  int slot=1,frame=0,hw_slot,last_slot, next_slot,hw_subframe=0,rx_cnt=0,tx_cnt=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2024
  // unsigned int aa;
Raymond Knopp's avatar
 
Raymond Knopp committed
2025
  int dummy[2][samples_per_packets];
Raymond Knopp's avatar
 
Raymond Knopp committed
2026 2027 2028 2029 2030
  int dummy_dump = 0;
  int tx_enabled=0;
  int start_rx_stream=0;
  int rx_off_diff = 0;
  int rx_correction_timer = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2031
  int i;
Raymond Knopp's avatar
 
Raymond Knopp committed
2032 2033 2034

  openair0_timestamp time0,time1;
  unsigned int rxs;
Raymond Knopp's avatar
 
Raymond Knopp committed
2035
  void *rxp[2],*txp[2];
Raymond Knopp's avatar
 
Raymond Knopp committed
2036

Raymond Knopp's avatar
 
Raymond Knopp committed
2037
  printf("waiting for USRP sync (UE_thread)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
2038 2039 2040
#ifdef RTAI
  rt_sem_wait(sync_sem);
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
2041 2042
  pthread_mutex_lock(&sync_mutex);
  printf("Locked sync_mutex, waiting (UE_thread)\n");
2043 2044
  while (sync_var<0)
    pthread_cond_wait(&sync_cond, &sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
2045 2046
  pthread_mutex_unlock(&sync_mutex);
  printf("unlocked sync_mutex, waiting (UE_thread)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
2047
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2048 2049 2050 2051

  printf("starting UE thread\n");

  T0 = rt_get_time_ns();
Raymond Knopp's avatar
 
Raymond Knopp committed
2052 2053 2054
  while (!oai_exit) {
    vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME, hw_subframe);
    vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, frame);
Raymond Knopp's avatar
 
Raymond Knopp committed
2055

Raymond Knopp's avatar
 
Raymond Knopp committed
2056

Raymond Knopp's avatar
 
Raymond Knopp committed
2057
    while (rx_cnt < sf_bounds[hw_subframe]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2058
  
Raymond Knopp's avatar
 
Raymond Knopp committed
2059
      vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
2060 2061
  
#ifndef USRP_DEBUG
Raymond Knopp's avatar
 
Raymond Knopp committed
2062 2063 2064

      for (i=0;i<PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_rx;i++)
	rxp[i] = (dummy_dump==0) ? (void*)&rxdata[i][rx_cnt*samples_per_packets] : (void*)dummy[i];
Raymond Knopp's avatar
 
Raymond Knopp committed
2065 2066
      rxs = openair0.trx_read_func(&openair0,
				   &timestamp,
Raymond Knopp's avatar
 
Raymond Knopp committed
2067 2068 2069
				   rxp,
				   samples_per_packets - ((rx_cnt==0) ? rx_off_diff : 0),
				   PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
2070
      if (rxs != (samples_per_packets- ((rx_cnt==0) ? rx_off_diff : 0)))
Raymond Knopp's avatar
 
Raymond Knopp committed
2071
	oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
2072 2073

      rx_off_diff = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2074 2075 2076
      vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,0);
      
      // Transmit TX buffer based on timestamp from RX
Raymond Knopp's avatar
 
Raymond Knopp committed
2077
      if (tx_enabled) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2078
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
2079 2080
	for (i=0;i<PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_tx;i++)
	  txp[i] = (void*)&txdata[i][tx_cnt*samples_per_packets];
Raymond Knopp's avatar
 
Raymond Knopp committed
2081 2082
	openair0.trx_write_func(&openair0,
				(timestamp+samples_per_packets*tx_delay-tx_forward_nsamps),
Raymond Knopp's avatar
 
Raymond Knopp committed
2083
				txp,
Raymond Knopp's avatar
 
Raymond Knopp committed
2084
				samples_per_packets,
Raymond Knopp's avatar
 
Raymond Knopp committed
2085
				PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_tx,
Raymond Knopp's avatar
 
Raymond Knopp committed
2086
				1);
Raymond Knopp's avatar
 
Raymond Knopp committed
2087
				
Raymond Knopp's avatar
 
Raymond Knopp committed
2088 2089
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,0);
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2090 2091 2092
#else
      rt_sleep_ns(10000000);
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2093 2094 2095 2096 2097 2098 2099 2100
      rx_cnt++;
      tx_cnt++;
      
      if(tx_cnt == max_cnt)
	tx_cnt = 0;
    }
    
    if(rx_cnt == max_cnt)
Raymond Knopp's avatar
 
Raymond Knopp committed
2101 2102 2103
      rx_cnt = 0;


Raymond Knopp's avatar
 
Raymond Knopp committed
2104
    
Raymond Knopp's avatar
 
Raymond Knopp committed
2105
    if (is_synchronized==1)  {
Raymond Knopp's avatar
 
Raymond Knopp committed
2106 2107
      LOG_D(HW,"UE_thread: hw_frame %d, hw_subframe %d (time %llu)\n",frame,hw_subframe,rt_get_time_ns()-T0);

Raymond Knopp's avatar
 
Raymond Knopp committed
2108 2109 2110 2111 2112 2113 2114
      if (start_rx_stream==1) {
	//	printf("UE_thread: locking UE mutex_rx\n");
	if (pthread_mutex_lock(&PHY_vars_UE_g[0][0]->mutex_rx) != 0) {
	  LOG_E(PHY,"[SCHED][UE] error locking mutex for UE RX thread\n");
	  oai_exit=1;
	}
	else {
Raymond Knopp's avatar
 
Raymond Knopp committed
2115
 	  
Raymond Knopp's avatar
 
Raymond Knopp committed
2116 2117 2118 2119
	  PHY_vars_UE_g[0][0]->instance_cnt_rx++;
	  //	  printf("UE_thread: Unlocking UE mutex_rx\n");
	  pthread_mutex_unlock(&PHY_vars_UE_g[0][0]->mutex_rx);
	  if (PHY_vars_UE_g[0][0]->instance_cnt_rx == 0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2120
	    LOG_D(HW,"Scheduling UE RX for frame %d (hw frame %d), subframe %d (%d), mode %d\n",PHY_vars_UE_g[0][0]->frame_rx,frame,hw_subframe,PHY_vars_UE_g[0][0]->slot_rx>>1,mode);
Raymond Knopp's avatar
 
Raymond Knopp committed
2121 2122 2123 2124 2125 2126 2127 2128 2129
	    if (pthread_cond_signal(&PHY_vars_UE_g[0][0]->cond_rx) != 0) {
	      LOG_E(PHY,"[SCHED][UE] ERROR pthread_cond_signal for UE RX thread\n");
	      oai_exit=1;
	    }
	    else {
	      //	      printf("UE_thread: cond_signal for RX ok (%p) @ %llu\n",(void*)&PHY_vars_UE_g[0][0]->cond_rx,rt_get_time_ns()-T0);
	    }
	    if (mode == rx_calib_ue) {
	      if (frame == 10) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2130
		LOG_D(PHY,"[SCHED][UE] Found cell with N_RB_DL %d, PHICH CONFIG (%d,%d), Nid_cell %d, NB_ANTENNAS_TX %d, initial frequency offset %d Hz, frequency offset %d Hz, RSSI (digital) %d dB, measured Gain %d dB, total_rx_gain %d dB, USRP rx gain %f dB\n",
Raymond Knopp's avatar
 
Raymond Knopp committed
2131 2132 2133 2134 2135 2136 2137 2138
		      PHY_vars_UE_g[0][0]->lte_frame_parms.N_RB_DL,
		      PHY_vars_UE_g[0][0]->lte_frame_parms.phich_config_common.phich_duration,
		      PHY_vars_UE_g[0][0]->lte_frame_parms.phich_config_common.phich_resource,
		      PHY_vars_UE_g[0][0]->lte_frame_parms.Nid_cell,
		      PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_tx_eNB,
		      openair_daq_vars.freq_offset,
		      PHY_vars_UE_g[0][0]->lte_ue_common_vars.freq_offset,
		      PHY_vars_UE_g[0][0]->PHY_measurements.rx_power_avg_dB[0],
Raymond Knopp's avatar
 
Raymond Knopp committed
2139 2140 2141
		      PHY_vars_UE_g[0][0]->PHY_measurements.rx_power_avg_dB[0] - rx_input_level_dBm,
		      PHY_vars_UE_g[0][0]->rx_total_gain_dB,
		      openair0_cfg[0].rx_gain[0]
Raymond Knopp's avatar
 
Raymond Knopp committed
2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152
		      );
		exit_fun("[HW][UE] UE in RX calibration mode, exiting");
	      }
	    }
	  }
	  else {
	    LOG_E(PHY,"[SCHED][UE] UE RX thread busy!!\n");
	    oai_exit=1;
	  }
	}
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2153 2154 2155
    }
    else {  // we are not yet synchronized
      
Raymond Knopp's avatar
 
Raymond Knopp committed
2156
      if ((hw_subframe == 9)&&(dummy_dump == 0)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2157
	// Wake up initial synch thread
Raymond Knopp's avatar
 
Raymond Knopp committed
2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177
	if (pthread_mutex_lock(&PHY_vars_UE_g[0][0]->mutex_synch) != 0) {
	  LOG_E(PHY,"[SCHED][UE] error locking mutex for UE initial synch thread\n");
	  oai_exit=1;
	}
	else {
	  
	  PHY_vars_UE_g[0][0]->instance_cnt_synch++;
	  pthread_mutex_unlock(&PHY_vars_UE_g[0][0]->mutex_synch);
	  dummy_dump = 1;
	  if (PHY_vars_UE_g[0][0]->instance_cnt_synch == 0) {
	    if (pthread_cond_signal(&PHY_vars_UE_g[0][0]->cond_synch) != 0) {
	      LOG_E(PHY,"[SCHED][UE] ERROR pthread_cond_signal for UE sync thread\n");
	      oai_exit=1;
	    }
	  }
	  else {
	    LOG_E(PHY,"[SCHED][UE] UE sync thread busy!!\n");
	    oai_exit=1;
	  }
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
2178
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2179
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190
    /*
      if ((slot%2000)<10)
      LOG_D(HW,"fun0: doing very hard work\n");
    */
    
    hw_subframe++;
    slot+=2;
    if(hw_subframe==10) {
      hw_subframe = 0;
      frame++;
      slot = 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
2191 2192
      if (PHY_vars_UE_g[0][0]->instance_cnt_synch < 0) {
	if (is_synchronized == 1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2193
	  //	  openair0_set_gains(&openair0,&openair0_cfg[0]);
Raymond Knopp's avatar
 
Raymond Knopp committed
2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204
	  rx_off_diff = 0;
	  //	  LOG_D(PHY,"HW RESYNC: hw_frame %d: rx_offset = %d\n",frame,PHY_vars_UE_g[0][0]->rx_offset);
	  if ((PHY_vars_UE_g[0][0]->rx_offset > RX_OFF_MAX)&&(start_rx_stream==0)) {
	    start_rx_stream=1;
	    //LOG_D(PHY,"HW RESYNC: hw_frame %d: Resynchronizing sample stream\n");
	    frame=0;
	    // dump ahead in time to start of frame
#ifndef USRP_DEBUG
	    rxs = openair0.trx_read_func(&openair0,
					 &timestamp,
					 &rxdata[0],
Raymond Knopp's avatar
 
Raymond Knopp committed
2205 2206
					 PHY_vars_UE_g[0][0]->rx_offset,
					 PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224
#else
	    rt_sleep_ns(10000000);
#endif
	    PHY_vars_UE_g[0][0]->rx_offset=0;
	  }
	  else if ((PHY_vars_UE_g[0][0]->rx_offset < RX_OFF_MIN)&&(start_rx_stream==1)) {
	    //	    rx_off_diff = -PHY_vars_UE_g[0][0]->rx_offset + RX_OFF_MIN;
	  }
	  else if ((PHY_vars_UE_g[0][0]->rx_offset > (FRAME_LENGTH_COMPLEX_SAMPLES-RX_OFF_MAX)) &&(start_rx_stream==1) && (rx_correction_timer == 0)) {
	    rx_off_diff = FRAME_LENGTH_COMPLEX_SAMPLES-PHY_vars_UE_g[0][0]->rx_offset;
	    rx_correction_timer = 5;
	  }
	  if (rx_correction_timer>0)
	    rx_correction_timer--;
	  //	  LOG_D(PHY,"HW RESYNC: hw_frame %d: Correction: rx_off_diff %d (timer %d)\n",frame,rx_off_diff,rx_correction_timer);
	}
	dummy_dump=0;
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2225 2226 2227 2228 2229 2230 2231
    }
    
#if defined(ENABLE_ITTI)
    itti_update_lte_time(frame, slot);
#endif
  }
}
2232
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2233

Raymond Knopp's avatar
 
Raymond Knopp committed
2234 2235


2236
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
2237 2238
/* This is the main UE thread. Initially it is doing a periodic get_frame. One synchronized it gets woken up by the kernel driver using the RTAI message mechanism (rt_send and rt_receive). */
static void *UE_thread(void *arg) {
2239
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2240 2241 2242
  RT_TASK *task;
#endif
  // RTIME in, out, diff;
Raymond Knopp's avatar
 
Raymond Knopp committed
2243
  int slot=0,frame=0,hw_slot,last_slot,next_slot;
Raymond Knopp's avatar
 
Raymond Knopp committed
2244 2245 2246 2247 2248 2249 2250
  // unsigned int aa;
  static int is_synchronized = 0;
  int delay_cnt;
  RTIME time_in;
  int hw_slot_offset=0,rx_offset_mbox=0,mbox_target=0,mbox_current=0;
  int diff2;
  int i, ret;
2251
  int CC_id,card;
Raymond Knopp's avatar
 
Raymond Knopp committed
2252 2253
  volatile unsigned int *DAQ_MBOX = openair0_daq_cnt();
#ifndef USRP
2254
  //exmimo_config_t *p_exmimo_config = openair0_exmimo_pci[card].exmimo_config_ptr;;
Raymond Knopp's avatar
 
Raymond Knopp committed
2255 2256
#endif

2257

2258
#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
Raymond Knopp's avatar
 
Raymond Knopp committed
2259 2260
  /* Wait for NAS UE to start cell selection */
  wait_system_ready ("Waiting for UE to be activated by UserProcess %s\r", &start_UE);
2261 2262
#endif

2263
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2264 2265
  task = rt_task_init_schmod(nam2num("TASK0"), 0, 0, 0, SCHED_FIFO, 0xF);
  LOG_D(HW,"Started UE thread (id %p)\n",task);
2266 2267 2268
#endif

#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
2269
  rt_make_hard_real_time();
2270 2271
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2272
  mlockall(MCL_CURRENT | MCL_FUTURE);
2273

Raymond Knopp's avatar
 
Raymond Knopp committed
2274 2275 2276 2277 2278 2279 2280 2281
  openair_daq_vars.freq_offset = 0; //-7500;
  /*
    if (mode == rx_calib_ue) {
    openair_daq_vars.freq_offset = -7500;
    for (i=0; i<4; i++) {
    p_exmimo_config->rf.rf_freq_rx[i] = p_exmimo_config->rf.rf_freq_rx[i]+openair_daq_vars.freq_offset;
    p_exmimo_config->rf.rf_freq_tx[i] = p_exmimo_config->rf.rf_freq_rx[i]+openair_daq_vars.freq_offset;
    }
2282
    openair0_dump_config(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
2283 2284 2285
    }
  */
  while (!oai_exit)  {
Raymond Knopp's avatar
 
Raymond Knopp committed
2286

Raymond Knopp's avatar
 
Raymond Knopp committed
2287
    hw_slot = (((((volatile unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15; //the slot the hw is about to store
Raymond Knopp's avatar
 
Raymond Knopp committed
2288 2289

     
Raymond Knopp's avatar
 
Raymond Knopp committed
2290
    if (is_synchronized) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2291 2292


Raymond Knopp's avatar
 
Raymond Knopp committed
2293
      //this is the mbox counter that indicates the start of the frame
Raymond Knopp's avatar
 
Raymond Knopp committed
2294
      rx_offset_mbox = (PHY_vars_UE_g[0][0]->rx_offset * 150) / (10*PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti);
Raymond Knopp's avatar
 
Raymond Knopp committed
2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307
      //this is the mbox counter where we should be
      mbox_target = (((((slot+1)%20)*15+1)>>1) + rx_offset_mbox + 1)%150;
      // round up to the next multiple of two (mbox counter from express MIMO gives only even numbers)
      mbox_target = ((mbox_target+1)-((mbox_target-1)%2))%150;
      //this is the mbox counter where we are
      mbox_current = ((volatile unsigned int *)DAQ_MBOX)[0];
      //this is the time we need to sleep in order to synchronize with the hw (in multiples of DAQ_PERIOD)
      if ((mbox_current>=120) && (mbox_target<30)) //handle the frame wrap-arround
	diff2 = 150-mbox_current+mbox_target;
      else if ((mbox_current<30) && (mbox_target>=120))
	diff2 = -150+mbox_target-mbox_current;
      else
	diff2 = mbox_target - mbox_current;
2308
	
Raymond Knopp's avatar
 
Raymond Knopp committed
2309 2310
      if (diff2 <(-7)) {
	LOG_D(HW,"UE Frame %d: missed slot, proceeding with next one (slot %d, hw_slot %d, diff %d)\n",frame, slot, hw_slot, diff2);
2311 2312 2313 2314 2315 2316 2317 2318
	if (frame>0){
	  if (exit_missed_slots==1)
	    exit_fun("[HW][UE] missed slot");
	  else{
	    num_missed_slots++;
	    LOG_W(HW,"[UE] just missed slot (total missed slots %ld)\n", num_missed_slots);
	  }
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
2319 2320 2321 2322
	slot++;
	if (slot==20) {
	  slot=0;
	  frame++;
Raymond Knopp's avatar
 
Raymond Knopp committed
2323
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347
	continue;
      }
      if (diff2>8)
	LOG_D(HW,"UE Frame %d: skipped slot, waiting for hw to catch up (slot %d, hw_slot %d, mbox_current %d, mbox_target %d, diff %d)\n",frame, slot, hw_slot, mbox_current, mbox_target, diff2);
	
      /*
	if (frame%100==0)
	LOG_D(HW,"frame %d (%d), slot %d, hw_slot %d, rx_offset_mbox %d, mbox_target %d, mbox_current %d, diff %d\n",frame, PHY_vars_UE_g[0]->frame, slot,hw_slot,rx_offset_mbox,mbox_target,mbox_current,diff2);
      */
	
      vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *DAQ_MBOX);
      vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DIFF, diff2);
	
      delay_cnt = 0;
      while ((diff2>0) && (!oai_exit) && (is_synchronized) )  {
	time_in = rt_get_time_ns();
	//LOG_D(HW,"eNB Frame %d delaycnt %d : hw_slot %d (%d), slot %d (%d), diff %d, time %llu\n",frame,delay_cnt,hw_slot,((volatile unsigned int *)DAQ_MBOX)[0],slot,mbox_target,diff2,time_in);
	vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *DAQ_MBOX);
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RT_SLEEP,1);
	ret = rt_sleep_ns(diff2*DAQ_PERIOD);
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RT_SLEEP,0);
	vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *DAQ_MBOX);
	if (ret)
	  LOG_D(HW,"eNB Frame %d, time %llu: rt_sleep_ns returned %d\n",frame, time_in);
2348
	  
Raymond Knopp's avatar
 
Raymond Knopp committed
2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373
	hw_slot = (((((volatile unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15;
	//LOG_D(HW,"eNB Frame %d : hw_slot %d, time %llu\n",frame,hw_slot,rt_get_time_ns());
	delay_cnt++;
	if (delay_cnt == 30)  {
	  LOG_D(HW,"UE frame %d: HW stopped ... \n",frame);
	  exit_fun("[HW][UE] HW stopped");
	}
	mbox_current = ((volatile unsigned int *)DAQ_MBOX)[0];
	if ((mbox_current>=135) && (mbox_target<15)) //handle the frame wrap-arround
	  diff2 = 150-mbox_current+mbox_target;
	else if ((mbox_current<15) && (mbox_target>=135))
	  diff2 = -150+mbox_target-mbox_current;
	else
	  diff2 = mbox_target - mbox_current;
	  
	vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *DAQ_MBOX);
	vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DIFF, diff2);
      }
	
    }
      
    last_slot = (slot)%LTE_SLOTS_PER_FRAME;
    if (last_slot <0)
      last_slot+=LTE_SLOTS_PER_FRAME;
    next_slot = (slot+3)%LTE_SLOTS_PER_FRAME;
2374 2375 2376 2377 2378 2379 2380 2381

    PHY_vars_UE_g[0][0]->slot_rx = last_slot;
    PHY_vars_UE_g[0][0]->slot_tx = next_slot;
    if (PHY_vars_UE_g[0][0]->slot_rx==20) 
      PHY_vars_UE_g[0][0]->frame_rx++;
    if (PHY_vars_UE_g[0][0]->slot_tx==20) 
      PHY_vars_UE_g[0][0]->frame_tx++;

Raymond Knopp's avatar
 
Raymond Knopp committed
2382 2383
      
    if (is_synchronized)  {
2384
      phy_procedures_UE_lte (PHY_vars_UE_g[0][0], 0, 0, mode, 0, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
2385 2386 2387 2388 2389 2390
	
    }
    else {  // we are not yet synchronized
      hw_slot_offset = 0;
	
      slot = 0;
2391
      openair0_get_frame(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
2392 2393 2394 2395
      //          LOG_D(HW,"after get_frame\n");
      //          rt_sleep_ns(FRAME_PERIOD);
      //          LOG_D(HW,"after sleep\n");
	
Raymond Knopp's avatar
 
Raymond Knopp committed
2396
      if (initial_sync(PHY_vars_UE_g[0][0],mode)==0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2397
	/*
Raymond Knopp's avatar
 
Raymond Knopp committed
2398 2399 2400 2401 2402
	  lte_adjust_synch(&PHY_vars_UE_g[0]->lte_frame_parms,
	  PHY_vars_UE_g[0],
	  0,
	  1,
	  16384);
Raymond Knopp's avatar
 
Raymond Knopp committed
2403
	*/
Raymond Knopp's avatar
 
Raymond Knopp committed
2404 2405 2406 2407 2408 2409
	//for better visualization afterwards
	/*
	  for (aa=0; aa<PHY_vars_UE_g[0]->lte_frame_parms.nb_antennas_rx; aa++)
	  memset(PHY_vars_UE_g[0]->lte_ue_common_vars.rxdata[aa],0,
	  PHY_vars_UE_g[0]->lte_frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int));
	*/
2410 2411
	
	/*if (mode == rx_calib_ue) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2412
	  exit_fun("[HW][UE] UE in RX calibration mode");
Raymond Knopp's avatar
 
Raymond Knopp committed
2413
	}
2414
	else {*/
Raymond Knopp's avatar
 
Raymond Knopp committed
2415 2416 2417
	  is_synchronized = 1;
	  //start the DMA transfers
	  //LOG_D(HW,"Before openair0_start_rt_acquisition \n");
2418 2419
	  for (card=0;card<openair0_num_detected_cards;card++)
	    openair0_start_rt_acquisition(card);
Raymond Knopp's avatar
 
Raymond Knopp committed
2420
	    
Raymond Knopp's avatar
 
Raymond Knopp committed
2421
	  hw_slot_offset = (PHY_vars_UE_g[0][0]->rx_offset<<1) / PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti;
Raymond Knopp's avatar
 
Raymond Knopp committed
2422 2423
	  //LOG_D(HW,"Got synch: hw_slot_offset %d\n",hw_slot_offset);
	  oai_exit=1;
2424
	  /*}*/
Raymond Knopp's avatar
 
Raymond Knopp committed
2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438
      }
      else {
	if (openair_daq_vars.freq_offset >= 0) {
	  openair_daq_vars.freq_offset += 100;
	  openair_daq_vars.freq_offset *= -1;
	}
	else {
	  openair_daq_vars.freq_offset *= -1;
	}
	if (abs(openair_daq_vars.freq_offset) > 7500) {
	  LOG_I(PHY,"[initial_sync] No cell synchronization found, abondoning\n");
	  mac_xface->macphy_exit("No cell synchronization found, abondoning");
	}
	else {
Raymond Knopp's avatar
 
Raymond Knopp committed
2439
	  //	  LOG_I(PHY,"[initial_sync] trying carrier off %d Hz\n",openair_daq_vars.freq_offset);
Raymond Knopp's avatar
 
Raymond Knopp committed
2440
#ifndef USRP
2441 2442 2443 2444 2445
	  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
	    for (i=0; i<openair0_cfg[rf_map[CC_id].card].rx_num_channels; i++) 
	      openair0_cfg[rf_map[CC_id].card].rx_freq[rf_map[CC_id].chain+i] = downlink_frequency[CC_id][i]+openair_daq_vars.freq_offset;
	    for (i=0; i<openair0_cfg[rf_map[CC_id].card].tx_num_channels; i++) 
	      openair0_cfg[rf_map[CC_id].card].tx_freq[rf_map[CC_id].chain+i] = downlink_frequency[CC_id][i]+openair_daq_vars.freq_offset;
Raymond Knopp's avatar
 
Raymond Knopp committed
2446
	  }
2447
	  openair0_config(&openair0_cfg[0],UE_flag);
2448
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2449 2450
	  rt_sleep_ns(FRAME_PERIOD);
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
2451
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2452
    }
2453
    
Raymond Knopp's avatar
 
Raymond Knopp committed
2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467
    /*
      if ((slot%2000)<10)
      LOG_D(HW,"fun0: doing very hard work\n");
    */
    slot++;
    if (slot==20) {
      slot=0;
      frame++;
    }
#if defined(ENABLE_ITTI)
    itti_update_lte_time(frame, slot);
#endif
  }
  LOG_D(HW,"UE_thread: finished, ran %d times.\n",frame);
2468 2469

#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
2470
  rt_make_soft_real_time();
2471 2472
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2473
  // clean task
2474
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2475
  rt_task_delete(task);
2476
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2477 2478 2479
  LOG_D(HW,"Task deleted. returning\n");
  return 0;
}
2480

Raymond Knopp's avatar
 
Raymond Knopp committed
2481
#else  // This is for USRP or ETHERNET targets
2482

2483
#endif
2484

2485

Raymond Knopp's avatar
 
Raymond Knopp committed
2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515
void init_UE_threads(void) {
  
  PHY_VARS_UE *UE=PHY_vars_UE_g[0][0];

  pthread_attr_init(&attr_UE_thread_tx);
  pthread_attr_setstacksize(&attr_UE_thread_tx,OPENAIR_THREAD_STACK_SIZE);
  sched_param_UE_thread_tx.sched_priority = sched_get_priority_max(SCHED_FIFO)-1;
  pthread_attr_setschedparam  (&attr_UE_thread_tx, &sched_param_UE_thread_tx);
  pthread_attr_setschedpolicy (&attr_UE_thread_tx, SCHED_FIFO);

  pthread_attr_init(&attr_UE_thread_rx);
  pthread_attr_setstacksize(&attr_UE_thread_rx,OPENAIR_THREAD_STACK_SIZE);
  sched_param_UE_thread_rx.sched_priority = sched_get_priority_max(SCHED_FIFO)-1;
  pthread_attr_setschedparam  (&attr_UE_thread_rx, &sched_param_UE_thread_rx);
  pthread_attr_setschedpolicy (&attr_UE_thread_rx, SCHED_FIFO);

  UE->instance_cnt_tx=-1;
  UE->instance_cnt_rx=-1;
  UE->instance_cnt_synch=-1;
  pthread_mutex_init(&UE->mutex_tx,NULL);
  pthread_mutex_init(&UE->mutex_rx,NULL);
  pthread_mutex_init(&UE->mutex_synch,NULL);
  pthread_cond_init(&UE->cond_tx,NULL);
  pthread_cond_init(&UE->cond_rx,NULL);
  pthread_cond_init(&UE->cond_synch,NULL);
  pthread_create(&UE->thread_tx,NULL,UE_thread_tx,(void*)UE);
  pthread_create(&UE->thread_rx,NULL,UE_thread_rx,(void*)UE);
  pthread_create(&UE->thread_rx,NULL,UE_thread_synch,(void*)UE);
  UE->frame_tx = 0;

2516
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527
  UE->slot_tx = 2;
  UE->slot_rx = 0;
  UE->frame_rx = 0;
#else
  UE->slot_tx = 1;
  UE->slot_rx = 19;
  UE->frame_rx = 0;
#endif

  
  
Raymond Knopp's avatar
 
Raymond Knopp committed
2528
}
Raymond Knopp's avatar
 
Raymond Knopp committed
2529 2530


Raymond Knopp's avatar
 
Raymond Knopp committed
2531
static void get_options (int argc, char **argv) {
2532
  int c;
Raymond Knopp's avatar
 
Raymond Knopp committed
2533 2534
  //  char                          line[1000];
  //  int                           l;
2535
  int k;//i,j,k;
Raymond Knopp's avatar
 
Raymond Knopp committed
2536 2537 2538
#ifdef USRP
  int clock_src;
#endif
2539
  int CC_id;
2540 2541 2542
  char rxg_fname[256], line[1000];
  FILE *rxg_fd;
  int l;
2543

Raymond Knopp's avatar
 
Raymond Knopp committed
2544 2545 2546 2547 2548 2549 2550 2551 2552
  const Enb_properties_array_t *enb_properties;
  
  enum long_option_e {
    LONG_OPTION_START = 0x100, /* Start after regular single char options */
    LONG_OPTION_ULSCH_MAX_CONSECUTIVE_ERRORS,
    LONG_OPTION_CALIB_UE_RX,
    LONG_OPTION_CALIB_UE_RX_MED,
    LONG_OPTION_CALIB_UE_RX_BYP,
    LONG_OPTION_DEBUG_UE_PRACH,
2553
    LONG_OPTION_NO_L2_CONNECT
Raymond Knopp's avatar
 
Raymond Knopp committed
2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564
  };
  
  static const struct option long_options[] = {
    {"ulsch-max-errors",required_argument,  NULL, LONG_OPTION_ULSCH_MAX_CONSECUTIVE_ERRORS},
    {"calib-ue-rx",     required_argument,  NULL, LONG_OPTION_CALIB_UE_RX},
    {"calib-ue-rx-med", required_argument,  NULL, LONG_OPTION_CALIB_UE_RX_MED},
    {"calib-ue-rx-byp", required_argument,  NULL, LONG_OPTION_CALIB_UE_RX_BYP},
    {"debug-ue-prach",  no_argument,        NULL, LONG_OPTION_DEBUG_UE_PRACH},
    {"no-L2-connect",   no_argument,        NULL, LONG_OPTION_NO_L2_CONNECT},
    {NULL, 0, NULL, 0}};
  
2565
  while ((c = getopt_long (argc, argv, "C:dK:g:F:G:qO:m:SUVRMr:P:s:t:x:",long_options,NULL)) != -1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597
    switch (c) {
    case LONG_OPTION_ULSCH_MAX_CONSECUTIVE_ERRORS:
      ULSCH_max_consecutive_errors = atoi(optarg);
      printf("Set ULSCH_max_consecutive_errors = %d\n",ULSCH_max_consecutive_errors);
      break;
      
    case LONG_OPTION_CALIB_UE_RX:
      mode = rx_calib_ue;
      rx_input_level_dBm = atoi(optarg);
      printf("Running with UE calibration on (LNA max), input level %d dBm\n",rx_input_level_dBm);
      break;
      
    case LONG_OPTION_CALIB_UE_RX_MED:
      mode = rx_calib_ue_med;
      rx_input_level_dBm = atoi(optarg);
      printf("Running with UE calibration on (LNA med), input level %d dBm\n",rx_input_level_dBm);
      break;
      
    case LONG_OPTION_CALIB_UE_RX_BYP:
      mode = rx_calib_ue_byp;
      rx_input_level_dBm = atoi(optarg);
      printf("Running with UE calibration on (LNA byp), input level %d dBm\n",rx_input_level_dBm);
      break;
      
    case LONG_OPTION_DEBUG_UE_PRACH:
      mode = debug_prach;
      break;
      
    case LONG_OPTION_NO_L2_CONNECT:
      mode = no_L2_connect;
      break;
    case 'M':
Raymond Knopp's avatar
 
Raymond Knopp committed
2598
      multi_thread=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2599 2600
      break;
    case 'C':
2601
      for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
2602 2603 2604 2605 2606
	downlink_frequency[CC_id][0] = atof(optarg); // Use float to avoid issue with frequency over 2^31.
	downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0];
	downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0];
	downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0];
	printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]);
2607
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2608 2609 2610 2611 2612
      break;
      
    case 'd':
#ifdef XFORMS
      do_forms=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
2613
      printf("Running with XFORMS!\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631
#endif
      break;
      
    case 'K':
#if defined(ENABLE_ITTI)
      itti_dump_file = strdup(optarg);
#else
      printf("-K option is disabled when ENABLE_ITTI is not defined\n");
#endif
      break;
      
    case 'O':
      conf_config_file_name = optarg;
      break;
      
    case 'U':
      UE_flag = 1;
      break;
2632 2633 2634 2635 2636 2637 2638
    
    case 'm':
      target_dl_mcs = atoi (optarg);
      break;
    case 't':
      target_ul_mcs = atoi (optarg);
      break;
2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654
    case 'P':
      /* enable openair packet tracer (OPT)*/
      if ((strcmp(optarg, "wireshark") == 0) || 
	  (strcmp(optarg, "WIRESHARK") == 0)) {
	opt_type = OPT_WIRESHARK;
	printf("Enabling OPT for wireshark\n");
      } else if ((strcmp(optarg, "pcap") == 0) ||
		 (strcmp(optarg, "PCAP") == 0)){
	opt_type = OPT_PCAP;
	printf("Enabling OPT for pcap\n");
      } else {
	opt_type = OPT_NONE;
	printf("Unrecognized option for OPT module\n");
	printf("Possible values are either wireshark or pcap\n");
      }
      break;  
Raymond Knopp's avatar
 
Raymond Knopp committed
2655 2656 2657 2658
      
    case 'V':
      ouput_vcd = 1;
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
2659
    case  'q':
Raymond Knopp's avatar
 
Raymond Knopp committed
2660 2661 2662 2663 2664 2665
      opp_enabled = 1;
      break;
    case  'R' :
      online_log_messages =1;
      break;
    case 'r':
Raymond Knopp's avatar
 
Raymond Knopp committed
2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687
      for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
	switch(atoi(optarg)) {
	case 6:
	  frame_parms[CC_id]->N_RB_DL=6;
	  frame_parms[CC_id]->N_RB_UL=6;
	  break;
	case 25:
	  frame_parms[CC_id]->N_RB_DL=25;
	  frame_parms[CC_id]->N_RB_UL=25;
	  break;
	case 50:
	  frame_parms[CC_id]->N_RB_DL=50;
	  frame_parms[CC_id]->N_RB_UL=50;
	  break;
	case 100:
	  frame_parms[CC_id]->N_RB_DL=100;
	  frame_parms[CC_id]->N_RB_UL=100;
	  break;
	default:
	  printf("Unknown N_RB_DL %d, switching to 25\n",atoi(optarg));
	  break;
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
2688
      }
2689
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
2690 2691
    case 's':
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
2692 2693 2694

      clock_src = atoi(optarg);
      if (clock_src == 0) {
2695
	//	char ref[128] = "internal";
Raymond Knopp's avatar
 
Raymond Knopp committed
2696 2697 2698
	//strncpy(uhd_ref, ref, strlen(ref)+1);
      }
      else if (clock_src == 1) {
2699
	//char ref[128] = "external";
Raymond Knopp's avatar
 
Raymond Knopp committed
2700 2701
	//strncpy(uhd_ref, ref, strlen(ref)+1);
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2702 2703 2704 2705
#else
      printf("Note: -s not defined for ExpressMIMO2\n");
#endif
      break;
2706 2707 2708 2709
    case 'S':
      exit_missed_slots=0;
      printf("Skip exit for missed slots\n");
      break;
2710
    case 'g':
Raymond Knopp's avatar
 
Raymond Knopp committed
2711
      glog_level=atoi(optarg); // value between 1 - 9
2712
      break;
2713 2714

    case 'F':
2715
#ifdef EXMIMO
2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732
      sprintf(rxg_fname,"%srxg.lime",optarg);
      rxg_fd = fopen(rxg_fname,"r");
      if (rxg_fd) {
	printf("Loading RX Gain parameters from %s\n",rxg_fname);
	l=0;
	while (fgets(line, sizeof(line), rxg_fd)) {
	  if ((strlen(line)==0) || (*line == '#')) continue; //ignore empty or comment lines
	  else {
	    if (l==0) sscanf(line,"%d %d %d %d",&rxg_max[0],&rxg_max[1],&rxg_max[2],&rxg_max[3]);
	    if (l==1) sscanf(line,"%d %d %d %d",&rxg_med[0],&rxg_med[1],&rxg_med[2],&rxg_med[3]);
	    if (l==2) sscanf(line,"%d %d %d %d",&rxg_byp[0],&rxg_byp[1],&rxg_byp[2],&rxg_byp[3]);
	    l++;
	  }
	}
      }
      else 
	printf("%s not found, running with defaults\n",rxg_fname);
2733
#endif
2734 2735
      break;
      
2736 2737 2738
    case 'G':
      glog_verbosity=atoi(optarg);// value from 0, 0x5, 0x15, 0x35, 0x75
      break;
2739 2740 2741 2742 2743 2744 2745
    case 'x':
      transmission_mode = atoi(optarg);
      if (transmission_mode > 2) {
	printf("Transmission mode > 2 (%d) not supported for the moment\n",transmission_mode);
	exit(-1);
      }
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
2746 2747
    default:
      break;
2748 2749
    }
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
2750 2751
  
  if ((UE_flag == 0) && (conf_config_file_name != NULL)) {
2752
    int i,j;
Raymond Knopp's avatar
 
Raymond Knopp committed
2753 2754 2755 2756 2757 2758 2759 2760 2761
    
    NB_eNB_INST = 1;
    
    /* Read eNB configuration file */
    enb_properties = enb_config_init(conf_config_file_name);
    
    AssertFatal (NB_eNB_INST <= enb_properties->number,
		 "Number of eNB is greater than eNB defined in configuration file %s (%d/%d)!",
		 conf_config_file_name, NB_eNB_INST, enb_properties->number);
2762

Raymond Knopp's avatar
 
Raymond Knopp committed
2763
    /* Update some simulation parameters */
2764
    for (i=0; i < enb_properties->number; i++) {
2765 2766 2767 2768
      AssertFatal (MAX_NUM_CCs == enb_properties->properties[i]->nb_cc,
		   "lte-softmodem compiled with MAX_NUM_CCs=%d, but only %d CCs configured for eNB %d!",
		   MAX_NUM_CCs, enb_properties->properties[i]->nb_cc, i);
      
Raymond Knopp's avatar
 
Raymond Knopp committed
2769 2770 2771 2772 2773 2774
      for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
	frame_parms[CC_id]->frame_type =       enb_properties->properties[i]->frame_type[CC_id];
	frame_parms[CC_id]->tdd_config =       enb_properties->properties[i]->tdd_config[CC_id];
	frame_parms[CC_id]->tdd_config_S =     enb_properties->properties[i]->tdd_config_s[CC_id];
	frame_parms[CC_id]->Ncp =              enb_properties->properties[i]->prefix_type[CC_id];
	
Raymond Knopp's avatar
 
Raymond Knopp committed
2775
	//for (j=0; j < enb_properties->properties[i]->nb_cc; j++ ){
2776 2777 2778 2779 2780
	frame_parms[CC_id]->Nid_cell            =  enb_properties->properties[i]->Nid_cell[CC_id];
	frame_parms[CC_id]->N_RB_DL             =  enb_properties->properties[i]->N_RB_DL[CC_id];
	frame_parms[CC_id]->nb_antennas_tx      =  enb_properties->properties[i]->nb_antennas_tx[CC_id];
	frame_parms[CC_id]->nb_antennas_tx_eNB  =  enb_properties->properties[i]->nb_antennas_tx[CC_id];
	frame_parms[CC_id]->nb_antennas_rx      =  enb_properties->properties[i]->nb_antennas_rx[CC_id];
2781
	//} // j
Raymond Knopp's avatar
 
Raymond Knopp committed
2782 2783
      }

2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803
      
#ifdef OPENAIR2
      
      init_all_otg(0);
      g_otg->seed = 0;
      init_seeds(g_otg->seed);
      for (k=0; k<enb_properties->properties[i]->num_otg_elements; k++){
	j=enb_properties->properties[i]->otg_ue_id[k]; // ue_id
	g_otg->application_idx[i][j] = 1;
	//g_otg->packet_gen_type=SUBSTRACT_STRING;
	g_otg->background[i][j][0] =enb_properties->properties[i]->otg_bg_traffic[k];
	g_otg->application_type[i][j][0] =enb_properties->properties[i]->otg_app_type[k];// BCBR; //MCBR, BCBR
      
	printf("[OTG] configuring traffic type %d for  eNB %d UE %d (Background traffic is %s)\n",
	       g_otg->application_type[i][j][0], i, j,(g_otg->background[i][j][0]==1)?"Enabled":"Disabled");
      }
      init_predef_traffic(enb_properties->properties[i]->num_otg_elements, 1);
  
#endif
      
2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817
      glog_level                     = enb_properties->properties[i]->glog_level;
      glog_verbosity                 = enb_properties->properties[i]->glog_verbosity;
      hw_log_level                   = enb_properties->properties[i]->hw_log_level;
      hw_log_verbosity               = enb_properties->properties[i]->hw_log_verbosity ;
      phy_log_level                  = enb_properties->properties[i]->phy_log_level;
      phy_log_verbosity              = enb_properties->properties[i]->phy_log_verbosity;
      mac_log_level                  = enb_properties->properties[i]->mac_log_level;
      mac_log_verbosity              = enb_properties->properties[i]->mac_log_verbosity;
      rlc_log_level                  = enb_properties->properties[i]->rlc_log_level;
      rlc_log_verbosity              = enb_properties->properties[i]->rlc_log_verbosity;
      pdcp_log_level                 = enb_properties->properties[i]->pdcp_log_level;
      pdcp_log_verbosity             = enb_properties->properties[i]->pdcp_log_verbosity;
      rrc_log_level                  = enb_properties->properties[i]->rrc_log_level;
      rrc_log_verbosity              = enb_properties->properties[i]->rrc_log_verbosity;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
2818 2819 2820 2821 2822 2823
# if defined(ENABLE_USE_MME)
      gtpu_log_level                 = enb_properties->properties[i]->gtpu_log_level;
      gtpu_log_verbosity             = enb_properties->properties[i]->gtpu_log_verbosity;
      udp_log_level                  = enb_properties->properties[i]->udp_log_level;
      udp_log_verbosity              = enb_properties->properties[i]->udp_log_verbosity;
#endif
2824 2825 2826 2827
#if defined (ENABLE_SECURITY)
      osa_log_level                  = enb_properties->properties[i]->osa_log_level;
      osa_log_verbosity              = enb_properties->properties[i]->osa_log_verbosity;
#endif 
2828
    
Raymond Knopp's avatar
 
Raymond Knopp committed
2829
      // adjust the log
2830 2831
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
	for (k = 0 ; k < 4; k++) {
2832
	  downlink_frequency[CC_id][k]      =       enb_properties->properties[i]->downlink_frequency[CC_id];
2833
	  uplink_frequency_offset[CC_id][k] =  enb_properties->properties[i]->uplink_frequency_offset[CC_id];
2834 2835
	  rx_gain[CC_id][k]                 =  (double)enb_properties->properties[i]->rx_gain[CC_id];
	  tx_gain[CC_id][k]                 =  (double)enb_properties->properties[i]->tx_gain[CC_id];
2836
	}
2837
	printf("Downlink frequency/ uplink offset of CC_id %d set to %ju/%d\n", CC_id,
2838 2839
	       enb_properties->properties[i]->downlink_frequency[CC_id],
	       enb_properties->properties[i]->uplink_frequency_offset[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
2840
      } // CC_id
2841
    }// i
Raymond Knopp's avatar
 
Raymond Knopp committed
2842 2843
  }
}
2844

Raymond Knopp's avatar
 
Raymond Knopp committed
2845
int main(int argc, char **argv) {
2846
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2847
  // RT_TASK *task;
Raymond Knopp's avatar
 
Raymond Knopp committed
2848
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
2849
  int *eNB_thread_status_p;
Raymond Knopp's avatar
 
Raymond Knopp committed
2850
  //  int *eNB_thread_status_rx[10],*eNB_thread_status_tx[10];
2851
#endif
2852 2853
  int i,j,aa,card;
#if defined (XFORMS) || defined (EMOS) || (! defined (RTAI)) || defined (SPECTRA)
Raymond Knopp's avatar
 
Raymond Knopp committed
2854
  void *status;
2855
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2856
  
Raymond Knopp's avatar
 
Raymond Knopp committed
2857
  int CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
2858
  uint16_t Nid_cell = 0;
2859
  uint8_t  cooperation_flag=0,  abstraction_flag=0;
2860
#ifndef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
2861
  uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
2862 2863 2864
#endif

#ifdef ENABLE_TCXO
Raymond Knopp's avatar
 
Raymond Knopp committed
2865
  unsigned int tcxo = 114;
2866 2867
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2868 2869 2870 2871
#ifdef ETHERNET
  char *rrh_ip = "127.0.0.1";
  int rrh_port = 22222;
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2872
  //  int amp;
Raymond Knopp's avatar
 
Raymond Knopp committed
2873 2874
  // uint8_t prach_fmt;
  // int N_ZC;
2875

Raymond Knopp's avatar
 
Raymond Knopp committed
2876
  //  int ret, ant;
Raymond Knopp's avatar
 
Raymond Knopp committed
2877
  int ant_offset=0;
2878
#if defined (XFORMS) || defined (SPECTRA)
2879 2880
  int ret;
#endif
2881
#if defined (EMOS) || (! defined (RTAI))
Raymond Knopp's avatar
 
Raymond Knopp committed
2882
  int error_code;
2883
#endif
2884 2885

  memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS);
2886

Raymond Knopp's avatar
 
Raymond Knopp committed
2887
  set_latency_target();
2888

Raymond Knopp's avatar
 
Raymond Knopp committed
2889
  mode = normal_txrx;
2890

Raymond Knopp's avatar
 
Raymond Knopp committed
2891 2892 2893
  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 */
Raymond Knopp's avatar
 
Raymond Knopp committed
2894
    frame_parms[CC_id]->frame_type         = FDD; /* TDD */
Raymond Knopp's avatar
 
Raymond Knopp committed
2895 2896 2897 2898
    frame_parms[CC_id]->tdd_config          = 3;
    frame_parms[CC_id]->tdd_config_S        = 0;
    frame_parms[CC_id]->N_RB_DL             = 25;
    frame_parms[CC_id]->N_RB_UL             = 25;
Raymond Knopp's avatar
 
Raymond Knopp committed
2899
    frame_parms[CC_id]->Ncp                 = NORMAL;
Raymond Knopp's avatar
 
Raymond Knopp committed
2900 2901
    frame_parms[CC_id]->Ncp_UL              = NORMAL;
    frame_parms[CC_id]->Nid_cell            = Nid_cell;
Raymond Knopp's avatar
 
Raymond Knopp committed
2902
    frame_parms[CC_id]->num_MBSFN_config    = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2903
  }
2904

2905 2906 2907
  // initialize the log (see log.h for details)
  logInit();
  set_glog(glog_level, glog_verbosity);
winckel's avatar
winckel committed
2908

Raymond Knopp's avatar
 
Raymond Knopp committed
2909 2910
  //randominit (0);
  set_taus_seed (0);
winckel's avatar
winckel committed
2911

2912 2913
  get_options (argc, argv); //Command-line options
  
Raymond Knopp's avatar
 
Raymond Knopp committed
2914 2915 2916 2917

  if (UE_flag==1)
    {
      printf("configuring for UE\n");
2918

2919
      set_comp_log(HW,      LOG_DEBUG,  LOG_HIGH, 1);
2920
#ifdef OPENAIR2
2921
      set_comp_log(PHY,     LOG_DEBUG,   LOG_HIGH, 1);
2922
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
2923
      set_comp_log(PHY,     LOG_INFO,   LOG_HIGH, 1);
2924
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2925 2926 2927 2928 2929
      set_comp_log(MAC,     LOG_INFO,   LOG_HIGH, 1);
      set_comp_log(RLC,     LOG_INFO,   LOG_HIGH, 1);
      set_comp_log(PDCP,    LOG_INFO,   LOG_HIGH, 1);
      set_comp_log(OTG,     LOG_INFO,   LOG_HIGH, 1);
      set_comp_log(RRC,     LOG_INFO,   LOG_HIGH, 1);
2930
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
2931
      set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
2932
# if defined(ENABLE_USE_MME)
Raymond Knopp's avatar
 
Raymond Knopp committed
2933
      set_comp_log(NAS,     LOG_INFO,   LOG_HIGH, 1);
2934 2935
# endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2936 2937 2938 2939
    }
  else
    {
      printf("configuring for eNB\n");
2940

2941
      set_comp_log(HW,      hw_log_level, hw_log_verbosity, 1);
2942
#ifdef OPENAIR2
2943
      set_comp_log(PHY,     phy_log_level,   phy_log_verbosity, 1);
2944
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
2945
      set_comp_log(PHY,     LOG_INFO,   LOG_HIGH, 1);
2946
#endif
2947 2948 2949 2950
      set_comp_log(MAC,     mac_log_level,  mac_log_verbosity, 1);
      set_comp_log(RLC,     rlc_log_level,   rlc_log_verbosity, 1);
      set_comp_log(PDCP,    pdcp_log_level,  pdcp_log_verbosity, 1);
      set_comp_log(RRC,     rrc_log_level,  rrc_log_verbosity, 1);
2951
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
2952
      set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
2953
# if defined(ENABLE_USE_MME)
Lionel Gauthier's avatar
 
Lionel Gauthier committed
2954 2955
      set_comp_log(UDP_,    udp_log_level,   udp_log_verbosity, 1);
      set_comp_log(GTPU,    gtpu_log_level,   gtpu_log_verbosity, 1);
Raymond Knopp's avatar
 
Raymond Knopp committed
2956 2957
      set_comp_log(S1AP,    LOG_DEBUG,   LOG_HIGH, 1);
      set_comp_log(SCTP,    LOG_INFO,   LOG_HIGH, 1);
2958
# endif
2959
#if defined(ENABLE_SECURITY)
2960
      set_comp_log(OSA,    osa_log_level,   osa_log_verbosity, 1);
2961
#endif
2962
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2963
      set_comp_log(ENB_APP, LOG_INFO, LOG_HIGH, 1);
2964
      set_comp_log(OTG,     LOG_INFO,   LOG_HIGH, 1);
Raymond Knopp's avatar
 
Raymond Knopp committed
2965 2966 2967
      if (online_log_messages == 1) { 
	set_component_filelog(RRC);
	set_component_filelog(PDCP);
Raymond Knopp's avatar
 
Raymond Knopp committed
2968 2969
      }
    }
2970

Raymond Knopp's avatar
 
Raymond Knopp committed
2971 2972 2973 2974 2975 2976
  if (ouput_vcd) {
    if (UE_flag==1)
      vcd_signal_dumper_init("/tmp/openair_dump_UE.vcd");
    else
      vcd_signal_dumper_init("/tmp/openair_dump_eNB.vcd");
  }
2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990
  
  if (opp_enabled ==1)
    reset_opp_meas();

  if (opt_type != OPT_NONE) {
    radio_type_t radio_type;
    if (frame_parms[0]->frame_type == FDD)
      radio_type = RADIO_TYPE_FDD;
    else 
      radio_type = RADIO_TYPE_TDD;
    if (init_opt(NULL, NULL, NULL, radio_type) == -1)
      LOG_E(OPT,"failed to run OPT \n");
  }
  
2991
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
2992 2993 2994 2995 2996 2997
  if (UE_flag == 1) {
    log_set_instance_type (LOG_INSTANCE_UE);
  }
  else {
    log_set_instance_type (LOG_INSTANCE_ENB);
  }
2998

Raymond Knopp's avatar
 
Raymond Knopp committed
2999
  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
3000 3001
#endif

3002
#ifdef NAS_NETLINK
Raymond Knopp's avatar
 
Raymond Knopp committed
3003
  netlink_init();
3004 3005
#endif

3006
#if !defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
3007 3008 3009
  // to make a graceful exit when ctrl-c is pressed
  signal(SIGSEGV, signal_handler);
  signal(SIGINT, signal_handler);
3010
#endif
3011 3012

#ifndef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3013 3014 3015 3016
  check_clock();
#endif

  // init the parameters
Raymond Knopp's avatar
 
Raymond Knopp committed
3017 3018 3019 3020
  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    frame_parms[CC_id]->nushift            = 0;
    if (UE_flag==0)
      {
3021

Raymond Knopp's avatar
 
Raymond Knopp committed
3022
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3023 3024 3025 3026
    else
      { //UE_flag==1
	frame_parms[CC_id]->nb_antennas_tx     = 1;
	frame_parms[CC_id]->nb_antennas_rx     = 1;
3027
	frame_parms[CC_id]->nb_antennas_tx_eNB = (transmission_mode == 1) ? 1 : 2; //initial value overwritten by initial sync later
Raymond Knopp's avatar
 
Raymond Knopp committed
3028 3029 3030 3031 3032 3033 3034 3035 3036
      }
    frame_parms[CC_id]->mode1_flag         = (transmission_mode == 1) ? 1 : 0;
    frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth;
    frame_parms[CC_id]->phich_config_common.phich_duration = normal;
    // UL RS Config
    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 0;//n_DMRS1 set to 0
    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 0;
    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
3037 3038
    init_ul_hopping(frame_parms[CC_id]);
    init_frame_parms(frame_parms[CC_id],1);
3039
    phy_init_top(frame_parms[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051
  }

  phy_init_lte_top(frame_parms[0]);

  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    //init prach for openair1 test
    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;
    // prach_fmt = get_prach_fmt(frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, frame_parms->frame_type);
Raymond Knopp's avatar
 
Raymond Knopp committed
3052
    // N_ZC = (prach_fmt <4)?839:139;
Raymond Knopp's avatar
 
Raymond Knopp committed
3053
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3054 3055

  if (UE_flag==1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3056 3057 3058
    NB_UE_INST=1;
    NB_INST=1;

Raymond Knopp's avatar
 
Raymond Knopp committed
3059 3060 3061
    PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**));
    PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs);
    for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
3062
      PHY_vars_UE_g[0][CC_id] = init_lte_UE(frame_parms[CC_id], UE_id,abstraction_flag,transmission_mode);
Raymond Knopp's avatar
 
Raymond Knopp committed
3063
      printf("PHY_vars_UE_g[0][%d] = %p\n",CC_id,PHY_vars_UE_g[0][CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
3064 3065
#ifndef OPENAIR2
      for (i=0;i<NUMBER_OF_eNB_MAX;i++) {
3066 3067 3068
	PHY_vars_UE_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK;
	PHY_vars_UE_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index  = beta_RI;
	PHY_vars_UE_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI;
Raymond Knopp's avatar
 
Raymond Knopp committed
3069
	
3070 3071 3072
	PHY_vars_UE_g[0][CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = UE_id;
	PHY_vars_UE_g[0][CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(UE_id%3);
	PHY_vars_UE_g[0][CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4;
Raymond Knopp's avatar
 
Raymond Knopp committed
3073
      }
3074
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3075
      
3076 3077 3078
      compute_prach_seq(&PHY_vars_UE_g[0][CC_id]->lte_frame_parms.prach_config_common,
			PHY_vars_UE_g[0][CC_id]->lte_frame_parms.frame_type,
			PHY_vars_UE_g[0][CC_id]->X_u);
Raymond Knopp's avatar
 
Raymond Knopp committed
3079
      
3080
      PHY_vars_UE_g[0][CC_id]->lte_ue_pdcch_vars[0]->crnti = 0x1234;
3081
#ifndef OPENAIR2
3082
      PHY_vars_UE_g[0][CC_id]->lte_ue_pdcch_vars[0]->crnti = 0x1235;
3083
#endif
3084
    
3085
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3086 3087 3088 3089 3090
      for (i=0;i<4;i++) {
	PHY_vars_UE_g[0][CC_id]->rx_gain_max[i] = rxg_max[i];
	PHY_vars_UE_g[0][CC_id]->rx_gain_med[i] = rxg_med[i];
	PHY_vars_UE_g[0][CC_id]->rx_gain_byp[i] = rxg_byp[i];
      }
3091

Raymond Knopp's avatar
 
Raymond Knopp committed
3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106
      if ((mode == normal_txrx) || (mode == rx_calib_ue) || (mode == no_L2_connect) || (mode == debug_prach)) {
	for (i=0;i<4;i++)
	  rx_gain_mode[CC_id][i] = max_gain;
	PHY_vars_UE_g[0][CC_id]->rx_total_gain_dB =  PHY_vars_UE_g[0][CC_id]->rx_gain_max[0] + (int)rx_gain[CC_id][0] - 30; //-30 because it was calibrated with a 30dB gain
      }
      else if ((mode == rx_calib_ue_med)) {
	for (i=0;i<4;i++)
	  rx_gain_mode[CC_id][i] =  med_gain;
	PHY_vars_UE_g[0][CC_id]->rx_total_gain_dB =  PHY_vars_UE_g[0][CC_id]->rx_gain_med[0]  + (int)rx_gain[CC_id][0] - 30; //-30 because it was calibrated with a 30dB gain;
      }
      else if ((mode == rx_calib_ue_byp)) {
	for (i=0;i<4;i++)
	  rx_gain_mode[CC_id][i] =  byp_gain;
	PHY_vars_UE_g[0][CC_id]->rx_total_gain_dB =  PHY_vars_UE_g[0][CC_id]->rx_gain_byp[0]  + (int)rx_gain[CC_id][0] - 30; //-30 because it was calibrated with a 30dB gain;
      }
3107
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3108
      PHY_vars_UE_g[0][CC_id]->rx_total_gain_dB =  (int)rx_gain[CC_id][0]; 
3109
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3110
    
Raymond Knopp's avatar
 
Raymond Knopp committed
3111
      PHY_vars_UE_g[0][CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
Raymond Knopp's avatar
 
Raymond Knopp committed
3112
    
3113

3114
   
3115
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127
      //N_TA_offset
      if (PHY_vars_UE_g[UE_id][CC_id]->lte_frame_parms.frame_type == TDD) {
	if (PHY_vars_UE_g[UE_id][CC_id]->lte_frame_parms.N_RB_DL == 100)
	  PHY_vars_UE_g[UE_id][CC_id]->N_TA_offset = 624;
	else if (PHY_vars_UE_g[UE_id][CC_id]->lte_frame_parms.N_RB_DL == 50)
	  PHY_vars_UE_g[UE_id][CC_id]->N_TA_offset = 624/2;
	else if (PHY_vars_UE_g[UE_id][CC_id]->lte_frame_parms.N_RB_DL == 25)
	  PHY_vars_UE_g[UE_id][CC_id]->N_TA_offset = 624/4;
      }
      else {
	PHY_vars_UE_g[UE_id][CC_id]->N_TA_offset = 0;
      }
3128
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3129 3130
      //already taken care of in lte-softmodem
      PHY_vars_UE_g[UE_id][CC_id]->N_TA_offset = 0;
3131
#endif 
Raymond Knopp's avatar
 
Raymond Knopp committed
3132
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3133 3134 3135 3136 3137
    openair_daq_vars.manual_timing_advance = 0;
    openair_daq_vars.rx_gain_mode = DAQ_AGC_ON;
    openair_daq_vars.auto_freq_correction = 0;
    openair_daq_vars.use_ia_receiver = 0;
    
3138
  
Raymond Knopp's avatar
 
Raymond Knopp committed
3139 3140 3141 3142 3143
    
    //  printf("tx_max_power = %d -> amp %d\n",tx_max_power,get_tx_amp(tx_max_power,tx_max_power));
  }
  else
    { //this is eNB
Raymond Knopp's avatar
 
Raymond Knopp committed
3144 3145 3146
      PHY_vars_eNB_g = malloc(sizeof(PHY_VARS_eNB**));
      PHY_vars_eNB_g[0] = malloc(sizeof(PHY_VARS_eNB*));
      for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3147
	PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],eNB_id,Nid_cell,cooperation_flag,transmission_mode,abstraction_flag);
3148
	PHY_vars_eNB_g[0][CC_id]->CC_id = CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
3149
       
3150
#ifndef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3151 3152 3153 3154 3155 3156 3157 3158 3159
	for (i=0;i<NUMBER_OF_UE_MAX;i++) {
	  PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK;
	  PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index  = beta_RI;
	  PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI;
	  
	  PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = i;
	  PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(i%3);
	  PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4;
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
3160
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3161 3162 3163 3164
      
	compute_prach_seq(&PHY_vars_eNB_g[0][CC_id]->lte_frame_parms.prach_config_common,
			  PHY_vars_eNB_g[0][CC_id]->lte_frame_parms.frame_type,
			  PHY_vars_eNB_g[0][CC_id]->X_u);
Raymond Knopp's avatar
 
Raymond Knopp committed
3165

3166
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3167

3168
	PHY_vars_eNB_g[0][CC_id]->rx_total_gain_eNB_dB = (int)rx_gain[CC_id][0];
Raymond Knopp's avatar
 
Raymond Knopp committed
3169

3170
#else
3171
	PHY_vars_eNB_g[0][CC_id]->rx_total_gain_eNB_dB =  rxg_max[0] + (int)rx_gain[CC_id][0] - 30; //was measured at rxgain=30;
Raymond Knopp's avatar
 
Raymond Knopp committed
3172 3173 3174

	printf("Setting RX total gain to %d\n",PHY_vars_eNB_g[0][CC_id]->rx_total_gain_eNB_dB);

3175 3176
	// set eNB to max gain
	for (i=0;i<4;i++)
3177 3178
	  rx_gain_mode[CC_id][i] = max_gain;
#endif
3179

3180
#ifdef EXMIMO
3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197
	//N_TA_offset
	if (PHY_vars_eNB_g[eNB_id][CC_id]->lte_frame_parms.frame_type == TDD) {
	  if (PHY_vars_eNB_g[eNB_id][CC_id]->lte_frame_parms.N_RB_DL == 100)
	    PHY_vars_eNB_g[eNB_id][CC_id]->N_TA_offset = 624;
	  else if (PHY_vars_eNB_g[eNB_id][CC_id]->lte_frame_parms.N_RB_DL == 50)
	    PHY_vars_eNB_g[eNB_id][CC_id]->N_TA_offset = 624/2;
	  else if (PHY_vars_eNB_g[eNB_id][CC_id]->lte_frame_parms.N_RB_DL == 25)
	    PHY_vars_eNB_g[eNB_id][CC_id]->N_TA_offset = 624/4;
	}
	else {
	  PHY_vars_eNB_g[eNB_id][CC_id]->N_TA_offset = 0;
	}
#else
	//already taken care of in lte-softmodem
	PHY_vars_eNB_g[eNB_id][CC_id]->N_TA_offset = 0;
#endif 
	
Raymond Knopp's avatar
 
Raymond Knopp committed
3198
      }
3199 3200


Raymond Knopp's avatar
 
Raymond Knopp committed
3201 3202
      NB_eNB_INST=1;
      NB_INST=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
3203

Raymond Knopp's avatar
 
Raymond Knopp committed
3204
      openair_daq_vars.ue_dl_rb_alloc=0x1fff;
3205
      openair_daq_vars.target_ue_dl_mcs=target_dl_mcs;
Raymond Knopp's avatar
 
Raymond Knopp committed
3206
      openair_daq_vars.ue_ul_nb_rb=6;
3207
      openair_daq_vars.target_ue_ul_mcs=target_ul_mcs;
Raymond Knopp's avatar
 
Raymond Knopp committed
3208 3209

    }
3210

3211

3212

Raymond Knopp's avatar
 
Raymond Knopp committed
3213
  dump_frame_parms(frame_parms[0]);
3214

Raymond Knopp's avatar
 
Raymond Knopp committed
3215
  if(frame_parms[0]->N_RB_DL == 100) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3216
    sample_rate = 30.72e6;
3217
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3218 3219 3220 3221 3222
    samples_per_packets = 2048;
    samples_per_frame = 307200;
    // from usrp_time_offset
    tx_forward_nsamps = 175;
    sf_bounds = sf_bounds_20;
Raymond Knopp's avatar
 
Raymond Knopp committed
3223
    sf_bounds_tx = sf_bounds_20_tx;
Raymond Knopp's avatar
 
Raymond Knopp committed
3224
    max_cnt = 150;
3225
    tx_delay = 8;
Raymond Knopp's avatar
 
Raymond Knopp committed
3226 3227
#endif
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3228
  else if(frame_parms[0]->N_RB_DL == 50){
3229
    sample_rate = 15.36e6;
3230
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3231 3232 3233 3234
    samples_per_packets = 2048;
    samples_per_frame = 153600;
    tx_forward_nsamps = 95;
    sf_bounds = sf_bounds_10;
Raymond Knopp's avatar
 
Raymond Knopp committed
3235
    sf_bounds_tx = sf_bounds_10_tx;
Raymond Knopp's avatar
 
Raymond Knopp committed
3236 3237 3238 3239
    max_cnt = 75;
    tx_delay = 4;
#endif
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3240
  else if (frame_parms[0]->N_RB_DL == 25) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3241
    sample_rate = 7.68e6;
3242
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3243 3244 3245 3246
    samples_per_packets = 1024;
    samples_per_frame = 76800;
    tx_forward_nsamps = 70;
    sf_bounds = sf_bounds_5;
Raymond Knopp's avatar
 
Raymond Knopp committed
3247
    sf_bounds_tx = sf_bounds_5_tx;
Raymond Knopp's avatar
 
Raymond Knopp committed
3248
    max_cnt = 75;
Raymond Knopp's avatar
 
Raymond Knopp committed
3249
    tx_delay = 5;
Raymond Knopp's avatar
 
Raymond Knopp committed
3250 3251 3252
#endif
  }
  
3253

3254
  for (card=0;card<MAX_CARDS;card++) {
3255 3256 3257 3258 3259 3260
#ifndef EXMIMO
    openair0_cfg[card].samples_per_packet = samples_per_packets;
#endif
    printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card,
	   ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_tx),
	   ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_rx)); 
Raymond Knopp's avatar
 
Raymond Knopp committed
3261 3262 3263 3264 3265 3266
    openair0_cfg[card].Mod_id = 0;
#ifdef ETHERNET
    printf("ETHERNET: Configuring ETH for %s:%d\n",rrh_ip,rrh_port);
    openair0_cfg[card].rrh_ip   = &rrh_ip[0];
    openair0_cfg[card].rrh_port = rrh_port;
#endif
3267 3268 3269
    openair0_cfg[card].sample_rate = sample_rate;
    openair0_cfg[card].tx_bw = bw;
    openair0_cfg[card].rx_bw = bw;
3270 3271 3272
    // in the case of the USRP, the following variables need to be initialized before the init
    // since the USRP only supports one CC (for the moment), we initialize all the cards with first CC. 
    // in the case of EXMIMO2, these values are overwirtten in the function setup_eNB/UE_buffer
3273
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3274 3275
    openair0_cfg[card].tx_num_channels=min(2,((UE_flag==0) ? PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_tx));
    openair0_cfg[card].rx_num_channels=min(2,((UE_flag==0) ? PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_rx));
3276
    for (i=0;i<4;i++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3277

3278
      openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
Raymond Knopp's avatar
 
Raymond Knopp committed
3279 3280
      openair0_cfg[card].rx_gain[i] = ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->rx_total_gain_eNB_dB : 
				                      PHY_vars_UE_g[0][0]->rx_total_gain_dB) - 73;  // calibrated for USRP B210 @ 2.6 GHz
3281 3282
      openair0_cfg[card].tx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] : downlink_frequency[0][i]+uplink_frequency_offset[0][i];
      openair0_cfg[card].rx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] + uplink_frequency_offset[0][i] : downlink_frequency[0][i];
Raymond Knopp's avatar
 
Raymond Knopp committed
3283 3284 3285 3286 3287 3288
      printf("Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n",
	     openair0_cfg[card].tx_gain[i],
	     openair0_cfg[card].rx_gain[i],
	     openair0_cfg[card].tx_freq[i],
	     openair0_cfg[card].rx_freq[i]);
      
Raymond Knopp's avatar
 
Raymond Knopp committed
3289
    }
3290
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3291
  }
3292 3293

  if (openair0_device_init(&openair0, &openair0_cfg[0]) <0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3294 3295 3296
    printf("Exiting, cannot initialize device\n");
    exit(-1);
  }
3297 3298 3299

  mac_xface = malloc(sizeof(MAC_xface));

3300
#ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3301
  int eMBMS_active=0;
3302

3303
  l2_init(frame_parms[0],eMBMS_active,
Raymond Knopp's avatar
 
Raymond Knopp committed
3304 3305 3306 3307 3308 3309
	  0,// cba_group_active
	  0); // HO flag
  if (UE_flag == 1)
    mac_xface->dl_phy_sync_success (0, 0, 0, 1);
  else
    mac_xface->mrbch_phy_sync_failure (0, 0, 0);
3310 3311
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3312
  mac_xface->macphy_exit = &exit_fun;
3313

winckel's avatar
winckel committed
3314
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
3315
  if (create_tasks(UE_flag ? 0 : 1, UE_flag ? 1 : 0) < 0) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
3316
    printf("cannot create ITTI tasks\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
3317 3318 3319
    exit(-1); // need a softer mode
  }
  printf("ITTI tasks created\n");
winckel's avatar
winckel committed
3320 3321
#endif

3322
  /* #ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333
  //if (otg_enabled) {
  init_all_otg(0);
  g_otg->seed = 0;
  init_seeds(g_otg->seed);
  g_otg->num_nodes = 2;
  for (i=0; i<g_otg->num_nodes; i++){
    for (j=0; j<g_otg->num_nodes; j++){
      g_otg->application_idx[i][j] = 1;
      //g_otg->packet_gen_type=SUBSTRACT_STRING;
      g_otg->aggregation_level[i][j][0]=1;
      g_otg->application_type[i][j][0] = BCBR; //MCBR, BCBR
3334
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3335 3336 3337
  }
  init_predef_traffic(UE_flag ? 1 : 0, UE_flag ? 0 : 1);
  //  }
3338
  #endif */
3339
#ifdef EXMIMO
3340
  number_of_cards = openair0_num_detected_cards;
3341 3342 3343
#else
  number_of_cards = 1;
#endif 
3344

Raymond Knopp's avatar
 
Raymond Knopp committed
3345
  openair_daq_vars.timing_advance = 0;
3346

Florian Kaltenberger's avatar
Florian Kaltenberger committed
3347 3348
  for(CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    rf_map[CC_id].card=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3349
    rf_map[CC_id].chain=CC_id;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
3350
  }
3351

Raymond Knopp's avatar
 
Raymond Knopp committed
3352 3353
  // connect the TX/RX buffers
  if (UE_flag==1) {
3354 3355 3356 3357
    if (setup_ue_buffers(PHY_vars_UE_g[0],&openair0_cfg[0],rf_map)!=0) {
      printf("Error setting up eNB buffer\n");
      exit(-1);
    }
3358 3359
    printf("Setting UE buffer to all-RX\n");
    // Set LSBs for antenna switch (ExpressMIMO)
Raymond Knopp's avatar
 
Raymond Knopp committed
3360
    for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3361
      for (i=0; i<frame_parms[CC_id]->samples_per_tti*10; i++)
3362
	for (aa=0; aa<frame_parms[CC_id]->nb_antennas_tx; aa++)
3363
	  PHY_vars_UE_g[0][CC_id]->lte_ue_common_vars.txdata[aa][i] = 0x00010001;
Raymond Knopp's avatar
 
Raymond Knopp committed
3364
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3365 3366 3367
    //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX;
  }
  else {
3368 3369 3370 3371 3372 3373
    if (setup_eNB_buffers(PHY_vars_eNB_g[0],&openair0_cfg[0],rf_map)!=0) {
      printf("Error setting up eNB buffer\n");
      exit(-1);
    }
    printf("Setting eNB buffer to all-RX\n");
    // Set LSBs for antenna switch (ExpressMIMO)
Raymond Knopp's avatar
 
Raymond Knopp committed
3374
    for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3375 3376
      for (i=0; i<frame_parms[CC_id]->samples_per_tti*10; i++)
	for (aa=0; aa<frame_parms[CC_id]->nb_antennas_tx; aa++)
3377
	  PHY_vars_eNB_g[0][CC_id]->lte_eNB_common_vars.txdata[0][aa][i] = 0x00010001;
Raymond Knopp's avatar
 
Raymond Knopp committed
3378
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3379
  }
3380
#ifdef EXMIMO
3381
  openair0_config(&openair0_cfg[0],UE_flag);
Raymond Knopp's avatar
 
Raymond Knopp committed
3382 3383
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3384
  /*  
Raymond Knopp's avatar
 
Raymond Knopp committed
3385 3386
      for (ant=0;ant<4;ant++)
      p_exmimo_config->rf.do_autocal[ant] = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3387
  */
3388 3389

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3390 3391 3392 3393 3394 3395 3396 3397 3398
  error_code = rtf_create(CHANSOUNDER_FIFO_MINOR,CHANSOUNDER_FIFO_SIZE);
  if (error_code==0)
    printf("[OPENAIR][SCHED][INIT] Created EMOS FIFO %d\n",CHANSOUNDER_FIFO_MINOR);
  else if (error_code==ENODEV)
    printf("[OPENAIR][SCHED][INIT] Problem: EMOS FIFO %d is greater than or equal to RTF_NO\n",CHANSOUNDER_FIFO_MINOR);
  else if (error_code==ENOMEM)
    printf("[OPENAIR][SCHED][INIT] Problem: cannot allocate memory for EMOS FIFO %d\n",CHANSOUNDER_FIFO_MINOR);
  else 
    printf("[OPENAIR][SCHED][INIT] Problem creating EMOS FIFO %d, error_code %d\n",CHANSOUNDER_FIFO_MINOR,error_code);
3399 3400
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3401
  mlockall(MCL_CURRENT | MCL_FUTURE);
3402 3403

#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424
  // make main thread LXRT soft realtime
  /* task = */ rt_task_init_schmod(nam2num("MYTASK"), 9, 0, 0, SCHED_FIFO, 0xF);

  // start realtime timer and scheduler
  //rt_set_oneshot_mode();
  rt_set_periodic_mode();
  start_rt_timer(0);

  //now = rt_get_time() + 10*PERIOD;
  //rt_task_make_periodic(task, now, PERIOD);

  printf("Init mutex\n");
  //mutex = rt_get_adr(nam2num("MUTEX"));
  mutex = rt_sem_init(nam2num("MUTEX"), 1);
  if (mutex==0)
    {
      printf("Error init mutex\n");
      exit(-1);
    }
  else
    printf("mutex=%p\n",mutex);
3425

Raymond Knopp's avatar
 
Raymond Knopp committed
3426 3427 3428
  sync_sem = rt_typed_sem_init(nam2num("syncsem"), 0, BIN_SEM|FIFO_Q);
  if(sync_sem == 0)
    printf("error init sync semphore\n");
3429

Raymond Knopp's avatar
 
Raymond Knopp committed
3430 3431 3432
#else
  pthread_cond_init(&sync_cond,NULL);
  pthread_mutex_init(&sync_mutex, NULL);
3433 3434
#endif

3435
#if defined(ENABLE_ITTI)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
3436 3437 3438 3439 3440
  // Wait for eNB application initialization to be complete (eNB registration to MME)
  if (UE_flag==0) {
    printf("Waiting for eNB application to be ready\n");
    wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
  }
3441
#endif
3442

Raymond Knopp's avatar
 
Raymond Knopp committed
3443 3444

  // this starts the DMA transfers
3445
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3446
  if (UE_flag!=1)
3447 3448
    for (card=0;card<openair0_num_detected_cards;card++)
      openair0_start_rt_acquisition(card);
Raymond Knopp's avatar
 
Raymond Knopp committed
3449
#endif
3450 3451

#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
3452 3453
  if (do_forms==1) {
    fl_initialize (&argc, argv, NULL, 0, 0);
3454 3455

    if (UE_flag==0) {
3456
      form_stats_l2 = create_form_stats_form();
3457 3458 3459
      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");
Raymond Knopp's avatar
 
Raymond Knopp committed
3460 3461 3462 3463 3464 3465 3466
      for(UE_id=0;UE_id<scope_enb_num_ue;UE_id++) {
	form_enb[UE_id] = create_lte_phy_scope_enb();
	sprintf (title, "UE%d LTE UL SCOPE eNB",UE_id+1);
	fl_show_form (form_enb[UE_id]->lte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
	if (otg_enabled) {
	  fl_set_button(form_enb[UE_id]->button_0,1);
	  fl_set_object_label(form_enb[UE_id]->button_0,"DL Traffic ON");
Raymond Knopp's avatar
 
Raymond Knopp committed
3467 3468
	}
	else {
Raymond Knopp's avatar
 
Raymond Knopp committed
3469 3470
	  fl_set_button(form_enb[UE_id]->button_0,0);
	  fl_set_object_label(form_enb[UE_id]->button_0,"DL Traffic OFF");
Raymond Knopp's avatar
 
Raymond Knopp committed
3471
	}
3472 3473
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3474
    else {
3475 3476 3477 3478 3479 3480 3481
      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);

Raymond Knopp's avatar
 
Raymond Knopp committed
3482 3483 3484 3485 3486 3487 3488 3489 3490 3491
      if (openair_daq_vars.use_ia_receiver) {
	fl_set_button(form_ue[UE_id]->button_0,1);
	fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON");
      }
      else {
	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
3492
    ret = pthread_create(&forms_thread, NULL, scope_thread, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
3493 3494
    printf("Scope thread created, ret=%d\n",ret);
  }
3495 3496 3497
#endif

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3498 3499
  ret = pthread_create(&thread3, NULL, emos_thread, NULL);
  printf("EMOS thread created, ret=%d\n",ret);
3500 3501
#endif

3502 3503 3504 3505 3506
#ifdef SPECTRA
  ret = pthread_create(&sensing_thread, NULL, sensing, NULL);
  printf("sensing thread created, ret=%d\n",ret);
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3507
  rt_sleep_ns(10*FRAME_PERIOD);
3508 3509

#ifndef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3510 3511
  pthread_attr_init (&attr_dlsch_threads);
  pthread_attr_setstacksize(&attr_dlsch_threads,OPENAIR_THREAD_STACK_SIZE);
3512 3513

#ifndef LOWLATENCY
3514
  sched_param_dlsch.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY;
Raymond Knopp's avatar
 
Raymond Knopp committed
3515 3516
  pthread_attr_setschedparam  (&attr_dlsch_threads, &sched_param_dlsch);
  pthread_attr_setschedpolicy (&attr_dlsch_threads, SCHED_FIFO);
3517
#endif 
Raymond Knopp's avatar
 
Raymond Knopp committed
3518 3519
  pthread_attr_init (&attr_UE_init_synch);
  pthread_attr_setstacksize(&attr_UE_init_synch,OPENAIR_THREAD_STACK_SIZE);
3520
  sched_param_UE_init_synch.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY;
Raymond Knopp's avatar
 
Raymond Knopp committed
3521 3522 3523
  pthread_attr_setschedparam  (&attr_UE_init_synch, &sched_param_UE_init_synch);
  pthread_attr_setschedpolicy (&attr_UE_init_synch, SCHED_FIFO);

3524 3525
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3526 3527
  // start the main thread
  if (UE_flag == 1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3528
    init_UE_threads();
3529
    sleep(1);
3530
#ifdef RTAI
3531
    main_ue_thread = rt_thread_create(UE_thread, NULL, 100000000);
3532
#else
3533
    error_code = pthread_create(&main_ue_thread, &attr_dlsch_threads, UE_thread, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
3534 3535 3536 3537 3538 3539 3540
    if (error_code!= 0) {
      LOG_D(HW,"[lte-softmodem.c] Could not allocate UE_thread, error %d\n",error_code);
      return(error_code);
    }
    else {
      LOG_D(HW,"[lte-softmodem.c] Allocate UE_thread successful\n");
    }
3541 3542
#endif
#ifdef DLSCH_THREAD
Raymond Knopp's avatar
 
Raymond Knopp committed
3543 3544 3545
    init_rx_pdsch_thread();
    rt_sleep_ns(FRAME_PERIOD/10);
    init_dlsch_threads();
3546
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3547 3548 3549
    printf("UE threads created\n");
  }
  else {
3550

Raymond Knopp's avatar
 
Raymond Knopp committed
3551 3552
    if (multi_thread>0) {
      init_eNB_proc();
3553
      sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3554 3555
      LOG_D(HW,"[lte-softmodem.c] eNB threads created\n");
    }
3556
    printf("Creating main eNB_thread \n");
Raymond Knopp's avatar
 
Raymond Knopp committed
3557
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3558
    main_eNB_thread = rt_thread_create(eNB_thread, NULL, OPENAIR_THREAD_STACK_SIZE);
Raymond Knopp's avatar
 
Raymond Knopp committed
3559
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3560
    error_code = pthread_create(&main_eNB_thread, &attr_dlsch_threads, eNB_thread, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
3561 3562 3563 3564 3565 3566
    if (error_code!= 0) {
      LOG_D(HW,"[lte-softmodem.c] Could not allocate eNB_thread, error %d\n",error_code);
      return(error_code);
    }
    else {
      LOG_D(HW,"[lte-softmodem.c] Allocate eNB_thread successful\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
3567
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3568 3569
#endif
  }
3570

Raymond Knopp's avatar
 
Raymond Knopp committed
3571
  // Sleep to allow all threads to setup
Raymond Knopp's avatar
 
Raymond Knopp committed
3572
  sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3573

3574
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3575
#ifndef USRP_DEBUG
Raymond Knopp's avatar
 
Raymond Knopp committed
3576
  openair0.trx_start_func(&openair0);
Raymond Knopp's avatar
 
Raymond Knopp committed
3577
  //  printf("returning from usrp start streaming: %llu\n",get_usrp_time(&openair0));
Raymond Knopp's avatar
 
Raymond Knopp committed
3578
#endif
3579 3580
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3581 3582 3583
#ifdef RTAI
  rt_sem_signal(sync_sem);
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3584 3585
  pthread_mutex_lock(&sync_mutex);
  printf("Sending sync ...\n");
3586
  sync_var=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3587 3588
  pthread_cond_broadcast(&sync_cond);
  pthread_mutex_unlock(&sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
3589
#endif
3590

Raymond Knopp's avatar
 
Raymond Knopp committed
3591 3592 3593
  // wait for end of program
  printf("TYPE <CTRL-C> TO TERMINATE\n");
  //getchar();
3594 3595

#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
3596 3597
  printf("Entering ITTI signals handler\n");
  itti_wait_tasks_end();
3598
  oai_exit=1;
3599
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3600 3601
  while (oai_exit==0)
    rt_sleep_ns(FRAME_PERIOD);
3602
#endif
3603

Raymond Knopp's avatar
 
Raymond Knopp committed
3604
  // stop threads
3605
#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
3606 3607 3608
  printf("waiting for XFORMS thread\n");
  if (do_forms==1)
    {
Raymond Knopp's avatar
 
Raymond Knopp committed
3609
      pthread_join(forms_thread,&status);
Raymond Knopp's avatar
 
Raymond Knopp committed
3610 3611 3612 3613 3614 3615
      fl_hide_form(form_stats->stats_form);
      fl_free_form(form_stats->stats_form);
      if (UE_flag==1) {
	fl_hide_form(form_ue[UE_id]->lte_phy_scope_ue);
	fl_free_form(form_ue[UE_id]->lte_phy_scope_ue);
      } else {
3616 3617
	fl_hide_form(form_stats_l2->stats_form);
	fl_free_form(form_stats_l2->stats_form);
Raymond Knopp's avatar
 
Raymond Knopp committed
3618 3619 3620 3621
	for(UE_id=0;UE_id<scope_enb_num_ue;UE_id++) {
	  fl_hide_form(form_enb[UE_id]->lte_phy_scope_enb);
	  fl_free_form(form_enb[UE_id]->lte_phy_scope_enb);
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
3622
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3623
    }
3624 3625
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3626 3627 3628
  printf("stopping MODEM threads\n");
  // cleanup
  if (UE_flag == 1) {
3629
#ifdef EXMIMO
3630
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3631
    rt_thread_join(main_ue_thread); 
3632
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3633
    pthread_join(main_ue_thread,&status); 
3634 3635
#endif
#ifdef DLSCH_THREAD
Raymond Knopp's avatar
 
Raymond Knopp committed
3636 3637
    cleanup_dlsch_threads();
    cleanup_rx_pdsch_thread();
3638
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3639 3640 3641
#endif
  }
  else {
Raymond Knopp's avatar
 
Raymond Knopp committed
3642
#ifdef DEBUG_THREADS
Raymond Knopp's avatar
 
Raymond Knopp committed
3643
    printf("Joining eNB_thread ...");
Raymond Knopp's avatar
 
Raymond Knopp committed
3644
#endif
3645 3646 3647
#ifdef RTAI
    rt_thread_join(main_eNB_thread); 
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3648
    pthread_join(main_eNB_thread,(void**)&eNB_thread_status_p); 
Raymond Knopp's avatar
 
Raymond Knopp committed
3649
#ifdef DEBUG_THREADS
Raymond Knopp's avatar
 
Raymond Knopp committed
3650
    printf("status %d\n",*eNB_thread_status_p);
Raymond Knopp's avatar
 
Raymond Knopp committed
3651
#endif
3652
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3653

Raymond Knopp's avatar
 
Raymond Knopp committed
3654 3655 3656
    if (multi_thread>0) {
      printf("Killing eNB processing threads\n");
      kill_eNB_proc();
Raymond Knopp's avatar
 
Raymond Knopp committed
3657

Raymond Knopp's avatar
 
Raymond Knopp committed
3658
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3659
  }
3660

3661
#ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3662
  //cleanup_pdcp_thread();
3663 3664
#endif

3665
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3666
  rt_sem_delete(sync_sem);
Raymond Knopp's avatar
 
Raymond Knopp committed
3667
  stop_rt_timer();
Raymond Knopp's avatar
 
Raymond Knopp committed
3668 3669 3670
#else
  pthread_cond_destroy(&sync_cond);
  pthread_mutex_destroy(&sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
3671
#endif
3672

3673
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3674
  printf("stopping card\n");
3675
  openair0_stop(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
3676 3677
  printf("closing openair0_lib\n");
  openair0_close();
Raymond Knopp's avatar
 
Raymond Knopp committed
3678
#endif
3679 3680

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3681 3682 3683
  printf("waiting for EMOS thread\n");
  pthread_cancel(thread3);
  pthread_join(thread3,&status);
3684 3685 3686
#endif

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3687 3688
  error_code = rtf_destroy(CHANSOUNDER_FIFO_MINOR);
  printf("[OPENAIR][SCHED][CLEANUP] EMOS FIFO closed, error_code %d\n", error_code);
3689 3690
#endif

3691 3692 3693 3694 3695 3696
#ifdef SPECTRA
  printf("waiting for sensing thread\n");
  pthread_cancel(sensing_thread);
  pthread_join(sensing_thread,&status);
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3697 3698
  if (ouput_vcd)
    vcd_signal_dumper_close();
3699

3700 3701 3702
  if (opt_type != OPT_NONE)
    terminate_opt();

Raymond Knopp's avatar
 
Raymond Knopp committed
3703
  logClean();
3704

Raymond Knopp's avatar
 
Raymond Knopp committed
3705 3706
  return 0;
}
3707

3708 3709
int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs])
{
Raymond Knopp's avatar
 
Raymond Knopp committed
3710

3711
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3712 3713 3714
  uint16_t N_TA_offset = 0;
#endif

3715 3716 3717 3718 3719
  int i, CC_id;
  LTE_DL_FRAME_PARMS *frame_parms;
  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    if (phy_vars_ue[CC_id]) {
      frame_parms = &(phy_vars_ue[CC_id]->lte_frame_parms); 
Raymond Knopp's avatar
 
Raymond Knopp committed
3720
    }
3721 3722 3723
    else {
      printf("phy_vars_eNB[%d] not initialized\n", CC_id);
      return(-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3724
    }
3725

Raymond Knopp's avatar
 
Raymond Knopp committed
3726

3727
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3728 3729 3730 3731 3732 3733
    if (frame_parms->frame_type == TDD) {
      if (frame_parms->N_RB_DL == 100)
	N_TA_offset = 624;
      else if (frame_parms->N_RB_DL == 50)
	N_TA_offset = 624/2;
      else if (frame_parms->N_RB_DL == 25)
Raymond Knopp's avatar
 
Raymond Knopp committed
3734
	N_TA_offset = 624/4;
Raymond Knopp's avatar
 
Raymond Knopp committed
3735 3736 3737
    }
#endif
   
3738
#ifdef EXMIMO
3739 3740 3741 3742 3743
    openair0_cfg[CC_id].tx_num_channels = 0;
    openair0_cfg[CC_id].rx_num_channels = 0;

    // replace RX signal buffers with mmaped HW versions
    for (i=0;i<frame_parms->nb_antennas_rx;i++) {
3744
      printf("Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n",CC_id,i,downlink_frequency[CC_id][i],rf_map[CC_id].card,rf_map[CC_id].chain+i);
3745 3746 3747 3748 3749 3750 3751 3752
      free(phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i]);
      phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i] = (int32_t*) openair0_exmimo_pci[rf_map[CC_id].card].adc_head[rf_map[CC_id].chain+i];
      if (openair0_cfg[rf_map[CC_id].card].rx_freq[rf_map[CC_id].chain+i]) {
	printf("Error with rf_map! A channel has already been allocated!\n");
	return(-1);
      }
      else {
	openair0_cfg[rf_map[CC_id].card].rx_freq[rf_map[CC_id].chain+i] = downlink_frequency[CC_id][i];
3753 3754
	openair0_cfg[rf_map[CC_id].card].rx_gain[rf_map[CC_id].chain+i] = rx_gain[CC_id][i];
	openair0_cfg[rf_map[CC_id].card].rxg_mode[rf_map[CC_id].chain+i] = rx_gain_mode[CC_id][i];
3755 3756
	openair0_cfg[rf_map[CC_id].card].rx_num_channels++;
      }
3757

3758
      printf("rxdata[%d] @ %p\n",i,phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i]);
Raymond Knopp's avatar
 
Raymond Knopp committed
3759
    }
3760
    for (i=0;i<frame_parms->nb_antennas_tx;i++) {
3761
      printf("Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n",CC_id,i,downlink_frequency[CC_id][i],rf_map[CC_id].card,rf_map[CC_id].chain+i);
3762 3763 3764 3765 3766 3767 3768 3769
      free(phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i]);
      phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i] = (int32_t*) openair0_exmimo_pci[rf_map[CC_id].card].dac_head[rf_map[CC_id].chain+i];
      if (openair0_cfg[rf_map[CC_id].card].tx_freq[rf_map[CC_id].chain+i]) {
	printf("Error with rf_map! A channel has already been allocated!\n");
	return(-1);
      }
      else {
	openair0_cfg[rf_map[CC_id].card].tx_freq[rf_map[CC_id].chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
3770
	openair0_cfg[rf_map[CC_id].card].tx_gain[rf_map[CC_id].chain+i] = tx_gain[CC_id][i];
3771 3772
	openair0_cfg[rf_map[CC_id].card].tx_num_channels++;
      }
3773

3774
      printf("txdata[%d] @ %p\n",i,phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i]);
3775
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3776
  
Raymond Knopp's avatar
 
Raymond Knopp committed
3777
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3778
    // replace RX signal buffers with mmaped HW versions
3779 3780
    rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*));
    txdata = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));
Raymond Knopp's avatar
 
Raymond Knopp committed
3781 3782 3783
    for (i=0;i<frame_parms->nb_antennas_rx;i++) {
      printf("Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n",CC_id,i,downlink_frequency[CC_id][i],rf_map[CC_id].card,rf_map[CC_id].chain+i);
      free(phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i]);
3784 3785
      rxdata[i] = (int32_t*)malloc16(samples_per_frame*sizeof(int32_t));
      phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i] = rxdata[i]-N_TA_offset; // N_TA offset for TDD
Raymond Knopp's avatar
 
Raymond Knopp committed
3786 3787 3788 3789
    }
    for (i=0;i<frame_parms->nb_antennas_tx;i++) {
      printf("Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n",CC_id,i,downlink_frequency[CC_id][i],rf_map[CC_id].card,rf_map[CC_id].chain+i);
      free(phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i]);
3790 3791 3792
      txdata[i] = (int32_t*)malloc16(samples_per_frame*sizeof(int32_t));
      phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i] = txdata[i];
      memset(txdata[i], 0, samples_per_frame*sizeof(int32_t));
Raymond Knopp's avatar
 
Raymond Knopp committed
3793 3794
    }
    
Raymond Knopp's avatar
 
Raymond Knopp committed
3795
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3796 3797 3798 3799
    
  }
  return(0);

Raymond Knopp's avatar
 
Raymond Knopp committed
3800
}
3801

3802 3803 3804 3805 3806
/* this function maps the phy_vars_eNB tx and rx buffers to the available rf chains. 
   Each rf chain is is addressed by the card number and the chain on the card. The 
   rf_map specifies for each CC, on which rf chain the mapping should start. Multiple 
   antennas are mapped to successive RF chains on the same card. */
int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]) {
3807

3808
  int i, CC_id;
3809
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3810
  uint16_t N_TA_offset = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3811 3812
#else
  int j;
Raymond Knopp's avatar
 
Raymond Knopp committed
3813
#endif
3814
  LTE_DL_FRAME_PARMS *frame_parms;
3815

Raymond Knopp's avatar
 
Raymond Knopp committed
3816

3817 3818
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    if (phy_vars_eNB[CC_id]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3819 3820 3821
      frame_parms = &(phy_vars_eNB[CC_id]->lte_frame_parms);
      printf("setup_eNB_buffers: frame_parms = %p\n",frame_parms);
    } 
3822 3823 3824
    else {
      printf("phy_vars_eNB[%d] not initialized\n", CC_id);
      return(-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3825
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3826

3827
#ifndef EXMIMO
3828 3829
    if (frame_parms->frame_type == TDD) {
      if (frame_parms->N_RB_DL == 100)
Raymond Knopp's avatar
 
Raymond Knopp committed
3830
	N_TA_offset = 624;
3831
      else if (frame_parms->N_RB_DL == 50)
Raymond Knopp's avatar
 
Raymond Knopp committed
3832
	N_TA_offset = 624/2;
3833
      else if (frame_parms->N_RB_DL == 25)
Raymond Knopp's avatar
 
Raymond Knopp committed
3834 3835
	N_TA_offset = 624/4;
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3836
#endif
3837 3838 3839 3840 3841
   

   

  
Raymond Knopp's avatar
 
Raymond Knopp committed
3842
    // replace RX signal buffers with mmaped HW versions
3843
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3844 3845 3846
    openair0_cfg[CC_id].tx_num_channels = 0;
    openair0_cfg[CC_id].rx_num_channels = 0;

3847 3848 3849 3850 3851 3852 3853 3854 3855 3856
    for (i=0;i<frame_parms->nb_antennas_rx;i++) {
      printf("Mapping eNB CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n",CC_id,i,downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i],rf_map[CC_id].card,rf_map[CC_id].chain+i);
      free(phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i]);
      phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i] = (int32_t*) openair0_exmimo_pci[rf_map[CC_id].card].adc_head[rf_map[CC_id].chain+i];
      if (openair0_cfg[rf_map[CC_id].card].rx_freq[rf_map[CC_id].chain+i]) {
	printf("Error with rf_map! A channel has already been allocated!\n");
	return(-1);
      }
      else {
	openair0_cfg[rf_map[CC_id].card].rx_freq[rf_map[CC_id].chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
3857
	openair0_cfg[rf_map[CC_id].card].rx_gain[rf_map[CC_id].chain+i] = rx_gain[CC_id][i];
3858 3859 3860
	openair0_cfg[rf_map[CC_id].card].rx_num_channels++;
      }
      printf("rxdata[%d] @ %p\n",i,phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i]);
Raymond Knopp's avatar
 
Raymond Knopp committed
3861
      for (j=0;j<16;j++) {
3862 3863
	printf("rxbuffer %d: %x\n",j,phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i][j]);
	phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i][j] = 16-j;
3864
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3865
    }
3866 3867 3868 3869 3870 3871 3872 3873 3874 3875
    for (i=0;i<frame_parms->nb_antennas_tx;i++) {
      printf("Mapping eNB CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n",CC_id,i,downlink_frequency[CC_id][i],rf_map[CC_id].card,rf_map[CC_id].chain+i);
      free(phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i]);
      phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i] = (int32_t*) openair0_exmimo_pci[rf_map[CC_id].card].dac_head[rf_map[CC_id].chain+i];
      if (openair0_cfg[rf_map[CC_id].card].tx_freq[rf_map[CC_id].chain+i]) {
	printf("Error with rf_map! A channel has already been allocated!\n");
	return(-1);
      }
      else {
	openair0_cfg[rf_map[CC_id].card].tx_freq[rf_map[CC_id].chain+i] = downlink_frequency[CC_id][i];
3876
	openair0_cfg[rf_map[CC_id].card].tx_gain[rf_map[CC_id].chain+i] = tx_gain[CC_id][i];
3877 3878 3879 3880
	openair0_cfg[rf_map[CC_id].card].tx_num_channels++;
      }
      
      printf("txdata[%d] @ %p\n",i,phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i]);
Raymond Knopp's avatar
 
Raymond Knopp committed
3881
      for (j=0;j<16;j++) {
3882 3883
	printf("txbuffer %d: %x\n",j,phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i][j]);
	phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i][j] = 16-j;
3884
      }
3885
    }
3886
#else // not EXMIMO
3887 3888 3889
    rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*));
    txdata = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));

3890 3891
    for (i=0;i<frame_parms->nb_antennas_rx;i++) {
      free(phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i]);
3892 3893 3894 3895
      rxdata[i] = (int32_t*)malloc16(samples_per_frame*sizeof(int32_t));
      phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i] = rxdata[i]-N_TA_offset; // N_TA offset for TDD
      memset(rxdata[i], 0, samples_per_frame*sizeof(int32_t));
      printf("rxdata[%d] @ %p (%p) (N_TA_OFFSET %d)\n", i, phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i],rxdata[i],N_TA_offset);
Raymond Knopp's avatar
 
Raymond Knopp committed
3896
    }
3897 3898
    for (i=0;i<frame_parms->nb_antennas_tx;i++) {
      free(phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i]);
3899 3900 3901
      txdata[i] = (int32_t*)malloc16(samples_per_frame*sizeof(int32_t));
      phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i] = txdata[i];
      memset(txdata[i], 0, samples_per_frame*sizeof(int32_t));
3902
      printf("txdata[%d] @ %p\n", i, phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i]);
3903

Raymond Knopp's avatar
 
Raymond Knopp committed
3904 3905
    }
#endif
3906
  }
3907
  return(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
3908
}
3909

3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928
void reset_opp_meas(void){
  int sfn;
  reset_meas(&softmodem_stats_mt);
  reset_meas(&softmodem_stats_hw);
  for (sfn=0; sfn < 10; sfn++) {
    reset_meas(&softmodem_stats_tx_sf[sfn]);
    reset_meas(&softmodem_stats_rx_sf[sfn]);
  }
}

void print_opp_meas(void){
  int sfn=0;
  print_meas(&softmodem_stats_mt, "Main ENB Thread", NULL, NULL);
  print_meas(&softmodem_stats_hw, "HW Acquisation", NULL, NULL);
  for (sfn=0; sfn < 10; sfn++) {
    print_meas(&softmodem_stats_tx_sf[sfn],"[eNB][total_phy_proc_tx]",NULL, NULL);
    print_meas(&softmodem_stats_rx_sf[sfn],"[eNB][total_phy_proc_rx]",NULL,NULL);
  }
}