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_1_5[10]    = {8, 15, 23, 30, 38, 45, 53, 60, 68, 75};
int sf_bounds_1_5_tx[10] = {4, 11, 19, 26, 34, 41, 49, 56, 64, 71};

Raymond Knopp's avatar
 
Raymond Knopp committed
297 298 299
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
300
int sf_bounds_10[10] = {8, 15, 23, 30, 38, 45, 53, 60, 68, 75};
Raymond Knopp's avatar
 
Raymond Knopp committed
301 302
int sf_bounds_10_tx[10] = {4, 11, 19, 26, 34, 41, 49, 56, 64, 71};

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

Raymond Knopp's avatar
 
Raymond Knopp committed
306
int *sf_bounds;
Raymond Knopp's avatar
 
Raymond Knopp committed
307 308
int *sf_bounds_tx;

Raymond Knopp's avatar
 
Raymond Knopp committed
309 310 311 312
int max_cnt;
int tx_delay;

#endif
313
/*
Raymond Knopp's avatar
 
Raymond Knopp committed
314 315 316
  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};
317
*/
Raymond Knopp's avatar
 
Raymond Knopp committed
318 319
//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
320 321
//{8254617, 8254617, 8254617, 8254617}; //eNB khalifa
//{8255067,8254810,8257340,8257340}; // eNB PETRONAS
322

Raymond Knopp's avatar
 
Raymond Knopp committed
323 324 325 326 327
//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};
328 329 330

static runmode_t                mode;
static int                      rx_input_level_dBm;
331
static int                      online_log_messages=0;
332
#ifdef XFORMS
333
extern int                      otg_enabled;
334
static char                     do_forms=0;
335
#else
336
int                             otg_enabled;
337
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
338
//int                             number_of_cards =   1;
Raymond Knopp's avatar
 
Raymond Knopp committed
339
#ifndef USRP
340 341
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
342
#endif
343

Raymond Knopp's avatar
 
Raymond Knopp committed
344
static LTE_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
345

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

352 353 354 355
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
356 357
void reset_opp_meas(void);
void print_opp_meas(void);
358
int transmission_mode=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
359

Lionel Gauthier's avatar
 
Lionel Gauthier committed
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379
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
380 381 382 383
#if defined (ENABLE_SECURITY)
int16_t           osa_log_level      = LOG_INFO;
int16_t           osa_log_verbosity  = LOG_MED;
#endif 
384

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

394 395 396 397 398 399 400 401 402 403 404 405
#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 
406
#if !defined(ENABLE_ITTI)
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421
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 {
422
    printf("trying to exit gracefully...\n"); 
423
    oai_exit = 1;
424 425
  }
}
426
#endif
427 428 429

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

  oai_exit = 1;

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

  //rt_sleep_ns(FRAME_PERIOD);

  //exit (-1);
}

Raymond Knopp's avatar
 
Raymond Knopp committed
446 447 448
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
449 450 451 452 453 454 455 456 457
 * 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
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474
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
475
 
476
#ifdef XFORMS
477 478 479 480

void reset_stats(FL_OBJECT *button, long arg) {
  int i,j,k;
  PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[0][0];
481 482 483 484 485 486 487 488 489 490 491 492
  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;
493 494 495
      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;
496
      }
497
    }
498 499 500
    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;
501 502 503
  }
}

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

Raymond Knopp's avatar
 
Raymond Knopp committed
512 513
  sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1; 
  sched_setscheduler(0, SCHED_FIFO,&sched_param);
514

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

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

# 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
550 551
      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
552
		      PHY_vars_eNB_g[eNB_id][0],
Raymond Knopp's avatar
 
Raymond Knopp committed
553 554
		      UE_id);
      }
555 556
              
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
557
    //printf("doing forms\n");
Florian Kaltenberger's avatar
Florian Kaltenberger committed
558 559
    //usleep(100000); // 100 ms
    sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
560
  }
561 562

  printf("%s",stats_buffer);
563
    
564
# ifdef ENABLE_XFORMS_WRITE_STATS
565 566 567 568 569 570 571 572 573 574 575 576 577 578
  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);
    }
  }
579
# endif
580
    
Raymond Knopp's avatar
 
Raymond Knopp committed
581
  pthread_exit((void*)arg);
582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606
}
#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;
607 608 609 610 611 612 613

  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);
614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635
 
  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);
    }
636 637
  else 
    printf("[EMOS] Opened GPS, gps_data=%p\n");
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 680 681 682
  
  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
683
	if (UE_flag==0)
684
	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
685
	else
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 744 745 746
	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

747 748 749 750 751 752 753 754 755 756 757 758 759
#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) {

    
760 761 762
    openair0_cfg[0].rx_freq[2]+= 5e6;
    if (openair0_cfg[0].rx_freq[2] >= 750000000)
      openair0_cfg[0].rx_freq[2] = 727500000;
763 764
    

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

    openair0_reconfig(&openair0_cfg[0]);

769
    usleep(200000);
770 771 772 773 774 775 776 777 778 779
    //sleep(1);
    
  }

  pthread_exit((void*) arg);

}
#endif


780
#if defined(ENABLE_ITTI)
781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798
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
799
#if defined(ENABLE_ITTI)
800
void *l2l1_task(void *arg)
801
{
Raymond Knopp's avatar
 
Raymond Knopp committed
802 803 804 805 806
  MessageDef *message_p = NULL;
  int         result;

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
807

Raymond Knopp's avatar
 
Raymond Knopp committed
808 809
  if (UE_flag == 0) {
    /* Wait for the initialize message */
810
    do {
Raymond Knopp's avatar
 
Raymond Knopp committed
811 812 813 814
      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);
      }
815 816 817
      itti_receive_msg (TASK_L2L1, &message_p);

      switch (ITTI_MSG_ID(message_p)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
818 819 820 821 822 823 824 825 826 827 828 829 830 831
      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;
832
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854
    } 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;
855

Raymond Knopp's avatar
 
Raymond Knopp committed
856 857 858 859 860 861 862 863 864 865 866 867
    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);
868

Raymond Knopp's avatar
 
Raymond Knopp committed
869
  return NULL;
870 871 872
}
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
873

Raymond Knopp's avatar
 
Raymond Knopp committed
874
void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) {
Raymond Knopp's avatar
 
Raymond Knopp committed
875 876 877 878

  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
879
  int slot_sizeF = (phy_vars_eNB->lte_frame_parms.ofdm_symbol_size)*
Raymond Knopp's avatar
 
Raymond Knopp committed
880
    ((phy_vars_eNB->lte_frame_parms.Ncp==1) ? 6 : 7);
Raymond Knopp's avatar
 
Raymond Knopp committed
881 882 883

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

Raymond Knopp's avatar
 
Raymond Knopp committed
886 887
  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
888
    //	  LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot);
Raymond Knopp's avatar
 
Raymond Knopp committed
889

Raymond Knopp's avatar
 
Raymond Knopp committed
890
    
Raymond Knopp's avatar
 
Raymond Knopp committed
891 892 893 894 895 896 897 898 899 900
    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
901 902 903 904 905 906 907 908
	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
909 910 911 912 913 914
      }
      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
915 916 917 918
	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
919
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
920 921

      for (i=0; i<phy_vars_eNB->lte_frame_parms.samples_per_tti; i++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938
	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
939 940 941

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

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

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

  if (task==NULL) {
Raymond Knopp's avatar
 
Raymond Knopp committed
964
    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
965 966 967
    return 0;
  }
  else {
968 969
    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
970
	  proc->subframe,
971
	  task);
Raymond Knopp's avatar
 
Raymond Knopp committed
972
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
973
#else
974 975 976 977 978 979
#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
980
  /* This creates a 1ms reservation every 10ms period*/
981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996
  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
997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008
#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
1009
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1010
    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
1011
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1012 1013
    //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
1014

Raymond Knopp's avatar
 
Raymond Knopp committed
1015 1016
    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
1017
      oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1018 1019
    }
    else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1020
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1021 1022
      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
1023
	//printf("Waiting and unlocking mutex for eNB proc %d (subframe_tx %d)\n",proc->subframe,subframe_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1024
	
Raymond Knopp's avatar
 
Raymond Knopp committed
1025
	pthread_cond_wait(&proc->cond_tx,&proc->mutex_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1026
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1027 1028 1029
      //      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
1030
	oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1031 1032
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1033
    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
1034
    vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB, proc->frame_tx);
1035 1036
    start_meas(&softmodem_stats_tx_sf[proc->subframe]);

Raymond Knopp's avatar
 
Raymond Knopp committed
1037
    if (oai_exit) break;
Raymond Knopp's avatar
 
Raymond Knopp committed
1038

Raymond Knopp's avatar
 
Raymond Knopp committed
1039 1040 1041 1042 1043 1044 1045
    
    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
1046
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1047 1048
    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
1049
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1050
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1051
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1052
    do_OFDM_mod_rt(proc->subframe_tx,PHY_vars_eNB_g[0][proc->CC_id]);  
Raymond Knopp's avatar
 
Raymond Knopp committed
1053
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1054 1055
    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
1056
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1057 1058
    else {
      proc->instance_cnt_tx--;
Raymond Knopp's avatar
 
Raymond Knopp committed
1059
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1060 1061 1062 1063
      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
1064

Raymond Knopp's avatar
 
Raymond Knopp committed
1065
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1066 1067 1068
    proc->frame_tx++;
    if (proc->frame_tx==1024)
      proc->frame_tx=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1069

Raymond Knopp's avatar
 
Raymond Knopp committed
1070
  }    
1071
  stop_meas(&softmodem_stats_tx_sf[proc->subframe]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1072 1073 1074 1075
  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
1076
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1077 1078 1079 1080 1081 1082 1083 1084 1085 1086
#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
1087
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100
#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;
1101
  char task_name[8];
1102 1103 1104 1105 1106
#else
#ifdef LOWLATENCY
  struct sched_attr attr;
  unsigned int flags = 0;
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1107 1108
#endif

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

#ifdef RTAI
1115
  sprintf(task_name,"RXC%1dS%1d",proc->CC_id,proc->subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
1116 1117 1118 1119 1120 1121 1122
  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 {
1123 1124
    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
1125
	  proc->subframe,
1126
	  task); /*,rtai_cpuid()*/
Raymond Knopp's avatar
 
Raymond Knopp committed
1127 1128
  }
#else
1129 1130 1131 1132 1133 1134
#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
1135
  /* This creates a 2ms reservation every 10ms period*/
1136
  attr.sched_policy = SCHED_DEADLINE;
Navid Nikaein's avatar
Navid Nikaein committed
1137 1138 1139
  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
1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151
  
  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
1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165
#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
1166
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1167 1168 1169 1170 1171 1172 1173 1174 1175 1176
    //    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
1177
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1178 1179 1180
      //      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
1181 1182
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1183
    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
1184
    vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, proc->frame_rx);
1185 1186
    start_meas(&softmodem_stats_rx_sf[proc->subframe]);
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1187 1188
    if (oai_exit) break;
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1189 1190 1191
    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
1192
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1193 1194
    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
1195 1196 1197 1198
    }
      
    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
1199 1200
    }
    else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1201
      proc->instance_cnt_rx--;
Raymond Knopp's avatar
 
Raymond Knopp committed
1202
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1203 1204
      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
1205 1206
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1207 1208 1209 1210

    proc->frame_rx++;
    if (proc->frame_rx==1024)
      proc->frame_rx=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1211
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1212
  }
1213
  stop_meas(&softmodem_stats_rx_sf[proc->subframe]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1214
  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
1215
#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227
  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
1228 1229
#endif

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



Raymond Knopp's avatar
 
Raymond Knopp committed
1237

1238
void init_eNB_proc(void) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1239 1240

  int i;
Raymond Knopp's avatar
 
Raymond Knopp committed
1241 1242 1243 1244
  int CC_id;

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

      pthread_attr_init (&attr_eNB_proc_rx[CC_id][i]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1251
      if (pthread_attr_setstacksize(&attr_eNB_proc_rx[CC_id][i],PTHREAD_STACK_MIN) != 0)
1252 1253 1254
	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
1255 1256 1257 1258 1259 1260 1261 1262
      //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);
1263
#endif       
Raymond Knopp's avatar
 
Raymond Knopp committed
1264
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276
      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;
1277
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1278 1279
      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
1280
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1281 1282
      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
1283
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1284 1285 1286
    }
  
  
1287
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1288 1289
    // 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
1290
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1291
    //PHY_vars_eNB_g[0][CC_id]->proc[0].frame_rx = 1023;
Raymond Knopp's avatar
 
Raymond Knopp committed
1292 1293
    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
1294
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1295 1296
    // 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
1297
    //    PHY_vars_eNB_g[0][CC_id]->proc[7].frame_tx = 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1298 1299
    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
1300
    //    PHY_vars_eNB_g[0][CC_id]->proc[0].frame_tx = 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1301
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1302 1303
  }
}
Raymond Knopp's avatar
 
Raymond Knopp committed
1304

1305
void kill_eNB_proc(void) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1306 1307

  int i;
1308
  void *status_tx,*status_rx;
Raymond Knopp's avatar
 
Raymond Knopp committed
1309
  int CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1310

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


Raymond Knopp's avatar
 
Raymond Knopp committed
1346 1347


Raymond Knopp's avatar
 
Raymond Knopp committed
1348 1349
  
/* This is the main eNB thread. */
Raymond Knopp's avatar
 
Raymond Knopp committed
1350 1351
int eNB_thread_status;

Raymond Knopp's avatar
 
Raymond Knopp committed
1352

Raymond Knopp's avatar
 
Raymond Knopp committed
1353

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

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

1374
  RTIME time_in, time_diff;
Raymond Knopp's avatar
 
Raymond Knopp committed
1375

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1391
  hw_subframe = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1392
#endif
1393

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

1401
#ifdef RTAI
1402 1403 1404 1405 1406 1407 1408 1409
   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
1410
   /* This creates a .5 ms  reservation */
1411
   attr.sched_policy = SCHED_DEADLINE;
Navid Nikaein's avatar
Navid Nikaein committed
1412 1413 1414
   attr.sched_runtime  = 1 * 1000000;
   attr.sched_deadline = 1 * 1000000;
   attr.sched_period   = 1 * 1000000;
1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428
   
   /* 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
1429 1430 1431 1432
#endif

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

#ifdef HARD_RT
1440
    rt_make_hard_real_time();
1441 1442
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1443
    printf("eNB_thread: mlockall in ...\n");
1444
    mlockall(MCL_CURRENT | MCL_FUTURE);
Raymond Knopp's avatar
 
Raymond Knopp committed
1445
    printf("eNB_thread: mlockall out ...\n");
1446

1447 1448 1449 1450
    timing_info.time_min = 100000000ULL;
    timing_info.time_max = 0;
    timing_info.time_avg = 0;
    timing_info.n_samples = 0;
1451

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1463
    while (!oai_exit) {
1464
      start_meas(&softmodem_stats_mt);
1465
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1466 1467
      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
1468 1469
      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
1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481
      //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;
      
1482 1483 1484 1485 1486
      //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;
1487
	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);
1488 1489
      } 

Raymond Knopp's avatar
 
Raymond Knopp committed
1490 1491
      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
1492
	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
1493
	slot++;
1494 1495 1496 1497 1498 1499 1500
	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
1501 1502 1503 1504
      }
      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
1505
      vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *DAQ_MBOX);
Raymond Knopp's avatar
 
Raymond Knopp committed
1506 1507 1508 1509 1510 1511 1512 1513 1514 1515
      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
1516
	vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *DAQ_MBOX);
Raymond Knopp's avatar
 
Raymond Knopp committed
1517 1518 1519 1520 1521 1522
	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) {
1523
	  stop_meas(&softmodem_stats_mt);
Raymond Knopp's avatar
 
Raymond Knopp committed
1524 1525 1526 1527 1528
	  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
1529
	  diff = 150-mbox_current+mbox_target;
Raymond Knopp's avatar
 
Raymond Knopp committed
1530
	else if ((mbox_current<15) && (mbox_target>=135))
Raymond Knopp's avatar
 
Raymond Knopp committed
1531
	  diff = -150+mbox_target-mbox_current;
Raymond Knopp's avatar
 
Raymond Knopp committed
1532
	else
Raymond Knopp's avatar
 
Raymond Knopp committed
1533
	  diff = mbox_target - mbox_current;
Raymond Knopp's avatar
 
Raymond Knopp committed
1534
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1535

1536
#else  // EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1537 1538
      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
1539 1540
      while (rx_cnt < sf_bounds[hw_subframe]) {

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1546 1547
	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);
1548

Raymond Knopp's avatar
 
Raymond Knopp committed
1549 1550 1551

	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];
1552
	start_meas(&softmodem_stats_hw);
1553 1554
	//	printf("rxp[0] %p\n",rxp[0]);

Raymond Knopp's avatar
 
Raymond Knopp committed
1555 1556
	rxs = openair0.trx_read_func(&openair0, 
				     &timestamp, 
Raymond Knopp's avatar
 
Raymond Knopp committed
1557 1558 1559
				     rxp, 
				     samples_per_packets,
				     PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_rx);
1560
	stop_meas(&softmodem_stats_hw);
Raymond Knopp's avatar
 
Raymond Knopp committed
1561 1562
	if (rxs != samples_per_packets)
	  oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1563
 
Raymond Knopp's avatar
 
Raymond Knopp committed
1564

Raymond Knopp's avatar
 
Raymond Knopp committed
1565 1566
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,0);

Raymond Knopp's avatar
 
Raymond Knopp committed
1567
	// Transmit TX buffer based on timestamp from RX
Raymond Knopp's avatar
 
Raymond Knopp committed
1568
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1569 1570 1571
	
	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
1572 1573
	openair0.trx_write_func(&openair0, 
				(timestamp+samples_per_packets*tx_delay-tx_forward_nsamps), 
Raymond Knopp's avatar
 
Raymond Knopp committed
1574
				txp,
Raymond Knopp's avatar
 
Raymond Knopp committed
1575
				samples_per_packets, 
Raymond Knopp's avatar
 
Raymond Knopp committed
1576
				PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_tx,
Raymond Knopp's avatar
 
Raymond Knopp committed
1577
				1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1578

1579
	stop_meas(&softmodem_stats_mt);
Raymond Knopp's avatar
 
Raymond Knopp committed
1580
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1581 1582 1583 1584 1585 1586 1587 1588 1589
#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
1590
	      //	      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
1591 1592 1593 1594 1595 1596 1597 1598
	      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
1599
		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
1600 1601 1602 1603 1604
		oai_exit=1;
	      }
	    }
	  }
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
1605 1606
	rx_cnt++;
	tx_cnt++;
Raymond Knopp's avatar
 
Raymond Knopp committed
1607 1608 1609

	if(tx_cnt == max_cnt)
	  tx_cnt = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1610 1611
      }

Raymond Knopp's avatar
 
Raymond Knopp committed
1612 1613
      if(rx_cnt == max_cnt)
	rx_cnt = 0; 
Raymond Knopp's avatar
 
Raymond Knopp committed
1614
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1615 1616 1617

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1620

Raymond Knopp's avatar
 
Raymond Knopp committed
1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641
      
      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
1642
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
1643 1644
      */
      //}
1645
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1646
      if ((slot&1) == 1) {
1647
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1648 1649 1650 1651 1652
	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
1653
	
Raymond Knopp's avatar
 
Raymond Knopp committed
1654
	for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
1655
#ifdef EXMIMO 
Raymond Knopp's avatar
 
Raymond Knopp committed
1656 1657
	  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
1658
	  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1659 1660 1661 1662 1663 1664 1665
	  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);
1666
	      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1667 1668 1669 1670 1671
	    }
	    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
1672
	  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683
#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
1684
	      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1685 1686 1687 1688
	    }
	    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
1689
	    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1690
	  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1691
	    
Raymond Knopp's avatar
 
Raymond Knopp committed
1692 1693
	}
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1694 1695
	  
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1696 1697 1698 1699 1700 1701 1702
#ifndef RTAI
      //pthread_mutex_lock(&tti_mutex);
#endif




Raymond Knopp's avatar
 
Raymond Knopp committed
1703
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1704
      slot++;
Raymond Knopp's avatar
 
Raymond Knopp committed
1705 1706 1707 1708
      if (slot == 20) {
	frame++;
	slot = 0;
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1709
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1710 1711 1712
      hw_subframe++;
      slot+=2;
      if(hw_subframe==10) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1713
	hw_subframe = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1714
	frame++;
Raymond Knopp's avatar
 
Raymond Knopp committed
1715
	slot = 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1716
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1717
#endif     
Raymond Knopp's avatar
 
Raymond Knopp committed
1718 1719


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

Raymond Knopp's avatar
 
Raymond Knopp committed
1733 1734 1735 1736 1737

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1750 1751 1752
#ifdef USRP_DEBUG
int is_synchronized=1;
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1753
int is_synchronized=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1754
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1755 1756 1757

static void *UE_thread_synch(void *arg) {

1758
  int i,hw_slot_offset,CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1759 1760
  PHY_VARS_UE *UE = arg;

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

  pthread_mutex_lock(&sync_mutex);
  printf("Locked sync_mutex, waiting (UE_sync_thread)\n");
1770 1771
  while (sync_var<0)
    pthread_cond_wait(&sync_cond, &sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
1772 1773
  pthread_mutex_unlock(&sync_mutex);
  printf("unlocked sync_mutex (UE_sync_thread)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1774
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1775
  printf("starting UE synch thread\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792
#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
1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808
    }  // 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
1809

Raymond Knopp's avatar
 
Raymond Knopp committed
1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823
      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
1824
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1825 1826 1827
      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
1828 1829
      }
      else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1830 1831 1832
	openair_daq_vars.freq_offset *= -1;
      }
      if (abs(openair_daq_vars.freq_offset) > 7500) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1833 1834
	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
1835 1836
      }
      else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1837 1838
	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
1839 1840 1841 1842
	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
1843
	    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
1844
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
1845 1846
#ifndef USRP_DEBUG
	    openair0_set_frequencies(&openair0,&openair0_cfg[0]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1847
	    //	    openair0_set_gains(&openair0,&openair0_cfg[0]);
Navid Nikaein's avatar
Navid Nikaein committed
1848
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1849
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1850
	  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868
	}

	//	    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
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 1933 1934 1935
    
  }  // 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
1936
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1937
  PHY_VARS_UE *UE = (PHY_VARS_UE*)arg;
Raymond Knopp's avatar
 
Raymond Knopp committed
1938 1939
  int i;
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1940
  UE->instance_cnt_rx=-1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1941
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1942
  mlockall(MCL_CURRENT | MCL_FUTURE);
Raymond Knopp's avatar
 
Raymond Knopp committed
1943
  
1944
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1945 1946 1947 1948 1949 1950
  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");
1951 1952
  while (sync_var<0)
    pthread_cond_wait(&sync_cond, &sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
1953 1954 1955 1956
  pthread_mutex_unlock(&sync_mutex);
  printf("unlocked sync_mutex, waiting (UE_thread_rx)\n");
#endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1957

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1960 1961
  while (!oai_exit) { 
    printf("UE_thread_rx: locking UE RX mutex\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1962 1963 1964 1965 1966 1967
    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
1968
      printf("UE_thread_rx: unlocking UE RX mutex (IC %d)\n",UE->instance_cnt_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1969
      while (UE->instance_cnt_rx < 0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1970
	printf("Waiting for cond_rx (%p)\n",(void*)&UE->cond_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1971
	pthread_cond_wait(&UE->cond_rx,&UE->mutex_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1972
	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
1973 1974 1975 1976 1977
      }
      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
1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994
      
      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
1995
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1996 1997 1998 1999 2000 2001 2002
    }
    
    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
2003
      
Raymond Knopp's avatar
 
Raymond Knopp committed
2004 2005 2006
      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
2007
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
2008
    printf("UE_thread_rx done\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
2009
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
2010
       
Raymond Knopp's avatar
 
Raymond Knopp committed
2011 2012 2013
  return(0);
}

Raymond Knopp's avatar
 
Raymond Knopp committed
2014 2015 2016



2017
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
2018 2019 2020 2021 2022
#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
2023

Raymond Knopp's avatar
 
Raymond Knopp committed
2024 2025 2026
  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
2027
  // unsigned int aa;
Raymond Knopp's avatar
 
Raymond Knopp committed
2028
  int dummy[2][samples_per_packets];
Raymond Knopp's avatar
 
Raymond Knopp committed
2029 2030 2031 2032 2033
  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
2034
  int i;
Raymond Knopp's avatar
 
Raymond Knopp committed
2035 2036 2037

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

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

  printf("starting UE thread\n");

  T0 = rt_get_time_ns();
Raymond Knopp's avatar
 
Raymond Knopp committed
2055 2056 2057
  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
2058

Raymond Knopp's avatar
 
Raymond Knopp committed
2059

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

      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
2068 2069
      rxs = openair0.trx_read_func(&openair0,
				   &timestamp,
Raymond Knopp's avatar
 
Raymond Knopp committed
2070 2071 2072
				   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
2073
      if (rxs != (samples_per_packets- ((rx_cnt==0) ? rx_off_diff : 0)))
Raymond Knopp's avatar
 
Raymond Knopp committed
2074
	oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
2075 2076

      rx_off_diff = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2077 2078 2079
      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
2080
      if (tx_enabled) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2081
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
2082 2083
	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
2084 2085
	openair0.trx_write_func(&openair0,
				(timestamp+samples_per_packets*tx_delay-tx_forward_nsamps),
Raymond Knopp's avatar
 
Raymond Knopp committed
2086
				txp,
Raymond Knopp's avatar
 
Raymond Knopp committed
2087
				samples_per_packets,
Raymond Knopp's avatar
 
Raymond Knopp committed
2088
				PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_tx,
Raymond Knopp's avatar
 
Raymond Knopp committed
2089
				1);
Raymond Knopp's avatar
 
Raymond Knopp committed
2090
				
Raymond Knopp's avatar
 
Raymond Knopp committed
2091 2092
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,0);
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2093 2094 2095
#else
      rt_sleep_ns(10000000);
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2096 2097 2098 2099 2100 2101 2102 2103
      rx_cnt++;
      tx_cnt++;
      
      if(tx_cnt == max_cnt)
	tx_cnt = 0;
    }
    
    if(rx_cnt == max_cnt)
Raymond Knopp's avatar
 
Raymond Knopp committed
2104 2105 2106
      rx_cnt = 0;


Raymond Knopp's avatar
 
Raymond Knopp committed
2107
    
Raymond Knopp's avatar
 
Raymond Knopp committed
2108
    if (is_synchronized==1)  {
Raymond Knopp's avatar
 
Raymond Knopp committed
2109 2110
      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
2111 2112 2113 2114 2115 2116 2117
      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
2118
 	  
Raymond Knopp's avatar
 
Raymond Knopp committed
2119 2120 2121 2122
	  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
2123
	    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
2124 2125 2126 2127 2128 2129 2130 2131 2132
	    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
2133
		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
2134 2135 2136 2137 2138 2139 2140 2141
		      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
2142 2143 2144
		      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
2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155
		      );
		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
2156 2157 2158
    }
    else {  // we are not yet synchronized
      
Raymond Knopp's avatar
 
Raymond Knopp committed
2159
      if ((hw_subframe == 9)&&(dummy_dump == 0)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2160
	// Wake up initial synch thread
Raymond Knopp's avatar
 
Raymond Knopp committed
2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180
	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
2181
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2182
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193
    /*
      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
2194 2195
      if (PHY_vars_UE_g[0][0]->instance_cnt_synch < 0) {
	if (is_synchronized == 1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2196
	  //	  openair0_set_gains(&openair0,&openair0_cfg[0]);
Raymond Knopp's avatar
 
Raymond Knopp committed
2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207
	  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
2208 2209
					 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
2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227
#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
2228 2229 2230 2231 2232 2233 2234
    }
    
#if defined(ENABLE_ITTI)
    itti_update_lte_time(frame, slot);
#endif
  }
}
2235
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2236

Raymond Knopp's avatar
 
Raymond Knopp committed
2237 2238


2239
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
2240 2241
/* 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) {
2242
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2243 2244 2245
  RT_TASK *task;
#endif
  // RTIME in, out, diff;
Raymond Knopp's avatar
 
Raymond Knopp committed
2246
  int slot=0,frame=0,hw_slot,last_slot,next_slot;
Raymond Knopp's avatar
 
Raymond Knopp committed
2247 2248 2249 2250 2251 2252 2253
  // 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;
2254
  int CC_id,card;
Raymond Knopp's avatar
 
Raymond Knopp committed
2255 2256
  volatile unsigned int *DAQ_MBOX = openair0_daq_cnt();
#ifndef USRP
2257
  //exmimo_config_t *p_exmimo_config = openair0_exmimo_pci[card].exmimo_config_ptr;;
Raymond Knopp's avatar
 
Raymond Knopp committed
2258 2259
#endif

2260

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

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

#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
2272
  rt_make_hard_real_time();
2273 2274
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2275
  mlockall(MCL_CURRENT | MCL_FUTURE);
2276

Raymond Knopp's avatar
 
Raymond Knopp committed
2277 2278 2279 2280 2281 2282 2283 2284
  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;
    }
2285
    openair0_dump_config(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
2286 2287 2288
    }
  */
  while (!oai_exit)  {
Raymond Knopp's avatar
 
Raymond Knopp committed
2289

Raymond Knopp's avatar
 
Raymond Knopp committed
2290
    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
2291 2292

     
Raymond Knopp's avatar
 
Raymond Knopp committed
2293
    if (is_synchronized) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2294 2295


Raymond Knopp's avatar
 
Raymond Knopp committed
2296
      //this is the mbox counter that indicates the start of the frame
Raymond Knopp's avatar
 
Raymond Knopp committed
2297
      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
2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310
      //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;
2311
	
Raymond Knopp's avatar
 
Raymond Knopp committed
2312 2313
      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);
2314 2315 2316 2317 2318 2319 2320 2321
	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
2322 2323 2324 2325
	slot++;
	if (slot==20) {
	  slot=0;
	  frame++;
Raymond Knopp's avatar
 
Raymond Knopp committed
2326
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350
	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);
2351
	  
Raymond Knopp's avatar
 
Raymond Knopp committed
2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376
	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;
2377 2378 2379 2380 2381 2382 2383 2384

    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
2385 2386
      
    if (is_synchronized)  {
2387
      phy_procedures_UE_lte (PHY_vars_UE_g[0][0], 0, 0, mode, 0, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
2388 2389 2390 2391 2392 2393
	
    }
    else {  // we are not yet synchronized
      hw_slot_offset = 0;
	
      slot = 0;
2394
      openair0_get_frame(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
2395 2396 2397 2398
      //          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
2399
      if (initial_sync(PHY_vars_UE_g[0][0],mode)==0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2400
	/*
Raymond Knopp's avatar
 
Raymond Knopp committed
2401 2402 2403 2404 2405
	  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
2406
	*/
Raymond Knopp's avatar
 
Raymond Knopp committed
2407 2408 2409 2410 2411 2412
	//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));
	*/
2413 2414
	
	/*if (mode == rx_calib_ue) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2415
	  exit_fun("[HW][UE] UE in RX calibration mode");
Raymond Knopp's avatar
 
Raymond Knopp committed
2416
	}
2417
	else {*/
Raymond Knopp's avatar
 
Raymond Knopp committed
2418 2419 2420
	  is_synchronized = 1;
	  //start the DMA transfers
	  //LOG_D(HW,"Before openair0_start_rt_acquisition \n");
2421 2422
	  for (card=0;card<openair0_num_detected_cards;card++)
	    openair0_start_rt_acquisition(card);
Raymond Knopp's avatar
 
Raymond Knopp committed
2423
	    
Raymond Knopp's avatar
 
Raymond Knopp committed
2424
	  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
2425 2426
	  //LOG_D(HW,"Got synch: hw_slot_offset %d\n",hw_slot_offset);
	  oai_exit=1;
2427
	  /*}*/
Raymond Knopp's avatar
 
Raymond Knopp committed
2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441
      }
      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
2442
	  //	  LOG_I(PHY,"[initial_sync] trying carrier off %d Hz\n",openair_daq_vars.freq_offset);
Raymond Knopp's avatar
 
Raymond Knopp committed
2443
#ifndef USRP
2444 2445 2446 2447 2448
	  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
2449
	  }
2450
	  openair0_config(&openair0_cfg[0],UE_flag);
2451
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2452 2453
	  rt_sleep_ns(FRAME_PERIOD);
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
2454
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2455
    }
2456
    
Raymond Knopp's avatar
 
Raymond Knopp committed
2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470
    /*
      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);
2471 2472

#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
2473
  rt_make_soft_real_time();
2474 2475
#endif

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

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

2486
#endif
2487

2488

Raymond Knopp's avatar
 
Raymond Knopp committed
2489 2490 2491 2492 2493
void init_UE_threads(void) {
  
  PHY_VARS_UE *UE=PHY_vars_UE_g[0][0];

  pthread_attr_init(&attr_UE_thread_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
2494
  pthread_attr_setstacksize(&attr_UE_thread_tx,PTHREAD_STACK_MIN);
Raymond Knopp's avatar
 
Raymond Knopp committed
2495 2496 2497 2498 2499
  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);
Raymond Knopp's avatar
 
Raymond Knopp committed
2500
  pthread_attr_setstacksize(&attr_UE_thread_rx,PTHREAD_STACK_MIN);
Raymond Knopp's avatar
 
Raymond Knopp committed
2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518
  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;

2519
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530
  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
2531
}
Raymond Knopp's avatar
 
Raymond Knopp committed
2532 2533


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

Raymond Knopp's avatar
 
Raymond Knopp committed
2547 2548 2549 2550 2551 2552 2553 2554 2555
  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,
2556
    LONG_OPTION_NO_L2_CONNECT
Raymond Knopp's avatar
 
Raymond Knopp committed
2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567
  };
  
  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}};
  
2568
  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
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 2598 2599 2600
    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
2601
      multi_thread=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2602 2603
      break;
    case 'C':
2604
      for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
2605 2606 2607 2608 2609
	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]);
2610
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2611 2612 2613 2614 2615
      break;
      
    case 'd':
#ifdef XFORMS
      do_forms=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
2616
      printf("Running with XFORMS!\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634
#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;
2635 2636 2637 2638 2639 2640 2641
    
    case 'm':
      target_dl_mcs = atoi (optarg);
      break;
    case 't':
      target_ul_mcs = atoi (optarg);
      break;
2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657
    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
2658 2659 2660 2661
      
    case 'V':
      ouput_vcd = 1;
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
2662
    case  'q':
Raymond Knopp's avatar
 
Raymond Knopp committed
2663 2664 2665 2666 2667 2668
      opp_enabled = 1;
      break;
    case  'R' :
      online_log_messages =1;
      break;
    case 'r':
Raymond Knopp's avatar
 
Raymond Knopp committed
2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690
      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
2691
      }
2692
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
2693 2694
    case 's':
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
2695 2696 2697

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

    case 'F':
2718
#ifdef EXMIMO
2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735
      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);
2736
#endif
2737 2738
      break;
      
2739 2740 2741
    case 'G':
      glog_verbosity=atoi(optarg);// value from 0, 0x5, 0x15, 0x35, 0x75
      break;
2742 2743 2744 2745 2746 2747 2748
    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
2749 2750
    default:
      break;
2751 2752
    }
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
2753 2754
  
  if ((UE_flag == 0) && (conf_config_file_name != NULL)) {
2755
    int i,j;
Raymond Knopp's avatar
 
Raymond Knopp committed
2756 2757 2758 2759 2760 2761 2762 2763 2764
    
    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);
2765

Raymond Knopp's avatar
 
Raymond Knopp committed
2766
    /* Update some simulation parameters */
2767
    for (i=0; i < enb_properties->number; i++) {
2768 2769 2770 2771
      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
2772 2773 2774 2775 2776 2777
      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
2778
	//for (j=0; j < enb_properties->properties[i]->nb_cc; j++ ){
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];
Raymond Knopp's avatar
 
Raymond Knopp committed
2781
	frame_parms[CC_id]->N_RB_UL             =  enb_properties->properties[i]->N_RB_DL[CC_id];
2782 2783 2784
	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];
2785
	//} // j
Raymond Knopp's avatar
 
Raymond Knopp committed
2786 2787
      }

2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807
      
#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
      
2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821
      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
2822 2823 2824 2825 2826 2827
# 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
2828 2829 2830 2831
#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 
2832
    
Raymond Knopp's avatar
 
Raymond Knopp committed
2833
      // adjust the log
2834 2835
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
	for (k = 0 ; k < 4; k++) {
2836
	  downlink_frequency[CC_id][k]      =       enb_properties->properties[i]->downlink_frequency[CC_id];
2837
	  uplink_frequency_offset[CC_id][k] =  enb_properties->properties[i]->uplink_frequency_offset[CC_id];
2838 2839
	  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];
2840
	}
2841
	printf("Downlink frequency/ uplink offset of CC_id %d set to %ju/%d\n", CC_id,
2842 2843
	       enb_properties->properties[i]->downlink_frequency[CC_id],
	       enb_properties->properties[i]->uplink_frequency_offset[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
2844
      } // CC_id
2845
    }// i
Raymond Knopp's avatar
 
Raymond Knopp committed
2846 2847
  }
}
2848

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

#ifdef ENABLE_TCXO
Raymond Knopp's avatar
 
Raymond Knopp committed
2869
  unsigned int tcxo = 114;
2870 2871
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2872 2873 2874 2875
#ifdef ETHERNET
  char *rrh_ip = "127.0.0.1";
  int rrh_port = 22222;
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2876
  //  int amp;
Raymond Knopp's avatar
 
Raymond Knopp committed
2877 2878
  // uint8_t prach_fmt;
  // int N_ZC;
2879

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
2891
  set_latency_target();
2892

Raymond Knopp's avatar
 
Raymond Knopp committed
2893
  mode = normal_txrx;
2894

Raymond Knopp's avatar
 
Raymond Knopp committed
2895 2896 2897
  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
2898
    frame_parms[CC_id]->frame_type         = FDD; /* TDD */
Raymond Knopp's avatar
 
Raymond Knopp committed
2899 2900 2901 2902
    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
2903
    frame_parms[CC_id]->Ncp                 = NORMAL;
Raymond Knopp's avatar
 
Raymond Knopp committed
2904 2905
    frame_parms[CC_id]->Ncp_UL              = NORMAL;
    frame_parms[CC_id]->Nid_cell            = Nid_cell;
Raymond Knopp's avatar
 
Raymond Knopp committed
2906
    frame_parms[CC_id]->num_MBSFN_config    = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2907
  }
2908

2909 2910 2911
  // initialize the log (see log.h for details)
  logInit();
  set_glog(glog_level, glog_verbosity);
winckel's avatar
winckel committed
2912

Raymond Knopp's avatar
 
Raymond Knopp committed
2913 2914
  //randominit (0);
  set_taus_seed (0);
winckel's avatar
winckel committed
2915

2916 2917
  get_options (argc, argv); //Command-line options
  
Raymond Knopp's avatar
 
Raymond Knopp committed
2918 2919 2920 2921

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

2923
      set_comp_log(HW,      LOG_DEBUG,  LOG_HIGH, 1);
2924
#ifdef OPENAIR2
2925
      set_comp_log(PHY,     LOG_DEBUG,   LOG_HIGH, 1);
2926
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
2927
      set_comp_log(PHY,     LOG_INFO,   LOG_HIGH, 1);
2928
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2929 2930 2931 2932 2933
      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);
2934
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
2935
      set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
2936
# if defined(ENABLE_USE_MME)
Raymond Knopp's avatar
 
Raymond Knopp committed
2937
      set_comp_log(NAS,     LOG_INFO,   LOG_HIGH, 1);
2938 2939
# endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2940 2941 2942 2943
    }
  else
    {
      printf("configuring for eNB\n");
2944

2945
      set_comp_log(HW,      hw_log_level, hw_log_verbosity, 1);
2946
#ifdef OPENAIR2
2947
      set_comp_log(PHY,     phy_log_level,   phy_log_verbosity, 1);
2948
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
2949
      set_comp_log(PHY,     LOG_INFO,   LOG_HIGH, 1);
2950
#endif
2951 2952 2953 2954
      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);
2955
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
2956
      set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
2957
# if defined(ENABLE_USE_MME)
Lionel Gauthier's avatar
 
Lionel Gauthier committed
2958 2959
      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
2960 2961
      set_comp_log(S1AP,    LOG_DEBUG,   LOG_HIGH, 1);
      set_comp_log(SCTP,    LOG_INFO,   LOG_HIGH, 1);
2962
# endif
2963
#if defined(ENABLE_SECURITY)
2964
      set_comp_log(OSA,    osa_log_level,   osa_log_verbosity, 1);
2965
#endif
2966
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2967
      set_comp_log(ENB_APP, LOG_INFO, LOG_HIGH, 1);
2968
      set_comp_log(OTG,     LOG_INFO,   LOG_HIGH, 1);
Raymond Knopp's avatar
 
Raymond Knopp committed
2969 2970 2971
      if (online_log_messages == 1) { 
	set_component_filelog(RRC);
	set_component_filelog(PDCP);
Raymond Knopp's avatar
 
Raymond Knopp committed
2972 2973
      }
    }
2974

Raymond Knopp's avatar
 
Raymond Knopp committed
2975 2976 2977 2978 2979 2980
  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");
  }
2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994
  
  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");
  }
  
2995
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
2996 2997 2998 2999 3000 3001
  if (UE_flag == 1) {
    log_set_instance_type (LOG_INSTANCE_UE);
  }
  else {
    log_set_instance_type (LOG_INSTANCE_ENB);
  }
3002

Raymond Knopp's avatar
 
Raymond Knopp committed
3003
  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
3004 3005
#endif

3006
#ifdef NAS_NETLINK
Raymond Knopp's avatar
 
Raymond Knopp committed
3007
  netlink_init();
3008 3009
#endif

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

#ifndef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3017 3018 3019 3020
  check_clock();
#endif

  // init the parameters
Raymond Knopp's avatar
 
Raymond Knopp committed
3021 3022 3023 3024
  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    frame_parms[CC_id]->nushift            = 0;
    if (UE_flag==0)
      {
3025

Raymond Knopp's avatar
 
Raymond Knopp committed
3026
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3027 3028 3029 3030
    else
      { //UE_flag==1
	frame_parms[CC_id]->nb_antennas_tx     = 1;
	frame_parms[CC_id]->nb_antennas_rx     = 1;
3031
	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
3032 3033 3034 3035 3036 3037 3038 3039 3040
      }
    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;
3041 3042
    init_ul_hopping(frame_parms[CC_id]);
    init_frame_parms(frame_parms[CC_id],1);
3043
    phy_init_top(frame_parms[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055
  }

  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
3056
    // N_ZC = (prach_fmt <4)?839:139;
Raymond Knopp's avatar
 
Raymond Knopp committed
3057
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3058 3059

  if (UE_flag==1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3060 3061 3062
    NB_UE_INST=1;
    NB_INST=1;

Raymond Knopp's avatar
 
Raymond Knopp committed
3063 3064 3065
    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++) {
3066
      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
3067
      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
3068 3069
#ifndef OPENAIR2
      for (i=0;i<NUMBER_OF_eNB_MAX;i++) {
3070 3071 3072
	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
3073
	
3074 3075 3076
	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
3077
      }
3078
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3079
      
3080 3081 3082
      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
3083
      
3084
      PHY_vars_UE_g[0][CC_id]->lte_ue_pdcch_vars[0]->crnti = 0x1234;
3085
#ifndef OPENAIR2
3086
      PHY_vars_UE_g[0][CC_id]->lte_ue_pdcch_vars[0]->crnti = 0x1235;
3087
#endif
3088
    
3089
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3090 3091 3092 3093 3094
      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];
      }
3095

Raymond Knopp's avatar
 
Raymond Knopp committed
3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110
      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;
      }
3111
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3112
      PHY_vars_UE_g[0][CC_id]->rx_total_gain_dB =  (int)rx_gain[CC_id][0]; 
3113
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3114
    
Raymond Knopp's avatar
 
Raymond Knopp committed
3115
      PHY_vars_UE_g[0][CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
Raymond Knopp's avatar
 
Raymond Knopp committed
3116
    
3117

3118
   
3119
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131
      //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;
      }
3132
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3133 3134
      //already taken care of in lte-softmodem
      PHY_vars_UE_g[UE_id][CC_id]->N_TA_offset = 0;
3135
#endif 
Raymond Knopp's avatar
 
Raymond Knopp committed
3136
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3137 3138 3139 3140 3141
    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;
    
3142
  
Raymond Knopp's avatar
 
Raymond Knopp committed
3143 3144 3145 3146 3147
    
    //  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
3148 3149 3150
      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
3151
	PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],eNB_id,Nid_cell,cooperation_flag,transmission_mode,abstraction_flag);
3152
	PHY_vars_eNB_g[0][CC_id]->CC_id = CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
3153
       
3154
#ifndef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3155 3156 3157 3158 3159 3160 3161 3162 3163
	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
3164
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3165 3166 3167 3168
      
	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
3169

3170
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3171

3172
	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
3173

3174
#else
3175
	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
3176 3177 3178

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

3179 3180
	// set eNB to max gain
	for (i=0;i<4;i++)
3181 3182
	  rx_gain_mode[CC_id][i] = max_gain;
#endif
3183

3184
#ifdef EXMIMO
3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201
	//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
3202
      }
3203 3204


Raymond Knopp's avatar
 
Raymond Knopp committed
3205 3206
      NB_eNB_INST=1;
      NB_INST=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
3207

Raymond Knopp's avatar
 
Raymond Knopp committed
3208
      openair_daq_vars.ue_dl_rb_alloc=0x1fff;
3209
      openair_daq_vars.target_ue_dl_mcs=target_dl_mcs;
Raymond Knopp's avatar
 
Raymond Knopp committed
3210
      openair_daq_vars.ue_ul_nb_rb=6;
3211
      openair_daq_vars.target_ue_ul_mcs=target_ul_mcs;
Raymond Knopp's avatar
 
Raymond Knopp committed
3212 3213

    }
3214

3215

3216

Raymond Knopp's avatar
 
Raymond Knopp committed
3217
  dump_frame_parms(frame_parms[0]);
3218

Raymond Knopp's avatar
 
Raymond Knopp committed
3219
  if(frame_parms[0]->N_RB_DL == 100) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3220
    sample_rate = 30.72e6;
3221
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3222 3223 3224 3225 3226
    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
3227
    sf_bounds_tx = sf_bounds_20_tx;
Raymond Knopp's avatar
 
Raymond Knopp committed
3228
    max_cnt = 150;
3229
    tx_delay = 8;
Raymond Knopp's avatar
 
Raymond Knopp committed
3230 3231
#endif
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3232
  else if(frame_parms[0]->N_RB_DL == 50){
3233
    sample_rate = 15.36e6;
3234
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3235 3236 3237 3238
    samples_per_packets = 2048;
    samples_per_frame = 153600;
    tx_forward_nsamps = 95;
    sf_bounds = sf_bounds_10;
Raymond Knopp's avatar
 
Raymond Knopp committed
3239
    sf_bounds_tx = sf_bounds_10_tx;
Raymond Knopp's avatar
 
Raymond Knopp committed
3240 3241 3242 3243
    max_cnt = 75;
    tx_delay = 4;
#endif
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3244
  else if (frame_parms[0]->N_RB_DL == 25) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3245
    sample_rate = 7.68e6;
3246
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3247 3248 3249 3250
    samples_per_packets = 1024;
    samples_per_frame = 76800;
    tx_forward_nsamps = 70;
    sf_bounds = sf_bounds_5;
Raymond Knopp's avatar
 
Raymond Knopp committed
3251
    sf_bounds_tx = sf_bounds_5_tx;
Raymond Knopp's avatar
 
Raymond Knopp committed
3252
    max_cnt = 75;
Raymond Knopp's avatar
 
Raymond Knopp committed
3253
    tx_delay = 5;
Raymond Knopp's avatar
 
Raymond Knopp committed
3254 3255
#endif
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267
  else if (frame_parms[0]->N_RB_DL == 6) {
    sample_rate = 1.92e6;
#ifndef EXMIMO
    samples_per_packets = 256;
    samples_per_frame = 19200;
    tx_forward_nsamps = 40;
    sf_bounds = sf_bounds_1_5;
    sf_bounds_tx = sf_bounds_1_5_tx;
    max_cnt = 75;
    tx_delay = 5;
#endif
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3268
  
3269

3270
  for (card=0;card<MAX_CARDS;card++) {
3271
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3272
    openair0_cfg[card].samples_per_packet = 1024;//samples_per_packets;
3273 3274 3275 3276
#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
3277 3278 3279 3280 3281 3282
    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
3283 3284 3285
    openair0_cfg[card].sample_rate = sample_rate;
    openair0_cfg[card].tx_bw = bw;
    openair0_cfg[card].rx_bw = bw;
3286 3287 3288
    // 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
3289
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3290 3291
    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));
3292
    for (i=0;i<4;i++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3293

3294
      openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
Raymond Knopp's avatar
 
Raymond Knopp committed
3295 3296
      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
3297 3298
      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
3299 3300 3301 3302 3303 3304
      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
3305
    }
3306
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3307
  }
3308 3309

  if (openair0_device_init(&openair0, &openair0_cfg[0]) <0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3310 3311 3312
    printf("Exiting, cannot initialize device\n");
    exit(-1);
  }
3313 3314 3315

  mac_xface = malloc(sizeof(MAC_xface));

3316
#ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3317
  int eMBMS_active=0;
3318

3319
  l2_init(frame_parms[0],eMBMS_active,
Raymond Knopp's avatar
 
Raymond Knopp committed
3320 3321 3322 3323 3324 3325
	  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);
3326 3327
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3328
  mac_xface->macphy_exit = &exit_fun;
3329

winckel's avatar
winckel committed
3330
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
3331
  if (create_tasks(UE_flag ? 0 : 1, UE_flag ? 1 : 0) < 0) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
3332
    printf("cannot create ITTI tasks\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
3333 3334 3335
    exit(-1); // need a softer mode
  }
  printf("ITTI tasks created\n");
winckel's avatar
winckel committed
3336 3337
#endif

3338
  /* #ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349
  //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
3350
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3351 3352 3353
  }
  init_predef_traffic(UE_flag ? 1 : 0, UE_flag ? 0 : 1);
  //  }
3354
  #endif */
Raymond Knopp's avatar
 
Raymond Knopp committed
3355

3356
#ifdef EXMIMO
3357
  number_of_cards = openair0_num_detected_cards;
3358 3359 3360
#else
  number_of_cards = 1;
#endif 
3361

Raymond Knopp's avatar
 
Raymond Knopp committed
3362
  openair_daq_vars.timing_advance = 0;
3363

Florian Kaltenberger's avatar
Florian Kaltenberger committed
3364 3365
  for(CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    rf_map[CC_id].card=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3366
    rf_map[CC_id].chain=CC_id+3;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
3367
  }
3368

Raymond Knopp's avatar
 
Raymond Knopp committed
3369 3370
  // connect the TX/RX buffers
  if (UE_flag==1) {
3371 3372 3373 3374
    if (setup_ue_buffers(PHY_vars_UE_g[0],&openair0_cfg[0],rf_map)!=0) {
      printf("Error setting up eNB buffer\n");
      exit(-1);
    }
3375 3376
    printf("Setting UE buffer to all-RX\n");
    // Set LSBs for antenna switch (ExpressMIMO)
Raymond Knopp's avatar
 
Raymond Knopp committed
3377
    for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3378
      for (i=0; i<frame_parms[CC_id]->samples_per_tti*10; i++)
3379
	for (aa=0; aa<frame_parms[CC_id]->nb_antennas_tx; aa++)
3380
	  PHY_vars_UE_g[0][CC_id]->lte_ue_common_vars.txdata[aa][i] = 0x00010001;
Raymond Knopp's avatar
 
Raymond Knopp committed
3381
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3382 3383 3384
    //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX;
  }
  else {
3385 3386 3387 3388 3389 3390
    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
3391
    for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3392 3393
      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++)
3394
	  PHY_vars_eNB_g[0][CC_id]->lte_eNB_common_vars.txdata[0][aa][i] = 0x00010001;
Raymond Knopp's avatar
 
Raymond Knopp committed
3395
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3396
  }
3397
#ifdef EXMIMO
3398
  openair0_config(&openair0_cfg[0],UE_flag);
Raymond Knopp's avatar
 
Raymond Knopp committed
3399 3400
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3401
  /*  
Raymond Knopp's avatar
 
Raymond Knopp committed
3402 3403
      for (ant=0;ant<4;ant++)
      p_exmimo_config->rf.do_autocal[ant] = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3404
  */
3405 3406

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3407 3408 3409 3410 3411 3412 3413 3414 3415
  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);
3416 3417
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3418
  mlockall(MCL_CURRENT | MCL_FUTURE);
3419 3420

#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441
  // 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);
3442

Raymond Knopp's avatar
 
Raymond Knopp committed
3443 3444 3445
  sync_sem = rt_typed_sem_init(nam2num("syncsem"), 0, BIN_SEM|FIFO_Q);
  if(sync_sem == 0)
    printf("error init sync semphore\n");
3446

Raymond Knopp's avatar
 
Raymond Knopp committed
3447 3448 3449
#else
  pthread_cond_init(&sync_cond,NULL);
  pthread_mutex_init(&sync_mutex, NULL);
3450 3451
#endif

3452
#if defined(ENABLE_ITTI)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
3453 3454 3455 3456 3457
  // 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);
  }
3458
#endif
3459

Raymond Knopp's avatar
 
Raymond Knopp committed
3460 3461

  // this starts the DMA transfers
3462
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3463
  if (UE_flag!=1)
3464 3465
    for (card=0;card<openair0_num_detected_cards;card++)
      openair0_start_rt_acquisition(card);
Raymond Knopp's avatar
 
Raymond Knopp committed
3466
#endif
3467 3468

#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
3469 3470
  if (do_forms==1) {
    fl_initialize (&argc, argv, NULL, 0, 0);
3471 3472

    if (UE_flag==0) {
3473
      form_stats_l2 = create_form_stats_form();
3474 3475 3476
      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
3477 3478 3479 3480 3481 3482 3483
      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
3484 3485
	}
	else {
Raymond Knopp's avatar
 
Raymond Knopp committed
3486 3487
	  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
3488
	}
3489 3490
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3491
    else {
3492 3493 3494 3495 3496 3497 3498
      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
3499 3500 3501 3502 3503 3504 3505 3506 3507 3508
      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
3509
    ret = pthread_create(&forms_thread, NULL, scope_thread, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
3510 3511
    printf("Scope thread created, ret=%d\n",ret);
  }
3512 3513 3514
#endif

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3515 3516
  ret = pthread_create(&thread3, NULL, emos_thread, NULL);
  printf("EMOS thread created, ret=%d\n",ret);
3517 3518
#endif

3519 3520 3521 3522 3523
#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
3524
  rt_sleep_ns(10*FRAME_PERIOD);
3525 3526

#ifndef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3527
  pthread_attr_init (&attr_dlsch_threads);
Raymond Knopp's avatar
 
Raymond Knopp committed
3528
  pthread_attr_setstacksize(&attr_dlsch_threads,PTHREAD_STACK_MIN);
3529 3530

#ifndef LOWLATENCY
3531
  sched_param_dlsch.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY;
Raymond Knopp's avatar
 
Raymond Knopp committed
3532 3533
  pthread_attr_setschedparam  (&attr_dlsch_threads, &sched_param_dlsch);
  pthread_attr_setschedpolicy (&attr_dlsch_threads, SCHED_FIFO);
3534
#endif 
Raymond Knopp's avatar
 
Raymond Knopp committed
3535
  pthread_attr_init (&attr_UE_init_synch);
Raymond Knopp's avatar
 
Raymond Knopp committed
3536
  pthread_attr_setstacksize(&attr_UE_init_synch,PTHREAD_STACK_MIN);
3537
  sched_param_UE_init_synch.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY;
Raymond Knopp's avatar
 
Raymond Knopp committed
3538 3539 3540
  pthread_attr_setschedparam  (&attr_UE_init_synch, &sched_param_UE_init_synch);
  pthread_attr_setschedpolicy (&attr_UE_init_synch, SCHED_FIFO);

3541 3542
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3543 3544
  // start the main thread
  if (UE_flag == 1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3545
    init_UE_threads();
3546
    sleep(1);
3547
#ifdef RTAI
3548
    main_ue_thread = rt_thread_create(UE_thread, NULL, 100000000);
3549
#else
3550
    error_code = pthread_create(&main_ue_thread, &attr_dlsch_threads, UE_thread, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
3551 3552 3553 3554 3555 3556 3557
    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");
    }
3558 3559
#endif
#ifdef DLSCH_THREAD
Raymond Knopp's avatar
 
Raymond Knopp committed
3560 3561 3562
    init_rx_pdsch_thread();
    rt_sleep_ns(FRAME_PERIOD/10);
    init_dlsch_threads();
3563
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3564 3565 3566
    printf("UE threads created\n");
  }
  else {
3567

Raymond Knopp's avatar
 
Raymond Knopp committed
3568 3569
    if (multi_thread>0) {
      init_eNB_proc();
3570
      sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3571 3572
      LOG_D(HW,"[lte-softmodem.c] eNB threads created\n");
    }
3573
    printf("Creating main eNB_thread \n");
Raymond Knopp's avatar
 
Raymond Knopp committed
3574
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3575
    main_eNB_thread = rt_thread_create(eNB_thread, NULL, PTHREAD_STACK_MIN);
Raymond Knopp's avatar
 
Raymond Knopp committed
3576
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3577
    error_code = pthread_create(&main_eNB_thread, &attr_dlsch_threads, eNB_thread, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
3578 3579 3580 3581 3582 3583
    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
3584
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3585 3586
#endif
  }
3587

Raymond Knopp's avatar
 
Raymond Knopp committed
3588
  // Sleep to allow all threads to setup
Raymond Knopp's avatar
 
Raymond Knopp committed
3589
  sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3590

3591
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3592
#ifndef USRP_DEBUG
Raymond Knopp's avatar
 
Raymond Knopp committed
3593
  openair0.trx_start_func(&openair0);
Raymond Knopp's avatar
 
Raymond Knopp committed
3594
  //  printf("returning from usrp start streaming: %llu\n",get_usrp_time(&openair0));
Raymond Knopp's avatar
 
Raymond Knopp committed
3595
#endif
3596 3597
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3598 3599 3600
#ifdef RTAI
  rt_sem_signal(sync_sem);
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3601 3602
  pthread_mutex_lock(&sync_mutex);
  printf("Sending sync ...\n");
3603
  sync_var=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3604 3605
  pthread_cond_broadcast(&sync_cond);
  pthread_mutex_unlock(&sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
3606
#endif
3607

Raymond Knopp's avatar
 
Raymond Knopp committed
3608 3609 3610
  // wait for end of program
  printf("TYPE <CTRL-C> TO TERMINATE\n");
  //getchar();
3611 3612

#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
3613 3614
  printf("Entering ITTI signals handler\n");
  itti_wait_tasks_end();
3615
  oai_exit=1;
3616
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3617 3618
  while (oai_exit==0)
    rt_sleep_ns(FRAME_PERIOD);
3619
#endif
3620

Raymond Knopp's avatar
 
Raymond Knopp committed
3621
  // stop threads
3622
#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
3623 3624 3625
  printf("waiting for XFORMS thread\n");
  if (do_forms==1)
    {
Raymond Knopp's avatar
 
Raymond Knopp committed
3626
      pthread_join(forms_thread,&status);
Raymond Knopp's avatar
 
Raymond Knopp committed
3627 3628 3629 3630 3631 3632
      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 {
3633 3634
	fl_hide_form(form_stats_l2->stats_form);
	fl_free_form(form_stats_l2->stats_form);
Raymond Knopp's avatar
 
Raymond Knopp committed
3635 3636 3637 3638
	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
3639
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3640
    }
3641 3642
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3643 3644 3645
  printf("stopping MODEM threads\n");
  // cleanup
  if (UE_flag == 1) {
3646
#ifdef EXMIMO
3647
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3648
    rt_thread_join(main_ue_thread); 
3649
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3650
    pthread_join(main_ue_thread,&status); 
3651 3652
#endif
#ifdef DLSCH_THREAD
Raymond Knopp's avatar
 
Raymond Knopp committed
3653 3654
    cleanup_dlsch_threads();
    cleanup_rx_pdsch_thread();
3655
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3656 3657 3658
#endif
  }
  else {
Raymond Knopp's avatar
 
Raymond Knopp committed
3659
#ifdef DEBUG_THREADS
Raymond Knopp's avatar
 
Raymond Knopp committed
3660
    printf("Joining eNB_thread ...");
Raymond Knopp's avatar
 
Raymond Knopp committed
3661
#endif
3662 3663 3664
#ifdef RTAI
    rt_thread_join(main_eNB_thread); 
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3665
    pthread_join(main_eNB_thread,(void**)&eNB_thread_status_p); 
Raymond Knopp's avatar
 
Raymond Knopp committed
3666
#ifdef DEBUG_THREADS
Raymond Knopp's avatar
 
Raymond Knopp committed
3667
    printf("status %d\n",*eNB_thread_status_p);
Raymond Knopp's avatar
 
Raymond Knopp committed
3668
#endif
3669
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3670

Raymond Knopp's avatar
 
Raymond Knopp committed
3671 3672 3673
    if (multi_thread>0) {
      printf("Killing eNB processing threads\n");
      kill_eNB_proc();
Raymond Knopp's avatar
 
Raymond Knopp committed
3674

Raymond Knopp's avatar
 
Raymond Knopp committed
3675
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3676
  }
3677

3678
#ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3679
  //cleanup_pdcp_thread();
3680 3681
#endif

3682
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3683
  rt_sem_delete(sync_sem);
Raymond Knopp's avatar
 
Raymond Knopp committed
3684
  stop_rt_timer();
Raymond Knopp's avatar
 
Raymond Knopp committed
3685 3686 3687
#else
  pthread_cond_destroy(&sync_cond);
  pthread_mutex_destroy(&sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
3688
#endif
3689

3690
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3691
  printf("stopping card\n");
3692
  openair0_stop(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
3693 3694
  printf("closing openair0_lib\n");
  openair0_close();
Raymond Knopp's avatar
 
Raymond Knopp committed
3695
#endif
3696 3697

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3698 3699 3700
  printf("waiting for EMOS thread\n");
  pthread_cancel(thread3);
  pthread_join(thread3,&status);
3701 3702 3703
#endif

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3704 3705
  error_code = rtf_destroy(CHANSOUNDER_FIFO_MINOR);
  printf("[OPENAIR][SCHED][CLEANUP] EMOS FIFO closed, error_code %d\n", error_code);
3706 3707
#endif

3708 3709 3710 3711 3712 3713
#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
3714 3715
  if (ouput_vcd)
    vcd_signal_dumper_close();
3716

3717 3718 3719
  if (opt_type != OPT_NONE)
    terminate_opt();

Raymond Knopp's avatar
 
Raymond Knopp committed
3720
  logClean();
3721

Raymond Knopp's avatar
 
Raymond Knopp committed
3722 3723
  return 0;
}
3724

3725 3726
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
3727

3728
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3729 3730 3731
  uint16_t N_TA_offset = 0;
#endif

3732 3733 3734 3735 3736
  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
3737
    }
3738 3739 3740
    else {
      printf("phy_vars_eNB[%d] not initialized\n", CC_id);
      return(-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3741
    }
3742

Raymond Knopp's avatar
 
Raymond Knopp committed
3743

3744
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3745 3746 3747 3748 3749 3750
    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
3751
	N_TA_offset = 624/4;
Raymond Knopp's avatar
 
Raymond Knopp committed
3752 3753 3754
    }
#endif
   
3755
#ifdef EXMIMO
3756 3757 3758 3759 3760
    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++) {
3761
      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);
3762 3763 3764 3765 3766 3767 3768 3769
      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];
3770 3771
	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];
3772 3773
	openair0_cfg[rf_map[CC_id].card].rx_num_channels++;
      }
3774

3775
      printf("rxdata[%d] @ %p\n",i,phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i]);
Raymond Knopp's avatar
 
Raymond Knopp committed
3776
    }
3777
    for (i=0;i<frame_parms->nb_antennas_tx;i++) {
3778
      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);
3779 3780 3781 3782 3783 3784 3785 3786
      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];
3787
	openair0_cfg[rf_map[CC_id].card].tx_gain[rf_map[CC_id].chain+i] = tx_gain[CC_id][i];
3788 3789
	openair0_cfg[rf_map[CC_id].card].tx_num_channels++;
      }
3790

3791
      printf("txdata[%d] @ %p\n",i,phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i]);
3792
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3793
  
Raymond Knopp's avatar
 
Raymond Knopp committed
3794
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3795
    // replace RX signal buffers with mmaped HW versions
3796 3797
    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
3798 3799 3800
    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]);
3801 3802
      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
3803 3804 3805 3806
    }
    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]);
3807 3808 3809
      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
3810 3811
    }
    
Raymond Knopp's avatar
 
Raymond Knopp committed
3812
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3813 3814 3815 3816
    
  }
  return(0);

Raymond Knopp's avatar
 
Raymond Knopp committed
3817
}
3818

3819 3820 3821 3822 3823
/* 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]) {
3824

3825
  int i, CC_id;
3826
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3827
  uint16_t N_TA_offset = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3828 3829
#else
  int j;
Raymond Knopp's avatar
 
Raymond Knopp committed
3830
#endif
3831
  LTE_DL_FRAME_PARMS *frame_parms;
3832

Raymond Knopp's avatar
 
Raymond Knopp committed
3833

3834 3835
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    if (phy_vars_eNB[CC_id]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3836 3837 3838
      frame_parms = &(phy_vars_eNB[CC_id]->lte_frame_parms);
      printf("setup_eNB_buffers: frame_parms = %p\n",frame_parms);
    } 
3839 3840 3841
    else {
      printf("phy_vars_eNB[%d] not initialized\n", CC_id);
      return(-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3842
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3843

3844
#ifndef EXMIMO
3845 3846
    if (frame_parms->frame_type == TDD) {
      if (frame_parms->N_RB_DL == 100)
Raymond Knopp's avatar
 
Raymond Knopp committed
3847
	N_TA_offset = 624;
3848
      else if (frame_parms->N_RB_DL == 50)
Raymond Knopp's avatar
 
Raymond Knopp committed
3849
	N_TA_offset = 624/2;
3850
      else if (frame_parms->N_RB_DL == 25)
Raymond Knopp's avatar
 
Raymond Knopp committed
3851 3852
	N_TA_offset = 624/4;
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3853
#endif
3854 3855 3856 3857 3858
   

   

  
Raymond Knopp's avatar
 
Raymond Knopp committed
3859
    // replace RX signal buffers with mmaped HW versions
3860
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3861 3862 3863
    openair0_cfg[CC_id].tx_num_channels = 0;
    openair0_cfg[CC_id].rx_num_channels = 0;

3864 3865 3866 3867 3868 3869 3870 3871 3872 3873
    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];
3874
	openair0_cfg[rf_map[CC_id].card].rx_gain[rf_map[CC_id].chain+i] = rx_gain[CC_id][i];
3875 3876 3877
	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
3878
      for (j=0;j<16;j++) {
3879 3880
	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;
3881
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3882
    }
3883 3884 3885 3886 3887 3888 3889 3890 3891 3892
    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];
3893
	openair0_cfg[rf_map[CC_id].card].tx_gain[rf_map[CC_id].chain+i] = tx_gain[CC_id][i];
3894 3895 3896 3897
	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
3898
      for (j=0;j<16;j++) {
3899 3900
	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;
3901
      }
3902
    }
3903
#else // not EXMIMO
3904 3905 3906
    rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*));
    txdata = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));

3907 3908
    for (i=0;i<frame_parms->nb_antennas_rx;i++) {
      free(phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i]);
Raymond Knopp's avatar
 
Raymond Knopp committed
3909
      rxdata[i] = (int32_t*)(16 + malloc16(16+samples_per_frame*sizeof(int32_t)));
3910 3911 3912
      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
3913
    }
3914 3915
    for (i=0;i<frame_parms->nb_antennas_tx;i++) {
      free(phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i]);
Raymond Knopp's avatar
 
Raymond Knopp committed
3916
      txdata[i] = (int32_t*)(16 + malloc16(16+samples_per_frame*sizeof(int32_t)));
3917 3918
      phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i] = txdata[i];
      memset(txdata[i], 0, samples_per_frame*sizeof(int32_t));
3919
      printf("txdata[%d] @ %p\n", i, phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i]);
3920

Raymond Knopp's avatar
 
Raymond Knopp committed
3921 3922
    }
#endif
3923
  }
3924
  return(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
3925
}
3926

3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945
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);
  }
}