lte-softmodem.c 120 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 51 52 53 54 55
#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>
#include <signal.h>
#include <execinfo.h>
#include <getopt.h>

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

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

62
#include "assertions.h"
63 64 65 66 67 68

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

#include "PHY/types.h"
69

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

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

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

#include "PHY/vars.h"
#include "MAC_INTERFACE/vars.h"
84
//#include "SCHED/defs.h"
85 86 87 88 89 90 91 92 93 94
#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
95
#include "otg_tx.h"
96 97
#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/vars.h"
98
#include "LAYER2/MAC/proto.h"
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
#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"
#include "UTIL/OTG/otg.h"
#include "UTIL/OTG/otg_vars.h"
#include "UTIL/MATH/oml.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
114
#include "enb_config.h"
115

116 117
#if defined(ENABLE_ITTI)
# include "intertask_interface_init.h"
118
# include "create_tasks.h"
119 120 121
# if defined(ENABLE_USE_MME)
#   include "s1ap_eNB.h"
# endif
122 123
#endif

124 125 126
#ifdef XFORMS
#include "PHY/TOOLS/lte_phy_scope.h"
#include "stats.h"
127 128 129 130 131
#endif

#define FRAME_PERIOD    100000000ULL
#define DAQ_PERIOD      66667ULL

Raymond Knopp's avatar
 
Raymond Knopp committed
132
#define DEBUG_THREADS 1
Raymond Knopp's avatar
 
Raymond Knopp committed
133

Raymond Knopp's avatar
 
Raymond Knopp committed
134 135
//#define USRP_DEBUG 1

136 137 138 139 140 141 142
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;

143 144
extern int16_t* sync_corr_ue0;
extern int16_t prach_ifft[4][1024*2];
145 146 147

int init_dlsch_threads(void);
void cleanup_dlsch_threads(void);
148
int32_t init_rx_pdsch_thread(void);
149
void cleanup_rx_pdsch_thread(void);
Raymond Knopp's avatar
 
Raymond Knopp committed
150

151
openair0_config_t openair0_cfg[MAX_CARDS];
Raymond Knopp's avatar
 
Raymond Knopp committed
152

Raymond Knopp's avatar
 
Raymond Knopp committed
153 154
int32_t **rxdata;
int32_t **txdata;
155 156
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]);
157 158

#ifdef XFORMS
159 160 161 162
// 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];
163
FD_stats_form                  *form_stats=NULL,*form_stats_l2=NULL;
164
char title[255];
165
unsigned char                   scope_enb_num_ue = 1;
166 167 168
#endif //XFORMS

#ifdef RTAI
169
static SEM                     *mutex;
170 171
//static CND *cond;

172 173
static long                      main_eNB_thread;
static long                      main_ue_thread;
Raymond Knopp's avatar
 
Raymond Knopp committed
174
static SEM *sync_sem; // to sync rx & tx streaming
175

176 177
//static int sync_thread;
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
178 179
pthread_t                       main_eNB_thread;
pthread_t                       main_ue_thread;
180 181
pthread_attr_t                  attr_dlsch_threads;
struct sched_param              sched_param_dlsch;
Raymond Knopp's avatar
 
Raymond Knopp committed
182

Raymond Knopp's avatar
 
Raymond Knopp committed
183 184
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
185
int sync_var=-1;
186
#endif
187

Raymond Knopp's avatar
 
Raymond Knopp committed
188
RTIME T0;
189

Raymond Knopp's avatar
 
Raymond Knopp committed
190 191 192
pthread_attr_t                  attr_UE_init_synch;
pthread_attr_t                  attr_UE_thread_tx;
pthread_attr_t                  attr_UE_thread_rx;
Raymond Knopp's avatar
 
Raymond Knopp committed
193 194
pthread_attr_t                  attr_eNB_proc_tx[MAX_NUM_CCs][10];
pthread_attr_t                  attr_eNB_proc_rx[MAX_NUM_CCs][10];
Raymond Knopp's avatar
 
Raymond Knopp committed
195 196 197
struct sched_param              sched_param_UE_init_synch;
struct sched_param              sched_param_UE_thread_tx;
struct sched_param              sched_param_UE_thread_rx;
Raymond Knopp's avatar
 
Raymond Knopp committed
198 199
struct sched_param              sched_param_eNB_proc_tx[MAX_NUM_CCs][10];
struct sched_param              sched_param_eNB_proc_rx[MAX_NUM_CCs][10];
Raymond Knopp's avatar
 
Raymond Knopp committed
200

201
#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
202
static pthread_t                forms_thread; //xforms
203 204 205 206
#endif
#ifdef EMOS
static pthread_t                thread3; //emos
#endif
207

208 209 210 211
#ifdef SPECTRA
static pthread_t sensing_thread;
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
212 213 214
openair0_device openair0;
openair0_timestamp timestamp;

215
/*
Raymond Knopp's avatar
 
Raymond Knopp committed
216 217 218
  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;
219 220 221 222
*/
//extern unsigned int bigphys_top;
//extern unsigned int mem_base;

223
int                             card = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
224

225

226
#if defined(ENABLE_ITTI)
227 228
static volatile int             start_eNB = 0;
static volatile int             start_UE = 0;
229
#endif
230 231 232 233 234 235
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
236

237
static char                     UE_flag=0;
238
static uint8_t                  eNB_id=0,UE_id=0;
239

240
//uint32_t                        carrier_freq[MAX_NUM_CCs][4] =           {{1907600000,1907600000,1907600000,1907600000}}; /* For UE! */
241 242 243
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}};
244 245

openair0_rf_map rf_map[MAX_NUM_CCs];
246

247
static char                    *conf_config_file_name = NULL;
248
#if defined(ENABLE_ITTI)
249
static char                    *itti_dump_file = NULL;
Raymond Knopp's avatar
 
Raymond Knopp committed
250 251
#endif

Lionel Gauthier's avatar
Lionel Gauthier committed
252
#ifndef USRP
253 254
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}};
255
// these are for EXMIMO2 target only
256
/*
257 258 259
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};
260 261 262 263 264 265 266 267
*/
// 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};
268
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
269
#else
270
double tx_gain[MAX_NUM_CCs][4] = {{120,0,0,0}};
Raymond Knopp's avatar
 
Raymond Knopp committed
271
double rx_gain[MAX_NUM_CCs][4] = {{125,0,0,0}};
Lionel Gauthier's avatar
Lionel Gauthier committed
272
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
273

Raymond Knopp's avatar
 
Raymond Knopp committed
274 275
double sample_rate=30.72e6;
double bw = 14e6;
276

277
static int                      tx_max_power[MAX_NUM_CCs] =  {0,0};
278

279
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
280 281 282
char ref[128] = "internal";
char channels[128] = "0";

Raymond Knopp's avatar
 
Raymond Knopp committed
283 284 285
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
286

Raymond Knopp's avatar
 
Raymond Knopp committed
287 288 289
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
290
int sf_bounds_10[10] = {8, 15, 23, 30, 38, 45, 53, 60, 68, 75};
Raymond Knopp's avatar
 
Raymond Knopp committed
291 292
int sf_bounds_10_tx[10] = {4, 11, 19, 26, 34, 41, 49, 56, 64, 71};

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

Raymond Knopp's avatar
 
Raymond Knopp committed
296
int *sf_bounds;
Raymond Knopp's avatar
 
Raymond Knopp committed
297 298
int *sf_bounds_tx;

Raymond Knopp's avatar
 
Raymond Knopp committed
299 300 301 302
int max_cnt;
int tx_delay;

#endif
303
/*
Raymond Knopp's avatar
 
Raymond Knopp committed
304 305 306
  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};
307
*/
Raymond Knopp's avatar
 
Raymond Knopp committed
308 309
//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
310 311
//{8254617, 8254617, 8254617, 8254617}; //eNB khalifa
//{8255067,8254810,8257340,8257340}; // eNB PETRONAS
312

Raymond Knopp's avatar
 
Raymond Knopp committed
313 314 315 316 317
//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};
318 319 320

static runmode_t                mode;
static int                      rx_input_level_dBm;
321
static int                      online_log_messages=0;
322
#ifdef XFORMS
323
extern int                      otg_enabled;
324
static char                     do_forms=0;
325
#else
326
int                             otg_enabled;
327
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
328
//int                             number_of_cards =   1;
Raymond Knopp's avatar
 
Raymond Knopp committed
329
#ifndef USRP
330 331
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
332
#endif
333

Raymond Knopp's avatar
 
Raymond Knopp committed
334
static LTE_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
335

Raymond Knopp's avatar
 
Raymond Knopp committed
336
int multi_thread=1;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
337
uint32_t target_dl_mcs = 28; //maximum allowed mcs
338
uint32_t target_ul_mcs = 10;
339

340
int transmission_mode=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
341

Lionel Gauthier's avatar
 
Lionel Gauthier committed
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
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
362

363
unsigned int build_rflocal(int txi, int txq, int rxi, int rxq)
364
{
Raymond Knopp's avatar
 
Raymond Knopp committed
365
  return (txi + (txq<<6) + (rxi<<12) + (rxq<<18));
366 367 368
}
unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
369
  return (dcoff_i_rxfe + (dcoff_q_rxfe<<8));
370 371
}

372
#if !defined(ENABLE_ITTI)
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
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 {
388
    printf("trying to exit gracefully...\n"); 
389
    oai_exit = 1;
390 391
  }
}
392
#endif
393 394 395

void exit_fun(const char* s)
{
396
  if (s != NULL) {
Lionel Gauthier's avatar
Lionel Gauthier committed
397
    printf("%s %s() Exiting: %s\n",__FILE__, __FUNCTION__, s);
398 399 400 401 402
  }

  oai_exit = 1;

#if defined(ENABLE_ITTI)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
403
  sleep(1); //allow lte-softmodem threads to exit first
404
  itti_terminate_tasks (TASK_UNKNOWN);
405
#endif
406 407 408 409 410 411

  //rt_sleep_ns(FRAME_PERIOD);

  //exit (-1);
}

Raymond Knopp's avatar
 
Raymond Knopp committed
412 413 414
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
415 416 417 418 419 420 421 422 423
 * 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
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
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
441
 
442
#ifdef XFORMS
443 444 445 446

void reset_stats(FL_OBJECT *button, long arg) {
  int i,j,k;
  PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[0][0];
447 448 449 450 451 452 453 454 455 456 457 458
  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;
459 460 461
      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;
462
      }
463
    }
464 465 466
    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;
467 468 469
  }
}

470
static void *scope_thread(void *arg) {
Raymond Knopp's avatar
 
Raymond Knopp committed
471
  char stats_buffer[16384];
472
# ifdef ENABLE_XFORMS_WRITE_STATS
Raymond Knopp's avatar
 
Raymond Knopp committed
473 474
  FILE *UE_stats, *eNB_stats;
  int len = 0;
475
# endif
Raymond Knopp's avatar
 
Raymond Knopp committed
476
  struct sched_param sched_param;
477

Raymond Knopp's avatar
 
Raymond Knopp committed
478 479
  sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1; 
  sched_setscheduler(0, SCHED_FIFO,&sched_param);
480

Raymond Knopp's avatar
 
Raymond Knopp committed
481
  printf("Scope thread has priority %d\n",sched_param.sched_priority);
482
    
483 484
# ifdef ENABLE_XFORMS_WRITE_STATS
  if (UE_flag==1) 
Raymond Knopp's avatar
 
Raymond Knopp committed
485
    UE_stats  = fopen("UE_stats.txt", "w");
486
  else 
Raymond Knopp's avatar
 
Raymond Knopp committed
487
    eNB_stats = fopen("eNB_stats.txt", "w");
488
#endif
489
    
Raymond Knopp's avatar
 
Raymond Knopp committed
490 491
  while (!oai_exit) {
    if (UE_flag==1) {
492
# ifdef ENABLE_XFORMS_WRITE_STATS
Raymond Knopp's avatar
 
Raymond Knopp committed
493
      len =
494
# endif
495
	dump_ue_stats (PHY_vars_UE_g[0][0], stats_buffer, 0, mode,rx_input_level_dBm);
Raymond Knopp's avatar
 
Raymond Knopp committed
496
      fl_set_object_label(form_stats->stats_text, stats_buffer);
497

Raymond Knopp's avatar
 
Raymond Knopp committed
498
      phy_scope_UE(form_ue[UE_id], 
499
		   PHY_vars_UE_g[UE_id][0],
Raymond Knopp's avatar
 
Raymond Knopp committed
500 501
		   eNB_id,
		   UE_id,7);
502
            
Raymond Knopp's avatar
 
Raymond Knopp committed
503
    } else {
504
# ifdef ENABLE_XFORMS_WRITE_STATS
Raymond Knopp's avatar
 
Raymond Knopp committed
505
      len =
506
# endif
507 508
      dump_eNB_l2_stats (stats_buffer, 0);
      fl_set_object_label(form_stats_l2->stats_text, stats_buffer);
509 510 511 512 513 514 515

# 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
516 517
      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
518
		      PHY_vars_eNB_g[eNB_id][0],
Raymond Knopp's avatar
 
Raymond Knopp committed
519 520
		      UE_id);
      }
521 522
              
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
523
    //printf("doing forms\n");
Florian Kaltenberger's avatar
Florian Kaltenberger committed
524 525
    //usleep(100000); // 100 ms
    sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
526
  }
527 528

  printf("%s",stats_buffer);
529
    
530
# ifdef ENABLE_XFORMS_WRITE_STATS
531 532 533 534 535 536 537 538 539 540 541 542 543 544
  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);
    }
  }
545
# endif
546
    
Raymond Knopp's avatar
 
Raymond Knopp committed
547
  pthread_exit((void*)arg);
548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572
}
#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;
573 574 575 576 577 578 579

  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);
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601
 
  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);
    }
602 603
  else 
    printf("[EMOS] Opened GPS, gps_data=%p\n");
604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648
  
  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
649
	if (UE_flag==0)
650
	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
651
	else
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 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712
	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

713 714 715 716 717 718 719 720 721 722 723 724 725
#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) {

    
726 727 728
    openair0_cfg[0].rx_freq[2]+= 5e6;
    if (openair0_cfg[0].rx_freq[2] >= 750000000)
      openair0_cfg[0].rx_freq[2] = 727500000;
729 730
    

731
    //LOG_I(HW,"[SPECTRA] changing frequency to %u \n",(uint32_t)openair0_cfg[1].rx_freq[0]);
732 733 734

    openair0_reconfig(&openair0_cfg[0]);

735
    usleep(200000);
736 737 738 739 740 741 742 743 744 745
    //sleep(1);
    
  }

  pthread_exit((void*) arg);

}
#endif


746
#if defined(ENABLE_ITTI)
747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764
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
765
#if defined(ENABLE_ITTI)
766
void *l2l1_task(void *arg)
767
{
Raymond Knopp's avatar
 
Raymond Knopp committed
768 769 770 771 772
  MessageDef *message_p = NULL;
  int         result;

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
773

Raymond Knopp's avatar
 
Raymond Knopp committed
774 775
  if (UE_flag == 0) {
    /* Wait for the initialize message */
776
    do {
Raymond Knopp's avatar
 
Raymond Knopp committed
777 778 779 780
      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);
      }
781 782 783
      itti_receive_msg (TASK_L2L1, &message_p);

      switch (ITTI_MSG_ID(message_p)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
784 785 786 787 788 789 790 791 792 793 794 795 796 797
      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;
798
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820
    } 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;
821

Raymond Knopp's avatar
 
Raymond Knopp committed
822 823 824 825 826 827 828 829 830 831 832 833
    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);
834

Raymond Knopp's avatar
 
Raymond Knopp committed
835
  return NULL;
836 837 838
}
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
839

Raymond Knopp's avatar
 
Raymond Knopp committed
840
void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) {
Raymond Knopp's avatar
 
Raymond Knopp committed
841 842 843 844

  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
845
  int slot_sizeF = (phy_vars_eNB->lte_frame_parms.ofdm_symbol_size)*
Raymond Knopp's avatar
 
Raymond Knopp committed
846
    ((phy_vars_eNB->lte_frame_parms.Ncp==1) ? 6 : 7);
Raymond Knopp's avatar
 
Raymond Knopp committed
847 848 849

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
856
    
Raymond Knopp's avatar
 
Raymond Knopp committed
857 858 859 860 861 862 863 864 865 866
    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
867 868 869 870 871 872 873 874
	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
875 876 877 878 879 880
      }
      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
881 882 883 884
	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
885
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
886 887

      for (i=0; i<phy_vars_eNB->lte_frame_parms.samples_per_tti; i++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904
	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
905 906 907

  //unsigned long cpuid;
  eNB_proc_t *proc = (eNB_proc_t*)param;
Raymond Knopp's avatar
 
Raymond Knopp committed
908
  //  RTIME time_in,time_out;
Raymond Knopp's avatar
 
Raymond Knopp committed
909 910
#ifdef RTAI
  RT_TASK *task;
911
  char task_name[8];
Raymond Knopp's avatar
 
Raymond Knopp committed
912
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
913 914

 
Florian Kaltenberger's avatar
Florian Kaltenberger committed
915 916
/*#if defined(ENABLE_ITTI)
  // Wait for eNB application initialization to be complete (eNB registration to MME)
Raymond Knopp's avatar
 
Raymond Knopp committed
917
  wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
918
#endif*/
Raymond Knopp's avatar
 
Raymond Knopp committed
919

Raymond Knopp's avatar
 
Raymond Knopp committed
920
#ifdef RTAI
921
  sprintf(task_name,"TXC%dS%d",proc->CC_id,proc->subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
922 923 924
  task = rt_task_init_schmod(nam2num(task_name), 0, 0, 0, SCHED_FIFO, 0xF);

  if (task==NULL) {
Raymond Knopp's avatar
 
Raymond Knopp committed
925
    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
926 927 928
    return 0;
  }
  else {
929 930
    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
931
	  proc->subframe,
932
	  task);
Raymond Knopp's avatar
 
Raymond Knopp committed
933
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
934
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
935
  //  LOG_I(PHY,
Raymond Knopp's avatar
 
Raymond Knopp committed
936 937
  printf("[SCHED][eNB] eNB TX thread %d started on CPU %d\n",
	 proc->subframe,sched_getcpu());
Raymond Knopp's avatar
 
Raymond Knopp committed
938 939 940 941 942 943 944 945 946 947 948 949
#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
950
    
Raymond Knopp's avatar
 
Raymond Knopp committed
951
    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
952 953
    
    
Raymond Knopp's avatar
 
Raymond Knopp committed
954 955
    //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
956

Raymond Knopp's avatar
 
Raymond Knopp committed
957 958
    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
959
      oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
960 961
    }
    else {
Raymond Knopp's avatar
 
Raymond Knopp committed
962
      
Raymond Knopp's avatar
 
Raymond Knopp committed
963 964
      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
965
	//printf("Waiting and unlocking mutex for eNB proc %d (subframe_tx %d)\n",proc->subframe,subframe_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
966
	
Raymond Knopp's avatar
 
Raymond Knopp committed
967
	pthread_cond_wait(&proc->cond_tx,&proc->mutex_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
968
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
969 970 971
      //      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
972
	oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
973 974
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
975
    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
976
    vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB, proc->frame_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
977
    
Raymond Knopp's avatar
 
Raymond Knopp committed
978
    if (oai_exit) break;
Raymond Knopp's avatar
 
Raymond Knopp committed
979

Raymond Knopp's avatar
 
Raymond Knopp committed
980 981 982 983 984 985 986
    
    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
987
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
988 989
    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
990
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
991
    
Raymond Knopp's avatar
 
Raymond Knopp committed
992
    
Raymond Knopp's avatar
 
Raymond Knopp committed
993
    do_OFDM_mod_rt(proc->subframe_tx,PHY_vars_eNB_g[0][proc->CC_id]);  
Raymond Knopp's avatar
 
Raymond Knopp committed
994
    
Raymond Knopp's avatar
 
Raymond Knopp committed
995 996
    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
997
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
998 999
    else {
      proc->instance_cnt_tx--;
Raymond Knopp's avatar
 
Raymond Knopp committed
1000
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1001 1002 1003 1004
      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
1005

Raymond Knopp's avatar
 
Raymond Knopp committed
1006
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1007 1008 1009
    proc->frame_tx++;
    if (proc->frame_tx==1024)
      proc->frame_tx=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1010

Raymond Knopp's avatar
 
Raymond Knopp committed
1011
  }    
Raymond Knopp's avatar
 
Raymond Knopp committed
1012 1013 1014 1015
  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
1016
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1017 1018 1019 1020 1021 1022 1023 1024 1025 1026
#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
1027
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040
#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;
1041
  char task_name[8];
Raymond Knopp's avatar
 
Raymond Knopp committed
1042 1043
#endif

Florian Kaltenberger's avatar
Florian Kaltenberger committed
1044 1045
/*#if defined(ENABLE_ITTI)
  // Wait for eNB application initialization to be complete (eNB registration to MME) 
Raymond Knopp's avatar
 
Raymond Knopp committed
1046
  wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1047
#endif*/
Raymond Knopp's avatar
 
Raymond Knopp committed
1048 1049

#ifdef RTAI
1050
  sprintf(task_name,"RXC%1dS%1d",proc->CC_id,proc->subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
1051 1052 1053 1054 1055 1056 1057
  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 {
1058 1059
    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
1060
	  proc->subframe,
1061
	  task); /*,rtai_cpuid()*/
Raymond Knopp's avatar
 
Raymond Knopp committed
1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079
  }
#else
  LOG_I(PHY,"[SCHED][eNB] eNB RX thread %d started on CPU %d\n",
	proc->subframe,sched_getcpu());
#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
1080
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090
    //    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
1091
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1092 1093 1094
      //      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
1095 1096
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1097
    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
1098
    vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, proc->frame_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1099 1100 1101

    if (oai_exit) break;
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1102 1103 1104
    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
1105
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1106 1107
    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
1108 1109 1110 1111
    }
      
    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
1112 1113
    }
    else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1114
      proc->instance_cnt_rx--;
Raymond Knopp's avatar
 
Raymond Knopp committed
1115
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1116 1117
      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
1118 1119
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1120 1121 1122 1123

    proc->frame_rx++;
    if (proc->frame_rx==1024)
      proc->frame_rx=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1124
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1125 1126
  }
  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
1127
#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139
  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
1140 1141
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1142 1143 1144
#ifdef DEBUG_THREADS
  printf("Exiting eNB RX thread %d\n",proc->subframe);
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1145 1146 1147 1148
}



Raymond Knopp's avatar
 
Raymond Knopp committed
1149

1150
void init_eNB_proc(void) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1151 1152

  int i;
Raymond Knopp's avatar
 
Raymond Knopp committed
1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170
  int CC_id;

  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    for (i=0;i<10;i++) {
      pthread_attr_init (&attr_eNB_proc_tx[CC_id][i]);
      pthread_attr_setstacksize(&attr_eNB_proc_tx[CC_id][i],OPENAIR_THREAD_STACK_SIZE);
      //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);
      
      pthread_attr_init (&attr_eNB_proc_rx[CC_id][i]);
      pthread_attr_setstacksize(&attr_eNB_proc_rx[CC_id][i],OPENAIR_THREAD_STACK_SIZE);
      //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);
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182
      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;
1183
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1184 1185
      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
1186
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1187 1188
      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
1189
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1190 1191 1192
    }
  
  
1193
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1194 1195
    // 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
1196
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1197
    //PHY_vars_eNB_g[0][CC_id]->proc[0].frame_rx = 1023;
Raymond Knopp's avatar
 
Raymond Knopp committed
1198 1199
    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
1200
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1201 1202
    // 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
1203
    //    PHY_vars_eNB_g[0][CC_id]->proc[7].frame_tx = 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1204 1205
    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
1206
    //    PHY_vars_eNB_g[0][CC_id]->proc[0].frame_tx = 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1207
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1208 1209
  }
}
Raymond Knopp's avatar
 
Raymond Knopp committed
1210

1211
void kill_eNB_proc(void) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1212 1213

  int i;
Raymond Knopp's avatar
 
Raymond Knopp committed
1214
  int *status_tx,*status_rx;
Raymond Knopp's avatar
 
Raymond Knopp committed
1215
  int CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1216

Raymond Knopp's avatar
 
Raymond Knopp committed
1217 1218 1219
  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) 
    for (i=0;i<10;i++) {
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1220
#ifdef DEBUG_THREADS
Raymond Knopp's avatar
 
Raymond Knopp committed
1221
      printf("Killing TX CC_id %d thread %d\n",CC_id,i);
Raymond Knopp's avatar
 
Raymond Knopp committed
1222
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1223 1224
      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
1225
#ifdef DEBUG_THREADS
1226
      printf("Joining eNB TX CC_id %d thread %d...\n",CC_id,i);
Raymond Knopp's avatar
 
Raymond Knopp committed
1227
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1228
      pthread_join(PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_tx,(void**)status_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1229
#ifdef DEBUG_THREADS
1230
      if (status_tx) printf("status %d...\n",*status_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1231 1232
#endif
#ifdef DEBUG_THREADS
Raymond Knopp's avatar
 
Raymond Knopp committed
1233
      printf("Killing RX CC_id %d thread %d\n",CC_id,i);
Raymond Knopp's avatar
 
Raymond Knopp committed
1234
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1235 1236
      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
1237
#ifdef DEBUG_THREADS
1238
      printf("Joining eNB RX CC_id %d thread %d...\n",CC_id,i);
Raymond Knopp's avatar
 
Raymond Knopp committed
1239
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1240
      pthread_join(PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_rx,(void**)status_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1241
#ifdef DEBUG_THREADS 
1242
      if (status_rx) printf("status %d...\n",*status_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1243
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1244 1245 1246 1247 1248
      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
1249 1250 1251
}


Raymond Knopp's avatar
 
Raymond Knopp committed
1252 1253


Raymond Knopp's avatar
 
Raymond Knopp committed
1254 1255
  
/* This is the main eNB thread. */
Raymond Knopp's avatar
 
Raymond Knopp committed
1256 1257
int eNB_thread_status;

Raymond Knopp's avatar
 
Raymond Knopp committed
1258

Raymond Knopp's avatar
 
Raymond Knopp committed
1259

1260 1261 1262 1263 1264
static void *eNB_thread(void *arg)
{
#ifdef RTAI
  RT_TASK *task;
#endif
1265 1266
#ifdef EXMIMO
  unsigned char slot=0;
1267 1268
#else
  unsigned char slot=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1269
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1270
  int frame=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1271
  int CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1272

1273
  RTIME time_in, time_diff;
Raymond Knopp's avatar
 
Raymond Knopp committed
1274

Raymond Knopp's avatar
 
Raymond Knopp committed
1275
  int sf;
1276
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1277
  volatile unsigned int *DAQ_MBOX = openair0_daq_cnt();
Raymond Knopp's avatar
 
Raymond Knopp committed
1278 1279
  int mbox_target=0,mbox_current=0;
  int hw_slot,delay_cnt;
Raymond Knopp's avatar
 
Raymond Knopp committed
1280 1281
  int diff;
  int ret;
1282
  int first_run=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1283
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1284 1285
  unsigned int rx_cnt = 0;
  unsigned int tx_cnt = tx_delay;
Raymond Knopp's avatar
 
Raymond Knopp committed
1286
  //  int tx_offset;
Raymond Knopp's avatar
 
Raymond Knopp committed
1287 1288
  void *rxp[2],*txp[2];
  int i;
Raymond Knopp's avatar
 
Raymond Knopp committed
1289

Raymond Knopp's avatar
 
Raymond Knopp committed
1290
  hw_subframe = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1291
#endif
1292

1293
  /*
1294
#if defined(ENABLE_ITTI)
1295
  // Wait for eNB application initialization to be complete (eNB registration to MME) 
1296
  wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
1297
#endif
1298
  */
1299

1300
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
1301
  task = rt_task_init_schmod(nam2num("TASK0"), 0, 0, 0, SCHED_FIFO, 0xF);
1302 1303 1304 1305
#endif

  if (!oai_exit) {
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
1306
    printf("[SCHED][eNB] Started eNB thread (id %p)\n",task);
Raymond Knopp's avatar
 
Raymond Knopp committed
1307
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1308 1309
    printf("[SCHED][eNB] Started eNB thread on CPU %d\n",
	   sched_getcpu());
1310 1311 1312
#endif

#ifdef HARD_RT
1313
    rt_make_hard_real_time();
1314 1315
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1316
    printf("eNB_thread: mlockall in ...\n");
1317
    mlockall(MCL_CURRENT | MCL_FUTURE);
Raymond Knopp's avatar
 
Raymond Knopp committed
1318
    printf("eNB_thread: mlockall out ...\n");
1319

1320 1321 1322 1323
    timing_info.time_min = 100000000ULL;
    timing_info.time_max = 0;
    timing_info.time_avg = 0;
    timing_info.n_samples = 0;
1324

1325
    printf("waiting for sync (eNB_thread)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1326 1327 1328
#ifdef RTAI
    rt_sem_wait(sync_sem);
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1329
    pthread_mutex_lock(&sync_mutex);
1330 1331
    while (sync_var<0)
      pthread_cond_wait(&sync_cond, &sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
1332
    pthread_mutex_unlock(&sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
1333 1334 1335
#endif
    //    printf("starting eNB thread @ %llu\n",get_usrp_time(&openair0));

Raymond Knopp's avatar
 
Raymond Knopp committed
1336
    while (!oai_exit) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1337

1338
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1339 1340
      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
1341 1342
      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
1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354
      //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;
      
1355 1356 1357 1358 1359
      //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;
1360
	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);
1361 1362
      } 

Raymond Knopp's avatar
 
Raymond Knopp committed
1363 1364
      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
1365
	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
1366
	slot++;
1367 1368
	//if (frame > 0)
	exit_fun("[HW][eNB] missed slot");
Raymond Knopp's avatar
 
Raymond Knopp committed
1369 1370 1371 1372
      }
      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
1373
      vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *DAQ_MBOX);
Raymond Knopp's avatar
 
Raymond Knopp committed
1374 1375 1376 1377 1378 1379 1380 1381 1382 1383
      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
1384
	vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *DAQ_MBOX);
Raymond Knopp's avatar
 
Raymond Knopp committed
1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395
	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) {
	  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
1396
	  diff = 150-mbox_current+mbox_target;
Raymond Knopp's avatar
 
Raymond Knopp committed
1397
	else if ((mbox_current<15) && (mbox_target>=135))
Raymond Knopp's avatar
 
Raymond Knopp committed
1398
	  diff = -150+mbox_target-mbox_current;
Raymond Knopp's avatar
 
Raymond Knopp committed
1399
	else
Raymond Knopp's avatar
 
Raymond Knopp committed
1400
	  diff = mbox_target - mbox_current;
Raymond Knopp's avatar
 
Raymond Knopp committed
1401
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1402

1403
#else  // EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1404 1405
      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
1406 1407
      while (rx_cnt < sf_bounds[hw_subframe]) {

Raymond Knopp's avatar
 
Raymond Knopp committed
1408 1409
	openair0_timestamp time0,time1;
	unsigned int rxs;
Raymond Knopp's avatar
 
Raymond Knopp committed
1410
#ifndef USRP_DEBUG
Raymond Knopp's avatar
 
Raymond Knopp committed
1411
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1412

Raymond Knopp's avatar
 
Raymond Knopp committed
1413 1414
	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);
1415

1416
	//	printf("hw_subframe %d: rx_cnt %d\n",hw_subframe,rx_cnt);
Raymond Knopp's avatar
 
Raymond Knopp committed
1417 1418 1419 1420

	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];

Raymond Knopp's avatar
 
Raymond Knopp committed
1421 1422
	rxs = openair0.trx_read_func(&openair0, 
				     &timestamp, 
Raymond Knopp's avatar
 
Raymond Knopp committed
1423 1424 1425
				     rxp, 
				     samples_per_packets,
				     PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_rx);
1426

Raymond Knopp's avatar
 
Raymond Knopp committed
1427 1428
	if (rxs != samples_per_packets)
	  oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1429
 
1430
	//	printf("hw_subframe %d: tx_cnt %d\n",hw_subframe,tx_cnt);
Raymond Knopp's avatar
 
Raymond Knopp committed
1431

Raymond Knopp's avatar
 
Raymond Knopp committed
1432 1433
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,0);

Raymond Knopp's avatar
 
Raymond Knopp committed
1434
	// Transmit TX buffer based on timestamp from RX
Raymond Knopp's avatar
 
Raymond Knopp committed
1435
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1436 1437 1438
	
	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
1439 1440
	openair0.trx_write_func(&openair0, 
				(timestamp+samples_per_packets*tx_delay-tx_forward_nsamps), 
Raymond Knopp's avatar
 
Raymond Knopp committed
1441
				txp,
Raymond Knopp's avatar
 
Raymond Knopp committed
1442
				samples_per_packets, 
Raymond Knopp's avatar
 
Raymond Knopp committed
1443
				PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_tx,
Raymond Knopp's avatar
 
Raymond Knopp committed
1444
				1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1445 1446

	
Raymond Knopp's avatar
 
Raymond Knopp committed
1447
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1448 1449 1450 1451 1452 1453 1454 1455 1456
#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
1457
	      //	      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
1458 1459 1460 1461 1462 1463 1464 1465
	      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
1466
		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
1467 1468 1469 1470 1471
		oai_exit=1;
	      }
	    }
	  }
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
1472 1473
	rx_cnt++;
	tx_cnt++;
Raymond Knopp's avatar
 
Raymond Knopp committed
1474 1475 1476

	if(tx_cnt == max_cnt)
	  tx_cnt = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1477 1478
      }

Raymond Knopp's avatar
 
Raymond Knopp committed
1479 1480
      if(rx_cnt == max_cnt)
	rx_cnt = 0; 
Raymond Knopp's avatar
 
Raymond Knopp committed
1481
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1482 1483 1484

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1487

Raymond Knopp's avatar
 
Raymond Knopp committed
1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508
      
      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
1509
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
1510 1511
      */
      //}
1512
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1513
      if ((slot&1) == 1) {
1514
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1515 1516 1517 1518 1519
	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
1520
	
Raymond Knopp's avatar
 
Raymond Knopp committed
1521
	for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
1522
#ifdef EXMIMO 
Raymond Knopp's avatar
 
Raymond Knopp committed
1523 1524
	  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
1525
	  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1526 1527 1528 1529 1530 1531 1532
	  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);
1533
	      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1534 1535 1536 1537 1538
	    }
	    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
1539
	  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550
#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
1551
	      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1552 1553 1554 1555
	    }
	    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
1556
	    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1557
	  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1558
	    
Raymond Knopp's avatar
 
Raymond Knopp committed
1559 1560
	}
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1561 1562
	  
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1563 1564 1565 1566 1567 1568 1569
#ifndef RTAI
      //pthread_mutex_lock(&tti_mutex);
#endif




Raymond Knopp's avatar
 
Raymond Knopp committed
1570
#ifndef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
1571
      slot++;
Raymond Knopp's avatar
 
Raymond Knopp committed
1572 1573 1574 1575
      if (slot == 20) {
	frame++;
	slot = 0;
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1576
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1577 1578 1579
      hw_subframe++;
      slot+=2;
      if(hw_subframe==10) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1580
	hw_subframe = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1581
	frame++;
Raymond Knopp's avatar
 
Raymond Knopp committed
1582
	slot = 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1583
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1584
#endif     
Raymond Knopp's avatar
 
Raymond Knopp committed
1585 1586


1587
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1588
      itti_update_lte_time(frame, slot);
1589
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1590 1591 1592 1593 1594 1595
    }
  }
#ifdef DEBUG_THREADS
  printf("eNB_thread: finished, ran %d times.\n",frame);
#endif
  
1596
#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
1597
  rt_make_soft_real_time();
1598 1599
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1600 1601 1602 1603 1604

#ifdef DEBUG_THREADS
  printf("Exiting eNB_thread ...");
#endif
  // clean task
1605
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
1606 1607 1608 1609
  rt_task_delete(task);
#else
  eNB_thread_status = 0;
  pthread_exit(&eNB_thread_status);
1610
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1611 1612 1613 1614 1615
#ifdef DEBUG_THREADS
  printf("eNB_thread deleted. returning\n");
#endif
  return 0;
}
1616

Raymond Knopp's avatar
 
Raymond Knopp committed
1617 1618 1619
#ifdef USRP_DEBUG
int is_synchronized=1;
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1620
int is_synchronized=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1621
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1622 1623 1624

static void *UE_thread_synch(void *arg) {

1625
  int i,hw_slot_offset,CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1626 1627
  PHY_VARS_UE *UE = arg;

Raymond Knopp's avatar
 
Raymond Knopp committed
1628
  printf("UE_thread_sync in with PHY_vars_UE %p\n",arg);
Raymond Knopp's avatar
 
Raymond Knopp committed
1629
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
1630
  printf("waiting for USRP sync (UE_thread_synch) \n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1631 1632 1633
#ifdef RTAI
  rt_sem_wait(sync_sem);
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1634 1635 1636

  pthread_mutex_lock(&sync_mutex);
  printf("Locked sync_mutex, waiting (UE_sync_thread)\n");
1637 1638
  while (sync_var<0)
    pthread_cond_wait(&sync_cond, &sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
1639 1640
  pthread_mutex_unlock(&sync_mutex);
  printf("unlocked sync_mutex (UE_sync_thread)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1641
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1642
  printf("starting UE synch thread\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659
#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
1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675
    }  // 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
1676

Raymond Knopp's avatar
 
Raymond Knopp committed
1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690
      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
1691
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1692 1693 1694
      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
1695 1696
      }
      else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1697 1698 1699
	openair_daq_vars.freq_offset *= -1;
      }
      if (abs(openair_daq_vars.freq_offset) > 7500) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1700 1701
	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
1702 1703
      }
      else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1704 1705
	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
1706 1707 1708 1709
	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
1710
	    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
1711
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
1712 1713
#ifndef USRP_DEBUG
	    openair0_set_frequencies(&openair0,&openair0_cfg[0]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1714
	    //	    openair0_set_gains(&openair0,&openair0_cfg[0]);
Navid Nikaein's avatar
Navid Nikaein committed
1715
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1716
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1717
	  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735
	}

	//	    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
1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802
    
  }  // 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
1803
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1804
  PHY_VARS_UE *UE = (PHY_VARS_UE*)arg;
Raymond Knopp's avatar
 
Raymond Knopp committed
1805 1806
  int i;
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1807
  UE->instance_cnt_rx=-1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1808
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1809
  mlockall(MCL_CURRENT | MCL_FUTURE);
Raymond Knopp's avatar
 
Raymond Knopp committed
1810
  
1811
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1812 1813 1814 1815 1816 1817
  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");
1818 1819
  while (sync_var<0)
    pthread_cond_wait(&sync_cond, &sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
1820 1821 1822 1823
  pthread_mutex_unlock(&sync_mutex);
  printf("unlocked sync_mutex, waiting (UE_thread_rx)\n");
#endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1824

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1827 1828
  while (!oai_exit) { 
    printf("UE_thread_rx: locking UE RX mutex\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1829 1830 1831 1832 1833 1834
    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
1835
      printf("UE_thread_rx: unlocking UE RX mutex (IC %d)\n",UE->instance_cnt_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1836
      while (UE->instance_cnt_rx < 0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1837
	printf("Waiting for cond_rx (%p)\n",(void*)&UE->cond_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1838
	pthread_cond_wait(&UE->cond_rx,&UE->mutex_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1839
	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
1840 1841 1842 1843 1844
      }
      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
1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861
      
      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
1862
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1863 1864 1865 1866 1867 1868 1869
    }
    
    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
1870
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1871 1872 1873
      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
1874
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1875
    printf("UE_thread_rx done\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1876
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1877
       
Raymond Knopp's avatar
 
Raymond Knopp committed
1878 1879 1880
  return(0);
}

Raymond Knopp's avatar
 
Raymond Knopp committed
1881 1882 1883



1884
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1885 1886 1887 1888 1889
#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
1890

Raymond Knopp's avatar
 
Raymond Knopp committed
1891 1892 1893
  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
1894
  // unsigned int aa;
Raymond Knopp's avatar
 
Raymond Knopp committed
1895
  int dummy[2][samples_per_packets];
Raymond Knopp's avatar
 
Raymond Knopp committed
1896 1897 1898 1899 1900
  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
1901
  int i;
Raymond Knopp's avatar
 
Raymond Knopp committed
1902 1903 1904

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1907
  printf("waiting for USRP sync (UE_thread)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1908 1909 1910
#ifdef RTAI
  rt_sem_wait(sync_sem);
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1911 1912
  pthread_mutex_lock(&sync_mutex);
  printf("Locked sync_mutex, waiting (UE_thread)\n");
1913 1914
  while (sync_var<0)
    pthread_cond_wait(&sync_cond, &sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
1915 1916
  pthread_mutex_unlock(&sync_mutex);
  printf("unlocked sync_mutex, waiting (UE_thread)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1917
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1918 1919 1920 1921

  printf("starting UE thread\n");

  T0 = rt_get_time_ns();
Raymond Knopp's avatar
 
Raymond Knopp committed
1922 1923 1924
  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
1925

Raymond Knopp's avatar
 
Raymond Knopp committed
1926

Raymond Knopp's avatar
 
Raymond Knopp committed
1927
    while (rx_cnt < sf_bounds[hw_subframe]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1928
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1929
      vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1930 1931
  
#ifndef USRP_DEBUG
Raymond Knopp's avatar
 
Raymond Knopp committed
1932 1933 1934

      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
1935 1936
      rxs = openair0.trx_read_func(&openair0,
				   &timestamp,
Raymond Knopp's avatar
 
Raymond Knopp committed
1937 1938 1939
				   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
1940
      if (rxs != (samples_per_packets- ((rx_cnt==0) ? rx_off_diff : 0)))
Raymond Knopp's avatar
 
Raymond Knopp committed
1941
	oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1942 1943

      rx_off_diff = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1944 1945 1946
      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
1947
      if (tx_enabled) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1948
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1949 1950
	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
1951 1952
	openair0.trx_write_func(&openair0,
				(timestamp+samples_per_packets*tx_delay-tx_forward_nsamps),
Raymond Knopp's avatar
 
Raymond Knopp committed
1953
				txp,
Raymond Knopp's avatar
 
Raymond Knopp committed
1954
				samples_per_packets,
Raymond Knopp's avatar
 
Raymond Knopp committed
1955
				PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_tx,
Raymond Knopp's avatar
 
Raymond Knopp committed
1956
				1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1957
				
Raymond Knopp's avatar
 
Raymond Knopp committed
1958 1959
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,0);
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1960 1961 1962
#else
      rt_sleep_ns(10000000);
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1963 1964 1965 1966 1967 1968 1969 1970
      rx_cnt++;
      tx_cnt++;
      
      if(tx_cnt == max_cnt)
	tx_cnt = 0;
    }
    
    if(rx_cnt == max_cnt)
Raymond Knopp's avatar
 
Raymond Knopp committed
1971 1972 1973
      rx_cnt = 0;


Raymond Knopp's avatar
 
Raymond Knopp committed
1974
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1975
    if (is_synchronized==1)  {
Raymond Knopp's avatar
 
Raymond Knopp committed
1976 1977
      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
1978 1979 1980 1981 1982 1983 1984
      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
1985
 	  
Raymond Knopp's avatar
 
Raymond Knopp committed
1986 1987 1988 1989
	  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
1990
	    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
1991 1992 1993 1994 1995 1996 1997 1998 1999
	    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
2000
		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
2001 2002 2003 2004 2005 2006 2007 2008
		      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
2009 2010 2011
		      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
2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022
		      );
		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
2023 2024 2025
    }
    else {  // we are not yet synchronized
      
Raymond Knopp's avatar
 
Raymond Knopp committed
2026
      if ((hw_subframe == 9)&&(dummy_dump == 0)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2027
	// Wake up initial synch thread
Raymond Knopp's avatar
 
Raymond Knopp committed
2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047
	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
2048
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2049
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060
    /*
      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
2061 2062
      if (PHY_vars_UE_g[0][0]->instance_cnt_synch < 0) {
	if (is_synchronized == 1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2063
	  //	  openair0_set_gains(&openair0,&openair0_cfg[0]);
Raymond Knopp's avatar
 
Raymond Knopp committed
2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074
	  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
2075 2076
					 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
2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094
#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
2095 2096 2097 2098 2099 2100 2101
    }
    
#if defined(ENABLE_ITTI)
    itti_update_lte_time(frame, slot);
#endif
  }
}
2102
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2103

Raymond Knopp's avatar
 
Raymond Knopp committed
2104 2105


2106
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
2107 2108
/* 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) {
2109
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2110 2111 2112
  RT_TASK *task;
#endif
  // RTIME in, out, diff;
Raymond Knopp's avatar
 
Raymond Knopp committed
2113
  int slot=0,frame=0,hw_slot,last_slot,next_slot;
Raymond Knopp's avatar
 
Raymond Knopp committed
2114 2115 2116 2117 2118 2119 2120
  // 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;
2121
  int CC_id,card;
Raymond Knopp's avatar
 
Raymond Knopp committed
2122 2123
  volatile unsigned int *DAQ_MBOX = openair0_daq_cnt();
#ifndef USRP
2124
  //exmimo_config_t *p_exmimo_config = openair0_exmimo_pci[card].exmimo_config_ptr;;
Raymond Knopp's avatar
 
Raymond Knopp committed
2125 2126
#endif

2127

2128
#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
Raymond Knopp's avatar
 
Raymond Knopp committed
2129 2130
  /* Wait for NAS UE to start cell selection */
  wait_system_ready ("Waiting for UE to be activated by UserProcess %s\r", &start_UE);
2131 2132
#endif

2133
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2134 2135
  task = rt_task_init_schmod(nam2num("TASK0"), 0, 0, 0, SCHED_FIFO, 0xF);
  LOG_D(HW,"Started UE thread (id %p)\n",task);
2136 2137 2138
#endif

#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
2139
  rt_make_hard_real_time();
2140 2141
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2142
  mlockall(MCL_CURRENT | MCL_FUTURE);
2143

Raymond Knopp's avatar
 
Raymond Knopp committed
2144 2145 2146 2147 2148 2149 2150 2151
  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;
    }
2152
    openair0_dump_config(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
2153 2154 2155
    }
  */
  while (!oai_exit)  {
Raymond Knopp's avatar
 
Raymond Knopp committed
2156

Raymond Knopp's avatar
 
Raymond Knopp committed
2157
    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
2158 2159

     
Raymond Knopp's avatar
 
Raymond Knopp committed
2160
    if (is_synchronized) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2161 2162


Raymond Knopp's avatar
 
Raymond Knopp committed
2163
      //this is the mbox counter that indicates the start of the frame
Raymond Knopp's avatar
 
Raymond Knopp committed
2164
      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
2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177
      //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;
2178
	
Raymond Knopp's avatar
 
Raymond Knopp committed
2179 2180 2181 2182 2183 2184 2185 2186
      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);
	if (frame>0)
	  exit_fun("[HW][UE] missed slot");
	slot++;
	if (slot==20) {
	  slot=0;
	  frame++;
Raymond Knopp's avatar
 
Raymond Knopp committed
2187
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211
	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);
2212
	  
Raymond Knopp's avatar
 
Raymond Knopp committed
2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237
	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;
2238 2239 2240 2241 2242 2243 2244 2245

    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
2246 2247
      
    if (is_synchronized)  {
2248
      phy_procedures_UE_lte (PHY_vars_UE_g[0][0], 0, 0, mode, 0, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
2249 2250 2251 2252 2253 2254
	
    }
    else {  // we are not yet synchronized
      hw_slot_offset = 0;
	
      slot = 0;
2255
      openair0_get_frame(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
2256 2257 2258 2259
      //          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
2260
      if (initial_sync(PHY_vars_UE_g[0][0],mode)==0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2261
	/*
Raymond Knopp's avatar
 
Raymond Knopp committed
2262 2263 2264 2265 2266
	  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
2267
	*/
Raymond Knopp's avatar
 
Raymond Knopp committed
2268 2269 2270 2271 2272 2273
	//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));
	*/
2274 2275
	
	/*if (mode == rx_calib_ue) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2276
	  exit_fun("[HW][UE] UE in RX calibration mode");
Raymond Knopp's avatar
 
Raymond Knopp committed
2277
	}
2278
	else {*/
Raymond Knopp's avatar
 
Raymond Knopp committed
2279 2280 2281
	  is_synchronized = 1;
	  //start the DMA transfers
	  //LOG_D(HW,"Before openair0_start_rt_acquisition \n");
2282 2283
	  for (card=0;card<openair0_num_detected_cards;card++)
	    openair0_start_rt_acquisition(card);
Raymond Knopp's avatar
 
Raymond Knopp committed
2284
	    
Raymond Knopp's avatar
 
Raymond Knopp committed
2285
	  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
2286 2287
	  //LOG_D(HW,"Got synch: hw_slot_offset %d\n",hw_slot_offset);
	  oai_exit=1;
2288
	  /*}*/
Raymond Knopp's avatar
 
Raymond Knopp committed
2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302
      }
      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
2303
	  //	  LOG_I(PHY,"[initial_sync] trying carrier off %d Hz\n",openair_daq_vars.freq_offset);
Raymond Knopp's avatar
 
Raymond Knopp committed
2304
#ifndef USRP
2305 2306 2307 2308 2309
	  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
2310
	  }
2311
	  openair0_config(&openair0_cfg[0],UE_flag);
2312
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2313 2314
	  rt_sleep_ns(FRAME_PERIOD);
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
2315
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2316
    }
2317
    
Raymond Knopp's avatar
 
Raymond Knopp committed
2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331
    /*
      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);
2332 2333

#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
2334
  rt_make_soft_real_time();
2335 2336
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2337
  // clean task
2338
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2339
  rt_task_delete(task);
2340
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2341 2342 2343
  LOG_D(HW,"Task deleted. returning\n");
  return 0;
}
2344

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

2347
#endif
2348

2349

Raymond Knopp's avatar
 
Raymond Knopp committed
2350 2351 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 2377 2378 2379
void init_UE_threads(void) {
  
  PHY_VARS_UE *UE=PHY_vars_UE_g[0][0];

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

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

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

2380
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391
  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
2392
}
Raymond Knopp's avatar
 
Raymond Knopp committed
2393 2394


Raymond Knopp's avatar
 
Raymond Knopp committed
2395
static void get_options (int argc, char **argv) {
2396
  int c;
Raymond Knopp's avatar
 
Raymond Knopp committed
2397 2398
  //  char                          line[1000];
  //  int                           l;
2399
  int k;//i,j,k;
Raymond Knopp's avatar
 
Raymond Knopp committed
2400 2401 2402
#ifdef USRP
  int clock_src;
#endif
2403
  int CC_id;
2404 2405 2406
  char rxg_fname[256], line[1000];
  FILE *rxg_fd;
  int l;
2407

Raymond Knopp's avatar
 
Raymond Knopp committed
2408 2409 2410 2411 2412 2413 2414 2415 2416
  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,
2417
    LONG_OPTION_NO_L2_CONNECT
Raymond Knopp's avatar
 
Raymond Knopp committed
2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428
  };
  
  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}};
  
2429
  while ((c = getopt_long (argc, argv, "C:dK:g:F:G:qO:m:SUVRMr:s:t:x:",long_options,NULL)) != -1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461
    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
2462
      multi_thread=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2463 2464
      break;
    case 'C':
2465
      for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
2466 2467 2468 2469 2470
	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]);
2471
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2472 2473 2474 2475 2476
      break;
      
    case 'd':
#ifdef XFORMS
      do_forms=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
2477
      printf("Running with XFORMS!\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495
#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;
2496 2497 2498 2499 2500 2501 2502
    
    case 'm':
      target_dl_mcs = atoi (optarg);
      break;
    case 't':
      target_ul_mcs = atoi (optarg);
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
2503 2504 2505 2506
      
    case 'V':
      ouput_vcd = 1;
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
2507
    case  'q':
Raymond Knopp's avatar
 
Raymond Knopp committed
2508 2509 2510 2511 2512 2513
      opp_enabled = 1;
      break;
    case  'R' :
      online_log_messages =1;
      break;
    case 'r':
Raymond Knopp's avatar
 
Raymond Knopp committed
2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535
      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
2536
      }
2537
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
2538 2539
    case 's':
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
2540 2541 2542

      clock_src = atoi(optarg);
      if (clock_src == 0) {
2543
	//	char ref[128] = "internal";
Raymond Knopp's avatar
 
Raymond Knopp committed
2544 2545 2546
	//strncpy(uhd_ref, ref, strlen(ref)+1);
      }
      else if (clock_src == 1) {
2547
	//char ref[128] = "external";
Raymond Knopp's avatar
 
Raymond Knopp committed
2548 2549
	//strncpy(uhd_ref, ref, strlen(ref)+1);
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2550 2551 2552 2553
#else
      printf("Note: -s not defined for ExpressMIMO2\n");
#endif
      break;
2554
    case 'g':
Raymond Knopp's avatar
 
Raymond Knopp committed
2555
      glog_level=atoi(optarg); // value between 1 - 9
2556
      break;
2557 2558

    case 'F':
2559
#ifdef EXMIMO
2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576
      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);
2577
#endif
2578 2579
      break;
      
2580 2581 2582
    case 'G':
      glog_verbosity=atoi(optarg);// value from 0, 0x5, 0x15, 0x35, 0x75
      break;
2583 2584 2585 2586 2587 2588 2589
    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
2590 2591
    default:
      break;
2592 2593
    }
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605
  
  if ((UE_flag == 0) && (conf_config_file_name != NULL)) {
    int i;
    
    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);
2606

Raymond Knopp's avatar
 
Raymond Knopp committed
2607
    /* Update some simulation parameters */
2608
    for (i=0; i < enb_properties->number; i++) {
2609 2610 2611 2612
      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
2613 2614 2615 2616 2617 2618
      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
2619
	//for (j=0; j < enb_properties->properties[i]->nb_cc; j++ ){
2620 2621 2622 2623 2624
	frame_parms[CC_id]->Nid_cell            =  enb_properties->properties[i]->Nid_cell[CC_id];
	frame_parms[CC_id]->N_RB_DL             =  enb_properties->properties[i]->N_RB_DL[CC_id];
	frame_parms[CC_id]->nb_antennas_tx      =  enb_properties->properties[i]->nb_antennas_tx[CC_id];
	frame_parms[CC_id]->nb_antennas_tx_eNB  =  enb_properties->properties[i]->nb_antennas_tx[CC_id];
	frame_parms[CC_id]->nb_antennas_rx      =  enb_properties->properties[i]->nb_antennas_rx[CC_id];
2625
	//} // j
Raymond Knopp's avatar
 
Raymond Knopp committed
2626 2627
      }

2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641
      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
2642 2643 2644 2645 2646 2647
# 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
2648
    
Raymond Knopp's avatar
 
Raymond Knopp committed
2649
      // adjust the log
2650 2651
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
	for (k = 0 ; k < 4; k++) {
2652
	  downlink_frequency[CC_id][k]      =       enb_properties->properties[i]->downlink_frequency[CC_id];
2653
	  uplink_frequency_offset[CC_id][k] =  enb_properties->properties[i]->uplink_frequency_offset[CC_id];
2654 2655
	  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];
2656
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
2657
	printf("Downlink frequency/ uplink offset of CC_id %d set to %llu/%d\n", CC_id,
2658 2659
	       enb_properties->properties[i]->downlink_frequency[CC_id],
	       enb_properties->properties[i]->uplink_frequency_offset[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
2660
      } // CC_id
2661
    }// i
Raymond Knopp's avatar
 
Raymond Knopp committed
2662 2663
  }
}
2664

Raymond Knopp's avatar
 
Raymond Knopp committed
2665
int main(int argc, char **argv) {
2666
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2667
  // RT_TASK *task;
Raymond Knopp's avatar
 
Raymond Knopp committed
2668
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
2669
  int *eNB_thread_status_p;
Raymond Knopp's avatar
 
Raymond Knopp committed
2670
  //  int *eNB_thread_status_rx[10],*eNB_thread_status_tx[10];
2671
#endif
2672 2673
  int i,j,aa,card;
#if defined (XFORMS) || defined (EMOS) || (! defined (RTAI)) || defined (SPECTRA)
Raymond Knopp's avatar
 
Raymond Knopp committed
2674
  void *status;
2675
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2676
  
Raymond Knopp's avatar
 
Raymond Knopp committed
2677
  int CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
2678
  uint16_t Nid_cell = 0;
2679
  uint8_t  cooperation_flag=0,  abstraction_flag=0;
2680
#ifndef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
2681
  uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
2682 2683 2684
#endif

#ifdef ENABLE_TCXO
Raymond Knopp's avatar
 
Raymond Knopp committed
2685
  unsigned int tcxo = 114;
2686 2687
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2688 2689 2690 2691
#ifdef ETHERNET
  char *rrh_ip = "127.0.0.1";
  int rrh_port = 22222;
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2692
  //  int amp;
Raymond Knopp's avatar
 
Raymond Knopp committed
2693 2694
  // uint8_t prach_fmt;
  // int N_ZC;
2695

Raymond Knopp's avatar
 
Raymond Knopp committed
2696
  //  int ret, ant;
Raymond Knopp's avatar
 
Raymond Knopp committed
2697
  int ant_offset=0;
2698
#if defined (XFORMS) || defined (SPECTRA)
2699 2700
  int ret;
#endif
2701
#if defined (EMOS) || (! defined (RTAI))
Raymond Knopp's avatar
 
Raymond Knopp committed
2702
  int error_code;
2703
#endif
2704 2705

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

Raymond Knopp's avatar
 
Raymond Knopp committed
2707
  set_latency_target();
2708

Raymond Knopp's avatar
 
Raymond Knopp committed
2709
  mode = normal_txrx;
2710

Raymond Knopp's avatar
 
Raymond Knopp committed
2711 2712 2713
  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
2714
    frame_parms[CC_id]->frame_type         = FDD; /* TDD */
Raymond Knopp's avatar
 
Raymond Knopp committed
2715 2716 2717 2718
    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
2719
    frame_parms[CC_id]->Ncp                 = NORMAL;
Raymond Knopp's avatar
 
Raymond Knopp committed
2720 2721
    frame_parms[CC_id]->Ncp_UL              = NORMAL;
    frame_parms[CC_id]->Nid_cell            = Nid_cell;
Raymond Knopp's avatar
 
Raymond Knopp committed
2722
    frame_parms[CC_id]->num_MBSFN_config    = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2723
  }
2724

Raymond Knopp's avatar
 
Raymond Knopp committed
2725
  get_options (argc, argv); //Command-line options
winckel's avatar
winckel committed
2726

Raymond Knopp's avatar
 
Raymond Knopp committed
2727 2728
  //randominit (0);
  set_taus_seed (0);
winckel's avatar
winckel committed
2729

Raymond Knopp's avatar
 
Raymond Knopp committed
2730 2731 2732
  // initialize the log (see log.h for details)
  logInit();

2733
  set_glog(glog_level, glog_verbosity);
Raymond Knopp's avatar
 
Raymond Knopp committed
2734 2735 2736
  if (UE_flag==1)
    {
      printf("configuring for UE\n");
2737

2738
      set_comp_log(HW,      LOG_DEBUG,  LOG_HIGH, 1);
2739
#ifdef OPENAIR2
2740
      set_comp_log(PHY,     LOG_DEBUG,   LOG_HIGH, 1);
2741
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
2742
      set_comp_log(PHY,     LOG_INFO,   LOG_HIGH, 1);
2743
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2744 2745 2746 2747 2748
      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);
2749
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
2750
      set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
2751
# if defined(ENABLE_USE_MME)
Raymond Knopp's avatar
 
Raymond Knopp committed
2752
      set_comp_log(NAS,     LOG_INFO,   LOG_HIGH, 1);
2753 2754
# endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2755 2756 2757 2758
    }
  else
    {
      printf("configuring for eNB\n");
2759

2760
      set_comp_log(HW,      hw_log_level, hw_log_verbosity, 1);
2761
#ifdef OPENAIR2
2762
      set_comp_log(PHY,     phy_log_level,   phy_log_verbosity, 1);
2763
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
2764
      set_comp_log(PHY,     LOG_INFO,   LOG_HIGH, 1);
2765
#endif
2766 2767 2768 2769
      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);
2770
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
2771
      set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
2772
# if defined(ENABLE_USE_MME)
Lionel Gauthier's avatar
 
Lionel Gauthier committed
2773 2774
      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
2775 2776
      set_comp_log(S1AP,    LOG_DEBUG,   LOG_HIGH, 1);
      set_comp_log(SCTP,    LOG_INFO,   LOG_HIGH, 1);
2777
# endif
2778
#if defined(ENABLE_SECURITY)
Raymond Knopp's avatar
 
Raymond Knopp committed
2779
      set_comp_log(OSA,    LOG_DEBUG,   LOG_HIGH, 1);
2780
#endif
2781
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2782
      set_comp_log(ENB_APP, LOG_INFO, LOG_HIGH, 1);
2783
      set_comp_log(OTG,     LOG_INFO,   LOG_HIGH, 1);
Raymond Knopp's avatar
 
Raymond Knopp committed
2784 2785 2786
      if (online_log_messages == 1) { 
	set_component_filelog(RRC);
	set_component_filelog(PDCP);
Raymond Knopp's avatar
 
Raymond Knopp committed
2787 2788
      }
    }
2789

Raymond Knopp's avatar
 
Raymond Knopp committed
2790 2791 2792 2793 2794 2795 2796
  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");
  }

2797
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
2798 2799 2800 2801 2802 2803
  if (UE_flag == 1) {
    log_set_instance_type (LOG_INSTANCE_UE);
  }
  else {
    log_set_instance_type (LOG_INSTANCE_ENB);
  }
2804

Raymond Knopp's avatar
 
Raymond Knopp committed
2805
  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
2806 2807
#endif

2808
#ifdef NAS_NETLINK
Raymond Knopp's avatar
 
Raymond Knopp committed
2809
  netlink_init();
2810 2811
#endif

2812
#if !defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
2813 2814 2815
  // to make a graceful exit when ctrl-c is pressed
  signal(SIGSEGV, signal_handler);
  signal(SIGINT, signal_handler);
2816
#endif
2817 2818

#ifndef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2819 2820 2821 2822
  check_clock();
#endif

  // init the parameters
Raymond Knopp's avatar
 
Raymond Knopp committed
2823 2824 2825 2826
  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    frame_parms[CC_id]->nushift            = 0;
    if (UE_flag==0)
      {
2827

Raymond Knopp's avatar
 
Raymond Knopp committed
2828
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2829 2830 2831 2832
    else
      { //UE_flag==1
	frame_parms[CC_id]->nb_antennas_tx     = 1;
	frame_parms[CC_id]->nb_antennas_rx     = 1;
2833
	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
2834 2835 2836 2837 2838 2839 2840 2841 2842
      }
    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;
2843 2844
    init_ul_hopping(frame_parms[CC_id]);
    init_frame_parms(frame_parms[CC_id],1);
2845
    phy_init_top(frame_parms[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857
  }

  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
2858
    // N_ZC = (prach_fmt <4)?839:139;
Raymond Knopp's avatar
 
Raymond Knopp committed
2859
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
2860 2861

  if (UE_flag==1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2862 2863 2864
    NB_UE_INST=1;
    NB_INST=1;

Raymond Knopp's avatar
 
Raymond Knopp committed
2865 2866 2867
    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++) {
2868
      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
2869
      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
2870 2871
#ifndef OPENAIR2
      for (i=0;i<NUMBER_OF_eNB_MAX;i++) {
2872 2873 2874
	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
2875
	
2876 2877 2878
	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
2879
      }
2880
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2881
      
2882 2883 2884
      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
2885
      
2886
      PHY_vars_UE_g[0][CC_id]->lte_ue_pdcch_vars[0]->crnti = 0x1234;
2887
#ifndef OPENAIR2
2888
      PHY_vars_UE_g[0][CC_id]->lte_ue_pdcch_vars[0]->crnti = 0x1235;
2889
#endif
2890
    
2891
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
2892 2893 2894 2895 2896
      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];
      }
2897

Raymond Knopp's avatar
 
Raymond Knopp committed
2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912
      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;
      }
2913
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
2914
      PHY_vars_UE_g[0][CC_id]->rx_total_gain_dB =  (int)rx_gain[CC_id][0]; 
2915
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2916
    
Raymond Knopp's avatar
 
Raymond Knopp committed
2917
      PHY_vars_UE_g[0][CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
Raymond Knopp's avatar
 
Raymond Knopp committed
2918
    
2919

2920
   
2921
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933
      //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;
      }
2934
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
2935 2936
      //already taken care of in lte-softmodem
      PHY_vars_UE_g[UE_id][CC_id]->N_TA_offset = 0;
2937
#endif 
Raymond Knopp's avatar
 
Raymond Knopp committed
2938
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
2939 2940 2941 2942 2943
    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;
    
2944
  
Raymond Knopp's avatar
 
Raymond Knopp committed
2945 2946 2947 2948 2949
    
    //  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
2950 2951 2952
      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
2953
	PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],eNB_id,Nid_cell,cooperation_flag,transmission_mode,abstraction_flag);
2954
	PHY_vars_eNB_g[0][CC_id]->CC_id = CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
2955
       
2956
#ifndef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
2957 2958 2959 2960 2961 2962 2963 2964 2965
	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
2966
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2967 2968 2969 2970
      
	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
2971

2972
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
2973

2974
	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
2975

2976
#else
2977
	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
2978 2979 2980

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

2981 2982
	// set eNB to max gain
	for (i=0;i<4;i++)
2983 2984
	  rx_gain_mode[CC_id][i] = max_gain;
#endif
2985

2986
#ifdef EXMIMO
2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003
	//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
3004
      }
3005 3006


Raymond Knopp's avatar
 
Raymond Knopp committed
3007 3008
      NB_eNB_INST=1;
      NB_INST=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
3009

Raymond Knopp's avatar
 
Raymond Knopp committed
3010
      openair_daq_vars.ue_dl_rb_alloc=0x1fff;
3011
      openair_daq_vars.target_ue_dl_mcs=target_dl_mcs;
Raymond Knopp's avatar
 
Raymond Knopp committed
3012
      openair_daq_vars.ue_ul_nb_rb=6;
3013
      openair_daq_vars.target_ue_ul_mcs=target_ul_mcs;
Raymond Knopp's avatar
 
Raymond Knopp committed
3014 3015

    }
3016

3017

3018

Raymond Knopp's avatar
 
Raymond Knopp committed
3019
  dump_frame_parms(frame_parms[0]);
3020

Raymond Knopp's avatar
 
Raymond Knopp committed
3021
  if(frame_parms[0]->N_RB_DL == 100) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3022
    sample_rate = 30.72e6;
3023
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3024 3025 3026 3027 3028
    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
3029
    sf_bounds_tx = sf_bounds_20_tx;
Raymond Knopp's avatar
 
Raymond Knopp committed
3030
    max_cnt = 150;
3031
    tx_delay = 8;
Raymond Knopp's avatar
 
Raymond Knopp committed
3032 3033
#endif
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3034
  else if(frame_parms[0]->N_RB_DL == 50){
3035
    sample_rate = 15.36e6;
3036
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3037 3038 3039 3040
    samples_per_packets = 2048;
    samples_per_frame = 153600;
    tx_forward_nsamps = 95;
    sf_bounds = sf_bounds_10;
Raymond Knopp's avatar
 
Raymond Knopp committed
3041
    sf_bounds_tx = sf_bounds_10_tx;
Raymond Knopp's avatar
 
Raymond Knopp committed
3042 3043 3044 3045
    max_cnt = 75;
    tx_delay = 4;
#endif
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3046
  else if (frame_parms[0]->N_RB_DL == 25) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3047
    sample_rate = 7.68e6;
3048
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3049 3050 3051 3052
    samples_per_packets = 1024;
    samples_per_frame = 76800;
    tx_forward_nsamps = 70;
    sf_bounds = sf_bounds_5;
Raymond Knopp's avatar
 
Raymond Knopp committed
3053
    sf_bounds_tx = sf_bounds_5_tx;
Raymond Knopp's avatar
 
Raymond Knopp committed
3054
    max_cnt = 75;
Raymond Knopp's avatar
 
Raymond Knopp committed
3055
    tx_delay = 5;
Raymond Knopp's avatar
 
Raymond Knopp committed
3056 3057 3058
#endif
  }
  
3059

3060
  for (card=0;card<MAX_CARDS;card++) {
3061 3062 3063 3064 3065 3066
#ifndef EXMIMO
    openair0_cfg[card].samples_per_packet = samples_per_packets;
#endif
    printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card,
	   ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_tx),
	   ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_rx)); 
Raymond Knopp's avatar
 
Raymond Knopp committed
3067 3068 3069 3070 3071 3072
    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
3073 3074 3075
    openair0_cfg[card].sample_rate = sample_rate;
    openair0_cfg[card].tx_bw = bw;
    openair0_cfg[card].rx_bw = bw;
3076 3077 3078
    // 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
3079
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3080 3081
    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));
3082
    for (i=0;i<4;i++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3083

3084
      openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
Raymond Knopp's avatar
 
Raymond Knopp committed
3085 3086
      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
3087 3088
      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
3089 3090 3091 3092 3093 3094
      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
3095
    }
3096
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3097
  }
3098 3099

  if (openair0_device_init(&openair0, &openair0_cfg[0]) <0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3100 3101 3102
    printf("Exiting, cannot initialize device\n");
    exit(-1);
  }
3103 3104 3105

  mac_xface = malloc(sizeof(MAC_xface));

3106
#ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3107
  int eMBMS_active=0;
3108

3109
  l2_init(frame_parms[0],eMBMS_active,
Raymond Knopp's avatar
 
Raymond Knopp committed
3110 3111 3112 3113 3114 3115
	  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);
3116 3117
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3118
  mac_xface->macphy_exit = &exit_fun;
3119

winckel's avatar
winckel committed
3120
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
3121
  if (create_tasks(UE_flag ? 0 : 1, UE_flag ? 1 : 0) < 0) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
3122
    printf("cannot create ITTI tasks\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
3123 3124 3125
    exit(-1); // need a softer mode
  }
  printf("ITTI tasks created\n");
winckel's avatar
winckel committed
3126 3127
#endif

3128
#ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139
  //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
3140
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3141 3142 3143
  }
  init_predef_traffic(UE_flag ? 1 : 0, UE_flag ? 0 : 1);
  //  }
3144 3145
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3146
  //  number_of_cards = openair0_num_detected_cards;
3147

Raymond Knopp's avatar
 
Raymond Knopp committed
3148
  openair_daq_vars.timing_advance = 0;
3149

Florian Kaltenberger's avatar
Florian Kaltenberger committed
3150 3151
  for(CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    rf_map[CC_id].card=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3152
    rf_map[CC_id].chain=CC_id;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
3153
  }
3154

Raymond Knopp's avatar
 
Raymond Knopp committed
3155 3156
  // connect the TX/RX buffers
  if (UE_flag==1) {
3157 3158 3159 3160
    if (setup_ue_buffers(PHY_vars_UE_g[0],&openair0_cfg[0],rf_map)!=0) {
      printf("Error setting up eNB buffer\n");
      exit(-1);
    }
3161 3162
    printf("Setting UE buffer to all-RX\n");
    // Set LSBs for antenna switch (ExpressMIMO)
Raymond Knopp's avatar
 
Raymond Knopp committed
3163
    for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3164
      for (i=0; i<frame_parms[CC_id]->samples_per_tti*10; i++)
3165
	for (aa=0; aa<frame_parms[CC_id]->nb_antennas_tx; aa++)
3166
	  PHY_vars_UE_g[0][CC_id]->lte_ue_common_vars.txdata[aa][i] = 0x00010001;
Raymond Knopp's avatar
 
Raymond Knopp committed
3167
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3168 3169 3170
    //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX;
  }
  else {
3171 3172 3173 3174 3175 3176
    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
3177
    for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3178 3179
      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++)
3180
	  PHY_vars_eNB_g[0][CC_id]->lte_eNB_common_vars.txdata[0][aa][i] = 0x00010001;
Raymond Knopp's avatar
 
Raymond Knopp committed
3181
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3182
  }
3183
#ifdef EXMIMO
3184
  openair0_config(&openair0_cfg[0],UE_flag);
Raymond Knopp's avatar
 
Raymond Knopp committed
3185 3186
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3187
  /*  
Raymond Knopp's avatar
 
Raymond Knopp committed
3188 3189
      for (ant=0;ant<4;ant++)
      p_exmimo_config->rf.do_autocal[ant] = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3190
  */
3191 3192

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3193 3194 3195 3196 3197 3198 3199 3200 3201
  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);
3202 3203
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3204
  mlockall(MCL_CURRENT | MCL_FUTURE);
3205 3206

#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227
  // 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);
3228

Raymond Knopp's avatar
 
Raymond Knopp committed
3229 3230 3231
  sync_sem = rt_typed_sem_init(nam2num("syncsem"), 0, BIN_SEM|FIFO_Q);
  if(sync_sem == 0)
    printf("error init sync semphore\n");
3232

Raymond Knopp's avatar
 
Raymond Knopp committed
3233 3234 3235
#else
  pthread_cond_init(&sync_cond,NULL);
  pthread_mutex_init(&sync_mutex, NULL);
3236 3237
#endif

3238
#if defined(ENABLE_ITTI)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
3239 3240 3241 3242 3243
  // 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);
  }
3244
#endif
3245

Raymond Knopp's avatar
 
Raymond Knopp committed
3246 3247

  // this starts the DMA transfers
3248
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3249
  if (UE_flag!=1)
3250 3251
    for (card=0;card<openair0_num_detected_cards;card++)
      openair0_start_rt_acquisition(card);
Raymond Knopp's avatar
 
Raymond Knopp committed
3252
#endif
3253 3254

#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
3255 3256
  if (do_forms==1) {
    fl_initialize (&argc, argv, NULL, 0, 0);
3257 3258

    if (UE_flag==0) {
3259
      form_stats_l2 = create_form_stats_form();
3260 3261 3262
      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
3263 3264 3265 3266 3267 3268 3269
      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
3270 3271
	}
	else {
Raymond Knopp's avatar
 
Raymond Knopp committed
3272 3273
	  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
3274
	}
3275 3276
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3277
    else {
3278 3279 3280 3281 3282 3283 3284
      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
3285 3286 3287 3288 3289 3290 3291 3292 3293 3294
      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
3295
    ret = pthread_create(&forms_thread, NULL, scope_thread, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
3296 3297
    printf("Scope thread created, ret=%d\n",ret);
  }
3298 3299 3300
#endif

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3301 3302
  ret = pthread_create(&thread3, NULL, emos_thread, NULL);
  printf("EMOS thread created, ret=%d\n",ret);
3303 3304
#endif

3305 3306 3307 3308 3309
#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
3310
  rt_sleep_ns(10*FRAME_PERIOD);
3311 3312

#ifndef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3313 3314
  pthread_attr_init (&attr_dlsch_threads);
  pthread_attr_setstacksize(&attr_dlsch_threads,OPENAIR_THREAD_STACK_SIZE);
3315
  sched_param_dlsch.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY;
Raymond Knopp's avatar
 
Raymond Knopp committed
3316 3317
  pthread_attr_setschedparam  (&attr_dlsch_threads, &sched_param_dlsch);
  pthread_attr_setschedpolicy (&attr_dlsch_threads, SCHED_FIFO);
Raymond Knopp's avatar
 
Raymond Knopp committed
3318 3319 3320

  pthread_attr_init (&attr_UE_init_synch);
  pthread_attr_setstacksize(&attr_UE_init_synch,OPENAIR_THREAD_STACK_SIZE);
3321
  sched_param_UE_init_synch.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY;
Raymond Knopp's avatar
 
Raymond Knopp committed
3322 3323 3324
  pthread_attr_setschedparam  (&attr_UE_init_synch, &sched_param_UE_init_synch);
  pthread_attr_setschedpolicy (&attr_UE_init_synch, SCHED_FIFO);

3325 3326
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3327 3328
  // start the main thread
  if (UE_flag == 1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3329
    init_UE_threads();
3330
    sleep(1);
3331
#ifdef RTAI
3332
    main_ue_thread = rt_thread_create(UE_thread, NULL, 100000000);
3333
#else
3334
    error_code = pthread_create(&main_ue_thread, &attr_dlsch_threads, UE_thread, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
3335 3336 3337 3338 3339 3340 3341
    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");
    }
3342 3343
#endif
#ifdef DLSCH_THREAD
Raymond Knopp's avatar
 
Raymond Knopp committed
3344 3345 3346
    init_rx_pdsch_thread();
    rt_sleep_ns(FRAME_PERIOD/10);
    init_dlsch_threads();
3347
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3348 3349 3350
    printf("UE threads created\n");
  }
  else {
3351

Raymond Knopp's avatar
 
Raymond Knopp committed
3352 3353
    if (multi_thread>0) {
      init_eNB_proc();
3354
      sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3355 3356
      LOG_D(HW,"[lte-softmodem.c] eNB threads created\n");
    }
3357
    printf("Creating main eNB_thread \n");
Raymond Knopp's avatar
 
Raymond Knopp committed
3358
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3359
    main_eNB_thread = rt_thread_create(eNB_thread, NULL, OPENAIR_THREAD_STACK_SIZE);
Raymond Knopp's avatar
 
Raymond Knopp committed
3360
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3361
    error_code = pthread_create(&main_eNB_thread, &attr_dlsch_threads, eNB_thread, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
3362 3363 3364 3365 3366 3367
    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
3368
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3369 3370
#endif
  }
3371

Raymond Knopp's avatar
 
Raymond Knopp committed
3372
  // Sleep to allow all threads to setup
Raymond Knopp's avatar
 
Raymond Knopp committed
3373
  sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3374

3375
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3376
#ifndef USRP_DEBUG
Raymond Knopp's avatar
 
Raymond Knopp committed
3377
  openair0.trx_start_func(&openair0);
Raymond Knopp's avatar
 
Raymond Knopp committed
3378
  //  printf("returning from usrp start streaming: %llu\n",get_usrp_time(&openair0));
Raymond Knopp's avatar
 
Raymond Knopp committed
3379
#endif
3380 3381
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3382 3383 3384
#ifdef RTAI
  rt_sem_signal(sync_sem);
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3385 3386
  pthread_mutex_lock(&sync_mutex);
  printf("Sending sync ...\n");
3387
  sync_var=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3388 3389
  pthread_cond_broadcast(&sync_cond);
  pthread_mutex_unlock(&sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
3390
#endif
3391

Raymond Knopp's avatar
 
Raymond Knopp committed
3392 3393 3394
  // wait for end of program
  printf("TYPE <CTRL-C> TO TERMINATE\n");
  //getchar();
3395 3396

#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
3397 3398
  printf("Entering ITTI signals handler\n");
  itti_wait_tasks_end();
3399
  oai_exit=1;
3400
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3401 3402
  while (oai_exit==0)
    rt_sleep_ns(FRAME_PERIOD);
3403
#endif
3404

Raymond Knopp's avatar
 
Raymond Knopp committed
3405
  // stop threads
3406
#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
3407 3408 3409
  printf("waiting for XFORMS thread\n");
  if (do_forms==1)
    {
Raymond Knopp's avatar
 
Raymond Knopp committed
3410
      pthread_join(forms_thread,&status);
Raymond Knopp's avatar
 
Raymond Knopp committed
3411 3412 3413 3414 3415 3416
      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 {
3417 3418
	fl_hide_form(form_stats_l2->stats_form);
	fl_free_form(form_stats_l2->stats_form);
Raymond Knopp's avatar
 
Raymond Knopp committed
3419 3420 3421 3422
	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
3423
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3424
    }
3425 3426
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3427 3428 3429
  printf("stopping MODEM threads\n");
  // cleanup
  if (UE_flag == 1) {
3430
#ifdef EXMIMO
3431
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3432
    rt_thread_join(main_ue_thread); 
3433
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3434
    pthread_join(main_ue_thread,&status); 
3435 3436
#endif
#ifdef DLSCH_THREAD
Raymond Knopp's avatar
 
Raymond Knopp committed
3437 3438
    cleanup_dlsch_threads();
    cleanup_rx_pdsch_thread();
3439
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3440 3441 3442
#endif
  }
  else {
Raymond Knopp's avatar
 
Raymond Knopp committed
3443
#ifdef DEBUG_THREADS
Raymond Knopp's avatar
 
Raymond Knopp committed
3444
    printf("Joining eNB_thread ...");
Raymond Knopp's avatar
 
Raymond Knopp committed
3445
#endif
3446 3447 3448
#ifdef RTAI
    rt_thread_join(main_eNB_thread); 
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3449
    pthread_join(main_eNB_thread,(void**)&eNB_thread_status_p); 
Raymond Knopp's avatar
 
Raymond Knopp committed
3450
#ifdef DEBUG_THREADS
Raymond Knopp's avatar
 
Raymond Knopp committed
3451
    printf("status %d\n",*eNB_thread_status_p);
Raymond Knopp's avatar
 
Raymond Knopp committed
3452
#endif
3453
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3454

Raymond Knopp's avatar
 
Raymond Knopp committed
3455 3456 3457
    if (multi_thread>0) {
      printf("Killing eNB processing threads\n");
      kill_eNB_proc();
Raymond Knopp's avatar
 
Raymond Knopp committed
3458

Raymond Knopp's avatar
 
Raymond Knopp committed
3459
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3460
  }
3461

3462
#ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3463
  //cleanup_pdcp_thread();
3464 3465
#endif

3466
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3467
  rt_sem_delete(sync_sem);
Raymond Knopp's avatar
 
Raymond Knopp committed
3468
  stop_rt_timer();
Raymond Knopp's avatar
 
Raymond Knopp committed
3469 3470 3471
#else
  pthread_cond_destroy(&sync_cond);
  pthread_mutex_destroy(&sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
3472
#endif
3473

3474
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3475
  printf("stopping card\n");
3476
  openair0_stop(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
3477 3478
  printf("closing openair0_lib\n");
  openair0_close();
Raymond Knopp's avatar
 
Raymond Knopp committed
3479
#endif
3480 3481

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3482 3483 3484
  printf("waiting for EMOS thread\n");
  pthread_cancel(thread3);
  pthread_join(thread3,&status);
3485 3486 3487
#endif

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3488 3489
  error_code = rtf_destroy(CHANSOUNDER_FIFO_MINOR);
  printf("[OPENAIR][SCHED][CLEANUP] EMOS FIFO closed, error_code %d\n", error_code);
3490 3491
#endif

3492 3493 3494 3495 3496 3497
#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
3498 3499
  if (ouput_vcd)
    vcd_signal_dumper_close();
3500

Raymond Knopp's avatar
 
Raymond Knopp committed
3501
  logClean();
3502

Raymond Knopp's avatar
 
Raymond Knopp committed
3503 3504
  return 0;
}
3505

3506 3507
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
3508

3509
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3510 3511 3512
  uint16_t N_TA_offset = 0;
#endif

3513 3514 3515 3516 3517
  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
3518
    }
3519 3520 3521
    else {
      printf("phy_vars_eNB[%d] not initialized\n", CC_id);
      return(-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3522
    }
3523

Raymond Knopp's avatar
 
Raymond Knopp committed
3524

3525
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3526 3527 3528 3529 3530 3531
    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
3532
	N_TA_offset = 624/4;
Raymond Knopp's avatar
 
Raymond Knopp committed
3533 3534 3535
    }
#endif
   
3536
#ifdef EXMIMO
3537 3538 3539 3540 3541
    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++) {
3542
      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);
3543 3544 3545 3546 3547 3548 3549 3550
      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];
3551 3552
	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];
3553 3554
	openair0_cfg[rf_map[CC_id].card].rx_num_channels++;
      }
3555

3556
      printf("rxdata[%d] @ %p\n",i,phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i]);
Raymond Knopp's avatar
 
Raymond Knopp committed
3557
    }
3558
    for (i=0;i<frame_parms->nb_antennas_tx;i++) {
3559
      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);
3560 3561 3562 3563 3564 3565 3566 3567
      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];
3568
	openair0_cfg[rf_map[CC_id].card].tx_gain[rf_map[CC_id].chain+i] = tx_gain[CC_id][i];
3569 3570
	openair0_cfg[rf_map[CC_id].card].tx_num_channels++;
      }
3571

3572
      printf("txdata[%d] @ %p\n",i,phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i]);
3573
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3574
  
Raymond Knopp's avatar
 
Raymond Knopp committed
3575
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3576
    // replace RX signal buffers with mmaped HW versions
3577 3578
    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
3579 3580 3581
    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]);
3582 3583
      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
3584 3585 3586 3587
    }
    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]);
3588 3589 3590
      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
3591 3592
    }
    
Raymond Knopp's avatar
 
Raymond Knopp committed
3593
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3594 3595 3596 3597
    
  }
  return(0);

Raymond Knopp's avatar
 
Raymond Knopp committed
3598
}
3599

3600 3601 3602 3603 3604
/* 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]) {
3605

3606
  int i, CC_id;
3607
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3608
  uint16_t N_TA_offset = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3609 3610
#else
  int j;
Raymond Knopp's avatar
 
Raymond Knopp committed
3611
#endif
3612
  LTE_DL_FRAME_PARMS *frame_parms;
3613

Raymond Knopp's avatar
 
Raymond Knopp committed
3614

3615 3616
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    if (phy_vars_eNB[CC_id]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3617 3618 3619
      frame_parms = &(phy_vars_eNB[CC_id]->lte_frame_parms);
      printf("setup_eNB_buffers: frame_parms = %p\n",frame_parms);
    } 
3620 3621 3622
    else {
      printf("phy_vars_eNB[%d] not initialized\n", CC_id);
      return(-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3623
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3624

3625
#ifndef EXMIMO
3626 3627
    if (frame_parms->frame_type == TDD) {
      if (frame_parms->N_RB_DL == 100)
Raymond Knopp's avatar
 
Raymond Knopp committed
3628
	N_TA_offset = 624;
3629
      else if (frame_parms->N_RB_DL == 50)
Raymond Knopp's avatar
 
Raymond Knopp committed
3630
	N_TA_offset = 624/2;
3631
      else if (frame_parms->N_RB_DL == 25)
Raymond Knopp's avatar
 
Raymond Knopp committed
3632 3633
	N_TA_offset = 624/4;
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3634
#endif
3635 3636 3637 3638 3639
   

   

  
Raymond Knopp's avatar
 
Raymond Knopp committed
3640
    // replace RX signal buffers with mmaped HW versions
3641
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3642 3643 3644
    openair0_cfg[CC_id].tx_num_channels = 0;
    openair0_cfg[CC_id].rx_num_channels = 0;

3645 3646 3647 3648 3649 3650 3651 3652 3653 3654
    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];
3655
	openair0_cfg[rf_map[CC_id].card].rx_gain[rf_map[CC_id].chain+i] = rx_gain[CC_id][i];
3656 3657 3658
	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
3659
      for (j=0;j<16;j++) {
3660 3661
	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;
3662
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3663
    }
3664 3665 3666 3667 3668 3669 3670 3671 3672 3673
    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];
3674
	openair0_cfg[rf_map[CC_id].card].tx_gain[rf_map[CC_id].chain+i] = tx_gain[CC_id][i];
3675 3676 3677 3678
	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
3679
      for (j=0;j<16;j++) {
3680 3681
	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;
3682
      }
3683
    }
3684
#else // not EXMIMO
3685 3686 3687
    rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*));
    txdata = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));

3688 3689
    for (i=0;i<frame_parms->nb_antennas_rx;i++) {
      free(phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i]);
3690 3691 3692 3693
      rxdata[i] = (int32_t*)malloc16(samples_per_frame*sizeof(int32_t));
      phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i] = rxdata[i]-N_TA_offset; // N_TA offset for TDD
      memset(rxdata[i], 0, samples_per_frame*sizeof(int32_t));
      printf("rxdata[%d] @ %p (%p) (N_TA_OFFSET %d)\n", i, phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i],rxdata[i],N_TA_offset);
Raymond Knopp's avatar
 
Raymond Knopp committed
3694
    }
3695 3696
    for (i=0;i<frame_parms->nb_antennas_tx;i++) {
      free(phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i]);
3697 3698 3699
      txdata[i] = (int32_t*)malloc16(samples_per_frame*sizeof(int32_t));
      phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i] = txdata[i];
      memset(txdata[i], 0, samples_per_frame*sizeof(int32_t));
3700
      printf("txdata[%d] @ %p\n", i, phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i]);
3701

Raymond Knopp's avatar
 
Raymond Knopp committed
3702 3703
    }
#endif
3704
  }
3705
  return(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
3706
}
3707