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

Raymond Knopp's avatar
 
Raymond Knopp committed
58
#ifdef USRP
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

Raymond Knopp's avatar
 
Raymond Knopp committed
74
#ifndef USRP
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 133
#define DEBUG_THREADS 1

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 175 176
#ifdef USRP
static SEM *sync_sem; // to sync rx & tx streaming
#endif
177 178
//static int sync_thread;
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
179 180
pthread_t                       main_eNB_thread;
pthread_t                       main_ue_thread;
181 182
pthread_attr_t                  attr_dlsch_threads;
struct sched_param              sched_param_dlsch;
Raymond Knopp's avatar
 
Raymond Knopp committed
183

Raymond Knopp's avatar
 
Raymond Knopp committed
184 185 186
#ifdef USRP
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
Raymond Knopp's avatar
 
Raymond Knopp committed
187

Raymond Knopp's avatar
 
Raymond Knopp committed
188
#endif
189
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
190
RTIME T0;
191

Raymond Knopp's avatar
 
Raymond Knopp committed
192 193 194
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
195 196
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
197 198 199
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
200 201
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
202

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

210 211 212 213
#ifdef SPECTRA
static pthread_t sensing_thread;
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
214 215 216
openair0_device openair0;
openair0_timestamp timestamp;

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

225
int                             card = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
226

227

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

239
static char                     UE_flag=0;
240
static uint8_t                  eNB_id=0,UE_id=0;
241

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

openair0_rf_map rf_map[MAX_NUM_CCs];
248

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
276 277
double sample_rate=30.72e6;
double bw = 14e6;
278

279
static int                      tx_max_power[MAX_NUM_CCs] =  {0,0};
280

281
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
282 283 284
char ref[128] = "internal";
char channels[128] = "0";

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
298
int *sf_bounds;
Raymond Knopp's avatar
 
Raymond Knopp committed
299 300
int *sf_bounds_tx;

Raymond Knopp's avatar
 
Raymond Knopp committed
301 302 303 304
int max_cnt;
int tx_delay;

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
336
static LTE_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
337

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

Raymond Knopp's avatar
 
Raymond Knopp committed
342

343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
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;

358
unsigned int build_rflocal(int txi, int txq, int rxi, int rxq)
359
{
Raymond Knopp's avatar
 
Raymond Knopp committed
360
  return (txi + (txq<<6) + (rxi<<12) + (rxq<<18));
361 362 363
}
unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
364
  return (dcoff_i_rxfe + (dcoff_q_rxfe<<8));
365 366
}

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

void exit_fun(const char* s)
{
391
  if (s != NULL) {
Lionel Gauthier's avatar
Lionel Gauthier committed
392
    printf("%s %s() Exiting: %s\n",__FILE__, __FUNCTION__, s);
393 394 395 396 397
  }

  oai_exit = 1;

#if defined(ENABLE_ITTI)
398
  itti_terminate_tasks (TASK_UNKNOWN);
399
#endif
400 401 402 403 404 405

  //rt_sleep_ns(FRAME_PERIOD);

  //exit (-1);
}

Raymond Knopp's avatar
 
Raymond Knopp committed
406 407 408
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
409 410 411 412 413 414 415 416 417
 * 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
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434
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
435
 
436
#ifdef XFORMS
437 438 439 440

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

464
static void *scope_thread(void *arg) {
Raymond Knopp's avatar
 
Raymond Knopp committed
465
  char stats_buffer[16384];
466
# ifdef ENABLE_XFORMS_WRITE_STATS
Raymond Knopp's avatar
 
Raymond Knopp committed
467 468
  FILE *UE_stats, *eNB_stats;
  int len = 0;
469
# endif
Raymond Knopp's avatar
 
Raymond Knopp committed
470
  struct sched_param sched_param;
471

Raymond Knopp's avatar
 
Raymond Knopp committed
472 473
  sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1; 
  sched_setscheduler(0, SCHED_FIFO,&sched_param);
474

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

Raymond Knopp's avatar
 
Raymond Knopp committed
492
      phy_scope_UE(form_ue[UE_id], 
493
		   PHY_vars_UE_g[UE_id][0],
Raymond Knopp's avatar
 
Raymond Knopp committed
494 495
		   eNB_id,
		   UE_id,7);
496
            
Raymond Knopp's avatar
 
Raymond Knopp committed
497
    } else {
498
# ifdef ENABLE_XFORMS_WRITE_STATS
Raymond Knopp's avatar
 
Raymond Knopp committed
499
      len =
500
# endif
501 502
      dump_eNB_l2_stats (stats_buffer, 0);
      fl_set_object_label(form_stats_l2->stats_text, stats_buffer);
503 504 505 506 507 508 509

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

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

  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);
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595
 
  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);
    }
596 597
  else 
    printf("[EMOS] Opened GPS, gps_data=%p\n");
598 599 600 601 602 603 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
  
  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
643
	if (UE_flag==0)
644
	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
645
	else
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706
	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

707 708 709 710 711 712 713 714 715 716 717 718 719
#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) {

    
720 721 722
    openair0_cfg[0].rx_freq[2]+= 5e6;
    if (openair0_cfg[0].rx_freq[2] >= 750000000)
      openair0_cfg[0].rx_freq[2] = 727500000;
723 724
    

725
    //LOG_I(HW,"[SPECTRA] changing frequency to %u \n",(uint32_t)openair0_cfg[1].rx_freq[0]);
726 727 728

    openair0_reconfig(&openair0_cfg[0]);

729
    usleep(200000);
730 731 732 733 734 735 736 737 738 739
    //sleep(1);
    
  }

  pthread_exit((void*) arg);

}
#endif


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

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
767

Raymond Knopp's avatar
 
Raymond Knopp committed
768 769
  if (UE_flag == 0) {
    /* Wait for the initialize message */
770
    do {
Raymond Knopp's avatar
 
Raymond Knopp committed
771 772 773 774
      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);
      }
775 776 777
      itti_receive_msg (TASK_L2L1, &message_p);

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

Raymond Knopp's avatar
 
Raymond Knopp committed
816 817 818 819 820 821 822 823 824 825 826 827
    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);
828

Raymond Knopp's avatar
 
Raymond Knopp committed
829
  return NULL;
830 831 832
}
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
833

Raymond Knopp's avatar
 
Raymond Knopp committed
834
void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) {
Raymond Knopp's avatar
 
Raymond Knopp committed
835 836 837 838

  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
839
  int slot_sizeF = (phy_vars_eNB->lte_frame_parms.ofdm_symbol_size)*
Raymond Knopp's avatar
 
Raymond Knopp committed
840
    ((phy_vars_eNB->lte_frame_parms.Ncp==1) ? 6 : 7);
Raymond Knopp's avatar
 
Raymond Knopp committed
841 842 843

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
850
    
Raymond Knopp's avatar
 
Raymond Knopp committed
851 852 853 854 855 856 857 858 859 860
    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
861 862 863 864 865 866 867 868
	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
869 870 871 872 873 874
      }
      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
875 876 877 878
	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
879
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
880 881

      for (i=0; i<phy_vars_eNB->lte_frame_parms.samples_per_tti; i++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898
	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
899 900 901

  //unsigned long cpuid;
  eNB_proc_t *proc = (eNB_proc_t*)param;
Raymond Knopp's avatar
 
Raymond Knopp committed
902
  //  RTIME time_in,time_out;
Raymond Knopp's avatar
 
Raymond Knopp committed
903 904
#ifdef RTAI
  RT_TASK *task;
905
  char task_name[8];
Raymond Knopp's avatar
 
Raymond Knopp committed
906
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
907 908

 
Raymond Knopp's avatar
 
Raymond Knopp committed
909

Raymond Knopp's avatar
 
Raymond Knopp committed
910 911 912 913 914
#if defined(ENABLE_ITTI)
  /* Wait for eNB application initialization to be complete (eNB registration to MME) */
  wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
915
#ifdef RTAI
916
  sprintf(task_name,"TXC%dS%d",proc->CC_id,proc->subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
917 918 919
  task = rt_task_init_schmod(nam2num(task_name), 0, 0, 0, SCHED_FIFO, 0xF);

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1001
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1002 1003 1004
    proc->frame_tx++;
    if (proc->frame_tx==1024)
      proc->frame_tx=0;
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 1010
  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
1011
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1012 1013 1014 1015 1016 1017 1018 1019 1020 1021
#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
1022
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035
#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;
1036
  char task_name[8];
Raymond Knopp's avatar
 
Raymond Knopp committed
1037 1038 1039 1040 1041 1042 1043 1044
#endif

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

#ifdef RTAI
1045
  sprintf(task_name,"RXC%1dS%1d",proc->CC_id,proc->subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
1046 1047 1048 1049 1050 1051 1052
  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 {
1053 1054
    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
1055
	  proc->subframe,
1056
	  task); /*,rtai_cpuid()*/
Raymond Knopp's avatar
 
Raymond Knopp committed
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074
  }
#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
1075
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1076 1077 1078 1079 1080 1081 1082 1083 1084 1085
    //    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
1086
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1087 1088 1089
      //      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
1090 1091
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1092
    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
1093
    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
1094 1095 1096

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1137 1138 1139
#ifdef DEBUG_THREADS
  printf("Exiting eNB RX thread %d\n",proc->subframe);
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1140 1141 1142 1143
}



Raymond Knopp's avatar
 
Raymond Knopp committed
1144

1145
void init_eNB_proc(void) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1146 1147

  int i;
Raymond Knopp's avatar
 
Raymond Knopp committed
1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165
  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
1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177
      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;
Raymond Knopp's avatar
 
Raymond Knopp committed
1178
#ifndef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
1179 1180
      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
1181
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1182 1183
      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
1184
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1185 1186 1187
    }
  
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1188
#ifndef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
1189 1190
    // 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
1191
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1192
    //PHY_vars_eNB_g[0][CC_id]->proc[0].frame_rx = 1023;
Raymond Knopp's avatar
 
Raymond Knopp committed
1193 1194
    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
1195
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1196 1197
    // 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
1198
    //    PHY_vars_eNB_g[0][CC_id]->proc[7].frame_tx = 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1199 1200
    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
1201
    //    PHY_vars_eNB_g[0][CC_id]->proc[0].frame_tx = 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1202
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1203 1204
  }
}
Raymond Knopp's avatar
 
Raymond Knopp committed
1205

1206
void kill_eNB_proc(void) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1207 1208

  int i;
Raymond Knopp's avatar
 
Raymond Knopp committed
1209
  int *status_tx,*status_rx;
Raymond Knopp's avatar
 
Raymond Knopp committed
1210
  int CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1211

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


Raymond Knopp's avatar
 
Raymond Knopp committed
1247 1248


Raymond Knopp's avatar
 
Raymond Knopp committed
1249 1250
  
/* This is the main eNB thread. */
Raymond Knopp's avatar
 
Raymond Knopp committed
1251 1252
int eNB_thread_status;

Raymond Knopp's avatar
 
Raymond Knopp committed
1253

Raymond Knopp's avatar
 
Raymond Knopp committed
1254

1255 1256 1257 1258 1259
static void *eNB_thread(void *arg)
{
#ifdef RTAI
  RT_TASK *task;
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1260 1261 1262 1263 1264
#ifndef USRP
  unsigned char slot=0;
#else
  unsigned char slot=1;
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1265
  int frame=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1266
  int CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1267

1268
  RTIME time_in, time_diff;
Raymond Knopp's avatar
 
Raymond Knopp committed
1269

Raymond Knopp's avatar
 
Raymond Knopp committed
1270
  int sf;
Raymond Knopp's avatar
 
Raymond Knopp committed
1271
#ifndef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
1272
  volatile unsigned int *DAQ_MBOX = openair0_daq_cnt();
Raymond Knopp's avatar
 
Raymond Knopp committed
1273 1274
  int mbox_target=0,mbox_current=0;
  int hw_slot,delay_cnt;
Raymond Knopp's avatar
 
Raymond Knopp committed
1275 1276
  int diff;
  int ret;
1277
  int first_run=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1278
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1279 1280
  unsigned int rx_cnt = 0;
  unsigned int tx_cnt = tx_delay;
Raymond Knopp's avatar
 
Raymond Knopp committed
1281 1282
  //  int tx_offset;

Raymond Knopp's avatar
 
Raymond Knopp committed
1283
  hw_subframe = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1284
#endif
1285

1286 1287
#if defined(ENABLE_ITTI)
  /* Wait for eNB application initialization to be complete (eNB registration to MME) */
1288
  wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
1289 1290
#endif

1291
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
1292
  task = rt_task_init_schmod(nam2num("TASK0"), 0, 0, 0, SCHED_FIFO, 0xF);
1293 1294 1295 1296
#endif

  if (!oai_exit) {
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
1297
    printf("[SCHED][eNB] Started eNB thread (id %p)\n",task);
Raymond Knopp's avatar
 
Raymond Knopp committed
1298
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1299 1300
    printf("[SCHED][eNB] Started eNB thread on CPU %d\n",
	   sched_getcpu());
1301 1302 1303
#endif

#ifdef HARD_RT
1304
    rt_make_hard_real_time();
1305 1306
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1307
    printf("eNB_thread: mlockall in ...\n");
1308
    mlockall(MCL_CURRENT | MCL_FUTURE);
Raymond Knopp's avatar
 
Raymond Knopp committed
1309
    printf("eNB_thread: mlockall out ...\n");
1310

1311 1312 1313 1314
    timing_info.time_min = 100000000ULL;
    timing_info.time_max = 0;
    timing_info.time_avg = 0;
    timing_info.n_samples = 0;
1315

Raymond Knopp's avatar
 
Raymond Knopp committed
1316
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
1317
    printf("waiting for USRP sync (eNB_thread)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1318 1319 1320
#ifdef RTAI
    rt_sem_wait(sync_sem);
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1321
    pthread_mutex_lock(&sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
1322
    pthread_cond_wait(&sync_cond, &sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
1323
    pthread_mutex_unlock(&sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
1324 1325 1326 1327
#endif
    //    printf("starting eNB thread @ %llu\n",get_usrp_time(&openair0));
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1328
    while (!oai_exit) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1329 1330

#ifndef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
1331 1332
      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
1333 1334
      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
1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346
      //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;
      
1347 1348 1349 1350 1351
      //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;
1352
	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);
1353 1354
      } 

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

#else  // USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
1396 1397
      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
1398 1399
      while (rx_cnt < sf_bounds[hw_subframe]) {

Raymond Knopp's avatar
 
Raymond Knopp committed
1400 1401
	openair0_timestamp time0,time1;
	unsigned int rxs;
Raymond Knopp's avatar
 
Raymond Knopp committed
1402
#ifndef USRP_DEBUG
Raymond Knopp's avatar
 
Raymond Knopp committed
1403
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1404 1405 1406
	/*
	// Grab 1/4 of RX buffer and get timestamp

Raymond Knopp's avatar
 
Raymond Knopp committed
1407
	rxs = openair0.trx_read_func(&openair0, 
Raymond Knopp's avatar
 
Raymond Knopp committed
1408 1409 1410
	&timestamp, 
	&rxdata[rx_cnt*samples_per_packets], 
	(samples_per_packets>>2));
Raymond Knopp's avatar
 
Raymond Knopp committed
1411
	if (rxs != (samples_per_packets>>2))
Raymond Knopp's avatar
 
Raymond Knopp committed
1412
	oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1413 1414 1415

	*/

Raymond Knopp's avatar
 
Raymond Knopp committed
1416 1417
	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);
Raymond Knopp's avatar
 
Raymond Knopp committed
1418 1419 1420 1421 1422 1423 1424
	rxs = openair0.trx_read_func(&openair0, 
				     &timestamp, 
				     &rxdata[rx_cnt*samples_per_packets], 
				     samples_per_packets);
	if (rxs != samples_per_packets)
	  oai_exit=1;

Raymond Knopp's avatar
 
Raymond Knopp committed
1425 1426
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,0);

Raymond Knopp's avatar
 
Raymond Knopp committed
1427
	// Transmit TX buffer based on timestamp from RX
Raymond Knopp's avatar
 
Raymond Knopp committed
1428
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1429 1430 1431 1432 1433
	openair0.trx_write_func(&openair0, 
				(timestamp+samples_per_packets*tx_delay-tx_forward_nsamps), 
				&txdata[tx_cnt*samples_per_packets], 
				samples_per_packets, 
				1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1434
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1435
	/*
Raymond Knopp's avatar
 
Raymond Knopp committed
1436 1437 1438
	// Grab remaining 3/4 of RX buffer
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,1);
	rxs = openair0.trx_read_func(&openair0, 
Raymond Knopp's avatar
 
Raymond Knopp committed
1439 1440 1441
	&timestamp, 
	&rxdata[(rx_cnt*samples_per_packets)+(samples_per_packets>>2)], 
	3*((samples_per_packets>>2)));
Raymond Knopp's avatar
 
Raymond Knopp committed
1442 1443
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,0);
	if (rxs != (3*(samples_per_packets>>2)))
Raymond Knopp's avatar
 
Raymond Knopp committed
1444
	oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1445
	*/
Raymond Knopp's avatar
 
Raymond Knopp committed
1446 1447 1448 1449 1450 1451 1452 1453 1454
#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
1455
	      //	      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
1456 1457 1458 1459 1460 1461 1462 1463
	      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
1464
		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
1465 1466 1467 1468 1469
		oai_exit=1;
	      }
	    }
	  }
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
1470 1471
	rx_cnt++;
	tx_cnt++;
Raymond Knopp's avatar
 
Raymond Knopp committed
1472 1473 1474

	if(tx_cnt == max_cnt)
	  tx_cnt = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1475 1476
      }

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1485

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




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


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

Raymond Knopp's avatar
 
Raymond Knopp committed
1598 1599 1600 1601 1602

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

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

static void *UE_thread_synch(void *arg) {

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

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

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

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

	//	    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
1733 1734 1735 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
    
  }  // 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
1800
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1801
  PHY_VARS_UE *UE = (PHY_VARS_UE*)arg;
Raymond Knopp's avatar
 
Raymond Knopp committed
1802 1803
  int i;
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1804
  UE->instance_cnt_rx=-1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1805
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1806
  mlockall(MCL_CURRENT | MCL_FUTURE);
Raymond Knopp's avatar
 
Raymond Knopp committed
1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819
  
#ifdef USRP
  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");
  pthread_cond_wait(&sync_cond, &sync_mutex);
  pthread_mutex_unlock(&sync_mutex);
  printf("unlocked sync_mutex, waiting (UE_thread_rx)\n");
#endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1820

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1877 1878 1879



1880
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
1881 1882 1883 1884 1885
#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
1886

Raymond Knopp's avatar
 
Raymond Knopp committed
1887 1888 1889
  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
1890
  // unsigned int aa;
Raymond Knopp's avatar
 
Raymond Knopp committed
1891 1892 1893 1894 1895 1896 1897 1898 1899
  int dummy[samples_per_packets];
  int dummy_dump = 0;
  int tx_enabled=0;
  int start_rx_stream=0;
  int rx_off_diff = 0;
  int rx_correction_timer = 0;

  openair0_timestamp time0,time1;
  unsigned int rxs;
Raymond Knopp's avatar
 
Raymond Knopp committed
1900

Raymond Knopp's avatar
 
Raymond Knopp committed
1901
  printf("waiting for USRP sync (UE_thread)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1902 1903 1904
#ifdef RTAI
  rt_sem_wait(sync_sem);
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1905 1906
  pthread_mutex_lock(&sync_mutex);
  printf("Locked sync_mutex, waiting (UE_thread)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1907
  pthread_cond_wait(&sync_cond, &sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
1908 1909
  pthread_mutex_unlock(&sync_mutex);
  printf("unlocked sync_mutex, waiting (UE_thread)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1910
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1911 1912 1913 1914

  printf("starting UE thread\n");

  T0 = rt_get_time_ns();
Raymond Knopp's avatar
 
Raymond Knopp committed
1915 1916 1917
  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
1918

Raymond Knopp's avatar
 
Raymond Knopp committed
1919

Raymond Knopp's avatar
 
Raymond Knopp committed
1920
    while (rx_cnt < sf_bounds[hw_subframe]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1921
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1922
      vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1923 1924 1925 1926 1927 1928 1929
  
#ifndef USRP_DEBUG
      rxs = openair0.trx_read_func(&openair0,
				   &timestamp,
				   (dummy_dump==0) ? &rxdata[rx_cnt*samples_per_packets] : dummy,
				   samples_per_packets - ((rx_cnt==0) ? rx_off_diff : 0));
      if (rxs != (samples_per_packets- ((rx_cnt==0) ? rx_off_diff : 0)))
Raymond Knopp's avatar
 
Raymond Knopp committed
1930
	oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1931 1932

      rx_off_diff = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1933 1934 1935
      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
1936
      if (tx_enabled) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1937
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1938 1939 1940 1941
	openair0.trx_write_func(&openair0,
				(timestamp+samples_per_packets*tx_delay-tx_forward_nsamps),
				&txdata[tx_cnt*samples_per_packets],
				samples_per_packets,
Raymond Knopp's avatar
 
Raymond Knopp committed
1942 1943 1944
				1);
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,0);
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1945 1946 1947
#else
      rt_sleep_ns(10000000);
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1948 1949 1950 1951 1952 1953 1954 1955
      rx_cnt++;
      tx_cnt++;
      
      if(tx_cnt == max_cnt)
	tx_cnt = 0;
    }
    
    if(rx_cnt == max_cnt)
Raymond Knopp's avatar
 
Raymond Knopp committed
1956 1957 1958
      rx_cnt = 0;


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

Raymond Knopp's avatar
 
Raymond Knopp committed
2088 2089


Raymond Knopp's avatar
 
Raymond Knopp committed
2090
#ifndef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
2091 2092
/* 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) {
2093
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2094 2095 2096
  RT_TASK *task;
#endif
  // RTIME in, out, diff;
Raymond Knopp's avatar
 
Raymond Knopp committed
2097
  int slot=0,frame=0,hw_slot,last_slot,next_slot;
Raymond Knopp's avatar
 
Raymond Knopp committed
2098 2099 2100 2101 2102 2103 2104
  // 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;
2105
  int CC_id,card;
Raymond Knopp's avatar
 
Raymond Knopp committed
2106 2107
  volatile unsigned int *DAQ_MBOX = openair0_daq_cnt();
#ifndef USRP
2108
  //exmimo_config_t *p_exmimo_config = openair0_exmimo_pci[card].exmimo_config_ptr;;
Raymond Knopp's avatar
 
Raymond Knopp committed
2109 2110
#endif

2111

2112
#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
Raymond Knopp's avatar
 
Raymond Knopp committed
2113 2114
  /* Wait for NAS UE to start cell selection */
  wait_system_ready ("Waiting for UE to be activated by UserProcess %s\r", &start_UE);
2115 2116
#endif

2117
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2118 2119
  task = rt_task_init_schmod(nam2num("TASK0"), 0, 0, 0, SCHED_FIFO, 0xF);
  LOG_D(HW,"Started UE thread (id %p)\n",task);
2120 2121 2122
#endif

#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
2123
  rt_make_hard_real_time();
2124 2125
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2126
  mlockall(MCL_CURRENT | MCL_FUTURE);
2127

Raymond Knopp's avatar
 
Raymond Knopp committed
2128 2129 2130 2131 2132 2133 2134 2135
  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;
    }
2136
    openair0_dump_config(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
2137 2138 2139
    }
  */
  while (!oai_exit)  {
Raymond Knopp's avatar
 
Raymond Knopp committed
2140

Raymond Knopp's avatar
 
Raymond Knopp committed
2141
    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
2142 2143

     
Raymond Knopp's avatar
 
Raymond Knopp committed
2144
    if (is_synchronized) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2145 2146


Raymond Knopp's avatar
 
Raymond Knopp committed
2147
      //this is the mbox counter that indicates the start of the frame
Raymond Knopp's avatar
 
Raymond Knopp committed
2148
      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
2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161
      //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;
2162
	
Raymond Knopp's avatar
 
Raymond Knopp committed
2163 2164 2165 2166 2167 2168 2169 2170
      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
2171
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195
	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);
2196
	  
Raymond Knopp's avatar
 
Raymond Knopp committed
2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221
	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;
2222 2223 2224 2225 2226 2227 2228 2229

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

#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
2318
  rt_make_soft_real_time();
2319 2320
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2321
  // clean task
2322
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2323
  rt_task_delete(task);
2324
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2325 2326 2327
  LOG_D(HW,"Task deleted. returning\n");
  return 0;
}
2328

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

2331
#endif
2332

2333

Raymond Knopp's avatar
 
Raymond Knopp committed
2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375
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;

#ifdef USRP
  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
2376
}
Raymond Knopp's avatar
 
Raymond Knopp committed
2377 2378


Raymond Knopp's avatar
 
Raymond Knopp committed
2379
static void get_options (int argc, char **argv) {
2380
  int c;
Raymond Knopp's avatar
 
Raymond Knopp committed
2381 2382
  //  char                          line[1000];
  //  int                           l;
2383
  int k;//i,j,k;
Raymond Knopp's avatar
 
Raymond Knopp committed
2384 2385 2386
#ifdef USRP
  int clock_src;
#endif
2387 2388
  int CC_id;

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

      clock_src = atoi(optarg);
      if (clock_src == 0) {
2527
	//	char ref[128] = "internal";
Raymond Knopp's avatar
 
Raymond Knopp committed
2528 2529 2530
	//strncpy(uhd_ref, ref, strlen(ref)+1);
      }
      else if (clock_src == 1) {
2531
	//char ref[128] = "external";
Raymond Knopp's avatar
 
Raymond Knopp committed
2532 2533
	//strncpy(uhd_ref, ref, strlen(ref)+1);
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2534 2535 2536 2537
#else
      printf("Note: -s not defined for ExpressMIMO2\n");
#endif
      break;
2538
    case 'g':
Raymond Knopp's avatar
 
Raymond Knopp committed
2539
      glog_level=atoi(optarg); // value between 1 - 9
2540 2541 2542 2543
      break;
    case 'G':
      glog_verbosity=atoi(optarg);// value from 0, 0x5, 0x15, 0x35, 0x75
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
2544 2545
    default:
      break;
2546 2547
    }
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559
  
  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);
2560

Raymond Knopp's avatar
 
Raymond Knopp committed
2561
    /* Update some simulation parameters */
2562
    for (i=0; i < enb_properties->number; i++) {
2563 2564 2565 2566
      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
2567 2568 2569 2570 2571 2572
      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
2573
	//for (j=0; j < enb_properties->properties[i]->nb_cc; j++ ){
2574
	frame_parms[CC_id]->Nid_cell          =  enb_properties->properties[i]->Nid_cell[CC_id];
Raymond Knopp's avatar
 
Raymond Knopp committed
2575
	frame_parms[CC_id]->N_RB_DL          =  enb_properties->properties[i]->N_RB_DL[CC_id];
2576
	//} // j
Raymond Knopp's avatar
 
Raymond Knopp committed
2577 2578
      }

2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594
      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;
    
    
Raymond Knopp's avatar
 
Raymond Knopp committed
2595
      // adjust the log
2596 2597 2598 2599 2600
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
	for (k = 0 ; k < 4; k++) {
	  downlink_frequency[CC_id][k] =       enb_properties->properties[i]->downlink_frequency[CC_id];
	  uplink_frequency_offset[CC_id][k] =  enb_properties->properties[i]->uplink_frequency_offset[CC_id];
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
2601
	printf("Downlink frequency/ uplink offset of CC_id %d set to %llu/%d\n", CC_id,
2602 2603
	       enb_properties->properties[i]->downlink_frequency[CC_id],
	       enb_properties->properties[i]->uplink_frequency_offset[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
2604
      } // CC_id
2605
    }// i
Raymond Knopp's avatar
 
Raymond Knopp committed
2606 2607
  }
}
2608

Raymond Knopp's avatar
 
Raymond Knopp committed
2609
int main(int argc, char **argv) {
2610
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2611
  // RT_TASK *task;
Raymond Knopp's avatar
 
Raymond Knopp committed
2612
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
2613
  int *eNB_thread_status_p;
Raymond Knopp's avatar
 
Raymond Knopp committed
2614
  //  int *eNB_thread_status_rx[10],*eNB_thread_status_tx[10];
2615
#endif
2616 2617
  int i,j,aa,card;
#if defined (XFORMS) || defined (EMOS) || (! defined (RTAI)) || defined (SPECTRA)
Raymond Knopp's avatar
 
Raymond Knopp committed
2618
  void *status;
2619
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2620
  
Raymond Knopp's avatar
 
Raymond Knopp committed
2621
  int CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
2622 2623
  uint16_t Nid_cell = 0;
  uint8_t  cooperation_flag=0, transmission_mode=1, abstraction_flag=0;
2624
#ifndef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
2625
  uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
2626 2627 2628
#endif

#ifdef ENABLE_TCXO
Raymond Knopp's avatar
 
Raymond Knopp committed
2629
  unsigned int tcxo = 114;
2630 2631
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2632
  //  int amp;
Raymond Knopp's avatar
 
Raymond Knopp committed
2633 2634
  // uint8_t prach_fmt;
  // int N_ZC;
2635

Raymond Knopp's avatar
 
Raymond Knopp committed
2636
  //  int ret, ant;
Raymond Knopp's avatar
 
Raymond Knopp committed
2637
  int ant_offset=0;
2638
#if defined (XFORMS) || defined (SPECTRA)
2639 2640
  int ret;
#endif
2641
#if defined (EMOS) || (! defined (RTAI))
Raymond Knopp's avatar
 
Raymond Knopp committed
2642
  int error_code;
2643
#endif
2644 2645

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

Raymond Knopp's avatar
 
Raymond Knopp committed
2647
  set_latency_target();
2648

Raymond Knopp's avatar
 
Raymond Knopp committed
2649
  mode = normal_txrx;
2650

Raymond Knopp's avatar
 
Raymond Knopp committed
2651 2652 2653
  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
2654
    frame_parms[CC_id]->frame_type         = FDD; /* TDD */
Raymond Knopp's avatar
 
Raymond Knopp committed
2655 2656 2657 2658
    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
2659
    frame_parms[CC_id]->Ncp                 = NORMAL;
Raymond Knopp's avatar
 
Raymond Knopp committed
2660 2661
    frame_parms[CC_id]->Ncp_UL              = NORMAL;
    frame_parms[CC_id]->Nid_cell            = Nid_cell;
Raymond Knopp's avatar
 
Raymond Knopp committed
2662
    frame_parms[CC_id]->num_MBSFN_config    = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2663
  }
2664

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

Raymond Knopp's avatar
 
Raymond Knopp committed
2667 2668
  //randominit (0);
  set_taus_seed (0);
winckel's avatar
winckel committed
2669

Raymond Knopp's avatar
 
Raymond Knopp committed
2670 2671 2672
  // initialize the log (see log.h for details)
  logInit();

2673
  set_glog(glog_level, glog_verbosity);
Raymond Knopp's avatar
 
Raymond Knopp committed
2674 2675 2676
  if (UE_flag==1)
    {
      printf("configuring for UE\n");
2677

2678
      set_comp_log(HW,      LOG_DEBUG,  LOG_HIGH, 1);
2679
#ifdef OPENAIR2
2680
      set_comp_log(PHY,     LOG_DEBUG,   LOG_HIGH, 1);
2681
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
2682
      set_comp_log(PHY,     LOG_INFO,   LOG_HIGH, 1);
2683
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2684 2685 2686 2687 2688
      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);
2689
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
2690
      set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
2691
# if defined(ENABLE_USE_MME)
Raymond Knopp's avatar
 
Raymond Knopp committed
2692
      set_comp_log(NAS,     LOG_INFO,   LOG_HIGH, 1);
2693 2694
# endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2695 2696 2697 2698
    }
  else
    {
      printf("configuring for eNB\n");
2699

2700
      set_comp_log(HW,      hw_log_level, hw_log_verbosity, 1);
2701
#ifdef OPENAIR2
2702
      set_comp_log(PHY,     phy_log_level,   phy_log_verbosity, 1);
2703
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
2704
      set_comp_log(PHY,     LOG_INFO,   LOG_HIGH, 1);
2705
#endif
2706 2707 2708 2709
      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);
2710
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
2711
      set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
2712
# if defined(ENABLE_USE_MME)
Raymond Knopp's avatar
 
Raymond Knopp committed
2713 2714 2715 2716
      set_comp_log(UDP_,    LOG_DEBUG,   LOG_HIGH, 1);
      set_comp_log(GTPU,    LOG_DEBUG,   LOG_HIGH, 1);
      set_comp_log(S1AP,    LOG_DEBUG,   LOG_HIGH, 1);
      set_comp_log(SCTP,    LOG_INFO,   LOG_HIGH, 1);
2717
# endif
2718
#if defined(ENABLE_SECURITY)
Raymond Knopp's avatar
 
Raymond Knopp committed
2719
      set_comp_log(OSA,    LOG_DEBUG,   LOG_HIGH, 1);
2720
#endif
2721
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2722
      set_comp_log(ENB_APP, LOG_INFO, LOG_HIGH, 1);
2723
      set_comp_log(OTG,     LOG_INFO,   LOG_HIGH, 1);
Raymond Knopp's avatar
 
Raymond Knopp committed
2724 2725 2726
      if (online_log_messages == 1) { 
	set_component_filelog(RRC);
	set_component_filelog(PDCP);
Raymond Knopp's avatar
 
Raymond Knopp committed
2727 2728
      }
    }
2729

Raymond Knopp's avatar
 
Raymond Knopp committed
2730 2731 2732 2733 2734 2735 2736
  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");
  }

2737
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
2738 2739 2740 2741 2742 2743
  if (UE_flag == 1) {
    log_set_instance_type (LOG_INSTANCE_UE);
  }
  else {
    log_set_instance_type (LOG_INSTANCE_ENB);
  }
2744

Raymond Knopp's avatar
 
Raymond Knopp committed
2745
  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
2746 2747
#endif

2748
#ifdef NAS_NETLINK
Raymond Knopp's avatar
 
Raymond Knopp committed
2749
  netlink_init();
2750 2751
#endif

2752
#if !defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
2753 2754 2755
  // to make a graceful exit when ctrl-c is pressed
  signal(SIGSEGV, signal_handler);
  signal(SIGINT, signal_handler);
2756
#endif
2757 2758

#ifndef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2759 2760 2761 2762
  check_clock();
#endif

  // init the parameters
Raymond Knopp's avatar
 
Raymond Knopp committed
2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781
  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    frame_parms[CC_id]->nushift            = 0;
    if (UE_flag==0)
      {
	switch (transmission_mode) {
	case 1: 
	  frame_parms[CC_id]->nb_antennas_tx     = 1;
	  frame_parms[CC_id]->nb_antennas_rx     = 1;
	  break;
	case 2:
	case 5:
	case 6:
	  frame_parms[CC_id]->nb_antennas_tx     = 2;
	  frame_parms[CC_id]->nb_antennas_rx     = 2;
	  break;
	default:
	  printf("Unsupported transmission mode %d\n",transmission_mode);
	  exit(-1);
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
2782
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796
    else
      { //UE_flag==1
	frame_parms[CC_id]->nb_antennas_tx     = 1;
	frame_parms[CC_id]->nb_antennas_rx     = 1;
      }
    frame_parms[CC_id]->nb_antennas_tx_eNB = (transmission_mode == 1) ? 1 : 2; //initial value overwritten by initial sync later
    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;
2797 2798
    init_ul_hopping(frame_parms[CC_id]);
    init_frame_parms(frame_parms[CC_id],1);
2799
    phy_init_top(frame_parms[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811
  }

  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
2812
    // N_ZC = (prach_fmt <4)?839:139;
Raymond Knopp's avatar
 
Raymond Knopp committed
2813
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
2814 2815

  if (UE_flag==1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2816 2817 2818
    NB_UE_INST=1;
    NB_INST=1;

Raymond Knopp's avatar
 
Raymond Knopp committed
2819 2820 2821
    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++) {
2822
      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
2823
      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
2824 2825
#ifndef OPENAIR2
      for (i=0;i<NUMBER_OF_eNB_MAX;i++) {
2826 2827 2828
	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
2829
	
2830 2831 2832
	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
2833
      }
2834
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2835
      
2836 2837 2838
      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
2839
      
2840
      PHY_vars_UE_g[0][CC_id]->lte_ue_pdcch_vars[0]->crnti = 0x1234;
2841
#ifndef OPENAIR2
2842
      PHY_vars_UE_g[0][CC_id]->lte_ue_pdcch_vars[0]->crnti = 0x1235;
2843
#endif
2844 2845
    
#ifndef USRP    
Raymond Knopp's avatar
 
Raymond Knopp committed
2846 2847 2848 2849 2850
      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];
      }
2851

Raymond Knopp's avatar
 
Raymond Knopp committed
2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866
      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;
      }
2867
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
2868
      PHY_vars_UE_g[0][CC_id]->rx_total_gain_dB =  (int)rx_gain[CC_id][0]; 
2869
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2870
    
Raymond Knopp's avatar
 
Raymond Knopp committed
2871
      PHY_vars_UE_g[0][CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
Raymond Knopp's avatar
 
Raymond Knopp committed
2872
    
2873

2874 2875
   
#ifndef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887
      //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;
      }
2888
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
2889 2890
      //already taken care of in lte-softmodem
      PHY_vars_UE_g[UE_id][CC_id]->N_TA_offset = 0;
2891
#endif 
Raymond Knopp's avatar
 
Raymond Knopp committed
2892
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
2893 2894 2895 2896 2897
    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;
    
2898
  
Raymond Knopp's avatar
 
Raymond Knopp committed
2899 2900 2901 2902 2903
    
    //  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
2904 2905 2906
      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
2907
	PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],eNB_id,Nid_cell,cooperation_flag,transmission_mode,abstraction_flag);
2908
	PHY_vars_eNB_g[0][CC_id]->CC_id = CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
2909
       
2910
#ifndef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
2911 2912 2913 2914 2915 2916 2917 2918 2919
	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
2920
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2921 2922 2923 2924
      
	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
2925

2926
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
2927

Raymond Knopp's avatar
 
Raymond Knopp committed
2928
	PHY_vars_eNB_g[0][CC_id]->rx_total_gain_eNB_dB =  135; //(int)rx_gain[CC_id][0];
Raymond Knopp's avatar
 
Raymond Knopp committed
2929

2930
#else
2931
	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
2932 2933 2934

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

2935 2936
	// set eNB to max gain
	for (i=0;i<4;i++)
2937 2938
	  rx_gain_mode[CC_id][i] = max_gain;
#endif
2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957

#ifndef USRP
	//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
2958
      }
2959 2960


Raymond Knopp's avatar
 
Raymond Knopp committed
2961 2962
      NB_eNB_INST=1;
      NB_INST=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
2963

Raymond Knopp's avatar
 
Raymond Knopp committed
2964
      openair_daq_vars.ue_dl_rb_alloc=0x1fff;
2965
      openair_daq_vars.target_ue_dl_mcs=target_dl_mcs;
Raymond Knopp's avatar
 
Raymond Knopp committed
2966
      openair_daq_vars.ue_ul_nb_rb=6;
2967
      openair_daq_vars.target_ue_ul_mcs=target_ul_mcs;
Raymond Knopp's avatar
 
Raymond Knopp committed
2968 2969

    }
2970

2971

2972

Raymond Knopp's avatar
 
Raymond Knopp committed
2973
  dump_frame_parms(frame_parms[0]);
2974

Raymond Knopp's avatar
 
Raymond Knopp committed
2975
  if(frame_parms[0]->N_RB_DL == 100) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2976 2977 2978 2979 2980 2981 2982
    sample_rate = 30.72e6;
#ifdef USRP
    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
2983
    sf_bounds_tx = sf_bounds_20_tx;
Raymond Knopp's avatar
 
Raymond Knopp committed
2984
    max_cnt = 150;
2985
    tx_delay = 8;
Raymond Knopp's avatar
 
Raymond Knopp committed
2986 2987
#endif
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
2988
  else if(frame_parms[0]->N_RB_DL == 50){
2989
    sample_rate = 15.36e6;
Raymond Knopp's avatar
 
Raymond Knopp committed
2990 2991 2992 2993 2994
#ifdef USRP
    samples_per_packets = 2048;
    samples_per_frame = 153600;
    tx_forward_nsamps = 95;
    sf_bounds = sf_bounds_10;
Raymond Knopp's avatar
 
Raymond Knopp committed
2995
    sf_bounds_tx = sf_bounds_10_tx;
Raymond Knopp's avatar
 
Raymond Knopp committed
2996 2997 2998 2999
    max_cnt = 75;
    tx_delay = 4;
#endif
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3000
  else if (frame_parms[0]->N_RB_DL == 25) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3001 3002 3003 3004 3005 3006
    sample_rate = 7.68e6;
#ifdef USRP
    samples_per_packets = 1024;
    samples_per_frame = 76800;
    tx_forward_nsamps = 70;
    sf_bounds = sf_bounds_5;
Raymond Knopp's avatar
 
Raymond Knopp committed
3007
    sf_bounds_tx = sf_bounds_5_tx;
Raymond Knopp's avatar
 
Raymond Knopp committed
3008
    max_cnt = 75;
Raymond Knopp's avatar
 
Raymond Knopp committed
3009
    tx_delay = 5;
Raymond Knopp's avatar
 
Raymond Knopp committed
3010 3011 3012
#endif
  }
  
3013

3014 3015 3016 3017
  for (card=0;card<MAX_CARDS;card++) {
    openair0_cfg[card].sample_rate = sample_rate;
    openair0_cfg[card].tx_bw = bw;
    openair0_cfg[card].rx_bw = bw;
3018 3019 3020
    // 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
3021
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
3022 3023
    openair0_cfg[card].tx_num_channels=1;
    openair0_cfg[card].rx_num_channels=1;
3024 3025
    for (i=0;i<4;i++) {
      openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
Raymond Knopp's avatar
 
Raymond Knopp committed
3026 3027
      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
3028 3029
      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
3030
    }
3031
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3032
  }
3033

Raymond Knopp's avatar
 
Raymond Knopp committed
3034
#ifndef USRP_DEBUG 
3035
  if (openair0_device_init(&openair0, &openair0_cfg[0]) <0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3036 3037 3038
    printf("Exiting, cannot initialize device\n");
    exit(-1);
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3039
#endif
3040 3041 3042

  mac_xface = malloc(sizeof(MAC_xface));

3043
#ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3044
  int eMBMS_active=0;
3045

3046
  l2_init(frame_parms[0],eMBMS_active,
Raymond Knopp's avatar
 
Raymond Knopp committed
3047 3048 3049 3050 3051 3052
	  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);
3053 3054
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3055
  mac_xface->macphy_exit = &exit_fun;
3056

winckel's avatar
winckel committed
3057
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
3058
  if (create_tasks(UE_flag ? 0 : 1, UE_flag ? 1 : 0) < 0) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
3059
    printf("cannot create ITTI tasks\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
3060 3061 3062
    exit(-1); // need a softer mode
  }
  printf("ITTI tasks created\n");
winckel's avatar
winckel committed
3063 3064
#endif

3065
#ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076
  //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
3077
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3078 3079 3080
  }
  init_predef_traffic(UE_flag ? 1 : 0, UE_flag ? 0 : 1);
  //  }
3081 3082
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3083
  //  number_of_cards = openair0_num_detected_cards;
3084

Raymond Knopp's avatar
 
Raymond Knopp committed
3085
  openair_daq_vars.timing_advance = 0;
3086

Florian Kaltenberger's avatar
Florian Kaltenberger committed
3087 3088
  for(CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    rf_map[CC_id].card=0;
3089
    rf_map[CC_id].chain=CC_id+1;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
3090
  }
3091

Raymond Knopp's avatar
 
Raymond Knopp committed
3092 3093
  // connect the TX/RX buffers
  if (UE_flag==1) {
3094 3095 3096 3097
    if (setup_ue_buffers(PHY_vars_UE_g[0],&openair0_cfg[0],rf_map)!=0) {
      printf("Error setting up eNB buffer\n");
      exit(-1);
    }
3098 3099
    printf("Setting UE buffer to all-RX\n");
    // Set LSBs for antenna switch (ExpressMIMO)
Raymond Knopp's avatar
 
Raymond Knopp committed
3100
    for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3101
      for (i=0; i<frame_parms[CC_id]->samples_per_tti*10; i++)
3102
	for (aa=0; aa<frame_parms[CC_id]->nb_antennas_tx; aa++)
3103
	  PHY_vars_UE_g[0][CC_id]->lte_ue_common_vars.txdata[aa][i] = 0x00010001;
Raymond Knopp's avatar
 
Raymond Knopp committed
3104
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3105 3106 3107
    //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX;
  }
  else {
3108 3109 3110 3111 3112 3113
    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
3114
    for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3115 3116
      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++)
3117
	  PHY_vars_eNB_g[0][CC_id]->lte_eNB_common_vars.txdata[0][aa][i] = 0x00010001;
Raymond Knopp's avatar
 
Raymond Knopp committed
3118
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3119
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3120
#ifndef USRP
3121
  openair0_config(&openair0_cfg[0],UE_flag);
Raymond Knopp's avatar
 
Raymond Knopp committed
3122 3123
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3124
  /*  
Raymond Knopp's avatar
 
Raymond Knopp committed
3125 3126
      for (ant=0;ant<4;ant++)
      p_exmimo_config->rf.do_autocal[ant] = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3127
  */
3128 3129

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3130 3131 3132 3133 3134 3135 3136 3137 3138
  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);
3139 3140
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3141
  mlockall(MCL_CURRENT | MCL_FUTURE);
3142 3143

#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164
  // 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);
Raymond Knopp's avatar
 
Raymond Knopp committed
3165 3166 3167 3168 3169 3170 3171 3172 3173 3174
#ifdef USRP
  sync_sem = rt_typed_sem_init(nam2num("syncsem"), 0, BIN_SEM|FIFO_Q);
  if(sync_sem == 0)
    printf("error init sync semphore\n");
#endif
#else
#ifdef USRP
  pthread_cond_init(&sync_cond,NULL);
  pthread_mutex_init(&sync_mutex, NULL);
#endif
3175 3176 3177
#endif


Raymond Knopp's avatar
 
Raymond Knopp committed
3178 3179

  // this starts the DMA transfers
Raymond Knopp's avatar
 
Raymond Knopp committed
3180
#ifndef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
3181
  if (UE_flag!=1)
3182 3183
    for (card=0;card<openair0_num_detected_cards;card++)
      openair0_start_rt_acquisition(card);
Raymond Knopp's avatar
 
Raymond Knopp committed
3184
#endif
3185 3186

#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
3187 3188 3189 3190 3191 3192 3193 3194
  if (do_forms==1) {
    fl_initialize (&argc, argv, NULL, 0, 0);
    form_stats = create_form_stats_form();
    if (UE_flag==1) {
      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);
    } else {
3195
      form_stats_l2 = create_form_stats_form();
Raymond Knopp's avatar
 
Raymond Knopp committed
3196 3197 3198 3199
      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);
3200
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3201 3202 3203
    }
    fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
    if (UE_flag==0) {
3204 3205
      fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats");

Raymond Knopp's avatar
 
Raymond Knopp committed
3206 3207 3208 3209
      for (UE_id=0;UE_id<scope_enb_num_ue;UE_id++) {
	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
3210 3211
	}
	else {
Raymond Knopp's avatar
 
Raymond Knopp committed
3212 3213
	  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
3214
	}
3215 3216
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227
    else {
      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
3228
    ret = pthread_create(&forms_thread, NULL, scope_thread, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
3229 3230
    printf("Scope thread created, ret=%d\n",ret);
  }
3231 3232 3233
#endif

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3234 3235
  ret = pthread_create(&thread3, NULL, emos_thread, NULL);
  printf("EMOS thread created, ret=%d\n",ret);
3236 3237
#endif

3238 3239 3240 3241 3242
#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
3243
  rt_sleep_ns(10*FRAME_PERIOD);
3244 3245

#ifndef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3246 3247 3248 3249 3250
  pthread_attr_init (&attr_dlsch_threads);
  pthread_attr_setstacksize(&attr_dlsch_threads,OPENAIR_THREAD_STACK_SIZE);
  sched_param_dlsch.sched_priority = 90;//sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY;
  pthread_attr_setschedparam  (&attr_dlsch_threads, &sched_param_dlsch);
  pthread_attr_setschedpolicy (&attr_dlsch_threads, SCHED_FIFO);
Raymond Knopp's avatar
 
Raymond Knopp committed
3251 3252 3253 3254 3255 3256 3257

  pthread_attr_init (&attr_UE_init_synch);
  pthread_attr_setstacksize(&attr_UE_init_synch,OPENAIR_THREAD_STACK_SIZE);
  sched_param_UE_init_synch.sched_priority = 90;//sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY;
  pthread_attr_setschedparam  (&attr_UE_init_synch, &sched_param_UE_init_synch);
  pthread_attr_setschedpolicy (&attr_UE_init_synch, SCHED_FIFO);

3258 3259
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3260 3261
  // start the main thread
  if (UE_flag == 1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3262
    init_UE_threads();
3263
    sleep(1);
3264
#ifdef RTAI
3265
    main_ue_thread = rt_thread_create(UE_thread, NULL, 100000000);
3266
#else
3267
    error_code = pthread_create(&main_ue_thread, &attr_dlsch_threads, UE_thread, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
3268 3269 3270 3271 3272 3273 3274
    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");
    }
3275 3276
#endif
#ifdef DLSCH_THREAD
Raymond Knopp's avatar
 
Raymond Knopp committed
3277 3278 3279
    init_rx_pdsch_thread();
    rt_sleep_ns(FRAME_PERIOD/10);
    init_dlsch_threads();
3280
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3281 3282 3283
    printf("UE threads created\n");
  }
  else {
3284

Raymond Knopp's avatar
 
Raymond Knopp committed
3285 3286
    if (multi_thread>0) {
      init_eNB_proc();
3287
      sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3288 3289
      LOG_D(HW,"[lte-softmodem.c] eNB threads created\n");
    }
3290
    printf("Creating main eNB_thread \n");
Raymond Knopp's avatar
 
Raymond Knopp committed
3291
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3292
    main_eNB_thread = rt_thread_create(eNB_thread, NULL, OPENAIR_THREAD_STACK_SIZE);
Raymond Knopp's avatar
 
Raymond Knopp committed
3293
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3294
    error_code = pthread_create(&main_eNB_thread, &attr_dlsch_threads, eNB_thread, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
3295 3296 3297 3298 3299 3300
    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
3301
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3302 3303
#endif
  }
3304

Raymond Knopp's avatar
 
Raymond Knopp committed
3305
  // Sleep to allow all threads to setup
3306
  sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3307

Raymond Knopp's avatar
 
Raymond Knopp committed
3308

Raymond Knopp's avatar
 
Raymond Knopp committed
3309
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
3310
#ifndef USRP_DEBUG
Raymond Knopp's avatar
 
Raymond Knopp committed
3311
  openair0.trx_start_func(&openair0);
Raymond Knopp's avatar
 
Raymond Knopp committed
3312
  //  printf("returning from usrp start streaming: %llu\n",get_usrp_time(&openair0));
Raymond Knopp's avatar
 
Raymond Knopp committed
3313
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3314 3315 3316
#ifdef RTAI
  rt_sem_signal(sync_sem);
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3317 3318 3319 3320
  pthread_mutex_lock(&sync_mutex);
  printf("Sending sync ...\n");
  pthread_cond_broadcast(&sync_cond);
  pthread_mutex_unlock(&sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
3321 3322
#endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3323 3324 3325
  // wait for end of program
  printf("TYPE <CTRL-C> TO TERMINATE\n");
  //getchar();
3326 3327

#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
3328 3329
  printf("Entering ITTI signals handler\n");
  itti_wait_tasks_end();
3330
  oai_exit=1;
3331
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3332 3333
  while (oai_exit==0)
    rt_sleep_ns(FRAME_PERIOD);
3334
#endif
3335

Raymond Knopp's avatar
 
Raymond Knopp committed
3336
  // stop threads
3337
#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
3338 3339 3340
  printf("waiting for XFORMS thread\n");
  if (do_forms==1)
    {
Raymond Knopp's avatar
 
Raymond Knopp committed
3341
      pthread_join(forms_thread,&status);
Raymond Knopp's avatar
 
Raymond Knopp committed
3342 3343 3344 3345 3346 3347
      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 {
3348 3349
	fl_hide_form(form_stats_l2->stats_form);
	fl_free_form(form_stats_l2->stats_form);
Raymond Knopp's avatar
 
Raymond Knopp committed
3350 3351 3352 3353
	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
3354
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3355
    }
3356 3357
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3358 3359 3360 3361
  printf("stopping MODEM threads\n");
  // cleanup
  if (UE_flag == 1) {
#ifndef USRP
3362
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3363
    rt_thread_join(main_ue_thread); 
3364
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3365
    pthread_join(main_ue_thread,&status); 
3366 3367
#endif
#ifdef DLSCH_THREAD
Raymond Knopp's avatar
 
Raymond Knopp committed
3368 3369
    cleanup_dlsch_threads();
    cleanup_rx_pdsch_thread();
3370
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3371 3372 3373
#endif
  }
  else {
Raymond Knopp's avatar
 
Raymond Knopp committed
3374
#ifdef DEBUG_THREADS
Raymond Knopp's avatar
 
Raymond Knopp committed
3375
    printf("Joining eNB_thread ...");
Raymond Knopp's avatar
 
Raymond Knopp committed
3376
#endif
3377 3378 3379
#ifdef RTAI
    rt_thread_join(main_eNB_thread); 
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3380
    pthread_join(main_eNB_thread,(void**)&eNB_thread_status_p); 
Raymond Knopp's avatar
 
Raymond Knopp committed
3381
#ifdef DEBUG_THREADS
Raymond Knopp's avatar
 
Raymond Knopp committed
3382
    printf("status %d\n",*eNB_thread_status_p);
Raymond Knopp's avatar
 
Raymond Knopp committed
3383
#endif
3384
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3385

Raymond Knopp's avatar
 
Raymond Knopp committed
3386 3387 3388
    if (multi_thread>0) {
      printf("Killing eNB processing threads\n");
      kill_eNB_proc();
Raymond Knopp's avatar
 
Raymond Knopp committed
3389

Raymond Knopp's avatar
 
Raymond Knopp committed
3390
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3391
  }
3392

3393
#ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3394
  //cleanup_pdcp_thread();
3395 3396
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3397
#ifdef USRP
3398
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3399
  rt_sem_delete(sync_sem);
Raymond Knopp's avatar
 
Raymond Knopp committed
3400
  stop_rt_timer();
Raymond Knopp's avatar
 
Raymond Knopp committed
3401 3402 3403
#else
  pthread_cond_destroy(&sync_cond);
  pthread_mutex_destroy(&sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
3404
#endif
3405 3406
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3407
#ifndef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
3408
  printf("stopping card\n");
3409
  openair0_stop(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
3410 3411
  printf("closing openair0_lib\n");
  openair0_close();
Raymond Knopp's avatar
 
Raymond Knopp committed
3412
#endif
3413 3414

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3415 3416 3417
  printf("waiting for EMOS thread\n");
  pthread_cancel(thread3);
  pthread_join(thread3,&status);
3418 3419 3420
#endif

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3421 3422
  error_code = rtf_destroy(CHANSOUNDER_FIFO_MINOR);
  printf("[OPENAIR][SCHED][CLEANUP] EMOS FIFO closed, error_code %d\n", error_code);
3423 3424
#endif

3425 3426 3427 3428 3429 3430
#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
3431 3432
  if (ouput_vcd)
    vcd_signal_dumper_close();
3433

Raymond Knopp's avatar
 
Raymond Knopp committed
3434
  logClean();
3435

Raymond Knopp's avatar
 
Raymond Knopp committed
3436 3437
  return 0;
}
3438

3439 3440
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
3441 3442 3443 3444 3445

#ifdef USRP
  uint16_t N_TA_offset = 0;
#endif

3446 3447 3448 3449 3450
  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
3451
    }
3452 3453 3454
    else {
      printf("phy_vars_eNB[%d] not initialized\n", CC_id);
      return(-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3455
    }
3456

Raymond Knopp's avatar
 
Raymond Knopp committed
3457 3458 3459 3460 3461 3462 3463 3464

#ifdef USRP
    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
3465
	N_TA_offset = 624/4;
Raymond Knopp's avatar
 
Raymond Knopp committed
3466 3467 3468 3469
    }
#endif
   
#ifndef USRP
3470 3471 3472 3473 3474
    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++) {
3475
      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);
3476 3477 3478 3479 3480 3481 3482 3483
      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];
3484 3485
	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];
3486 3487
	openair0_cfg[rf_map[CC_id].card].rx_num_channels++;
      }
3488

3489
      printf("rxdata[%d] @ %p\n",i,phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i]);
Raymond Knopp's avatar
 
Raymond Knopp committed
3490
    }
3491
    for (i=0;i<frame_parms->nb_antennas_tx;i++) {
3492
      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);
3493 3494 3495 3496 3497 3498 3499 3500
      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];
3501
	openair0_cfg[rf_map[CC_id].card].tx_gain[rf_map[CC_id].chain+i] = tx_gain[CC_id][i];
3502 3503
	openair0_cfg[rf_map[CC_id].card].tx_num_channels++;
      }
3504

3505
      printf("txdata[%d] @ %p\n",i,phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i]);
3506
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3507
  
Raymond Knopp's avatar
 
Raymond Knopp committed
3508
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523
    // replace RX signal buffers with mmaped HW versions
    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]);
      rxdata = (int32_t*)malloc16(samples_per_frame*sizeof(int32_t));
      phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i] = rxdata-N_TA_offset; // N_TA offset for TDD
    }
    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]);
      txdata = (int32_t*)malloc16(samples_per_frame*sizeof(int32_t));
      phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i] = txdata;
      memset(txdata, 0, samples_per_frame*sizeof(int32_t));
    }
    
Raymond Knopp's avatar
 
Raymond Knopp committed
3524
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3525 3526 3527 3528
    
  }
  return(0);

Raymond Knopp's avatar
 
Raymond Knopp committed
3529
}
3530

3531 3532 3533 3534 3535
/* 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]) {
3536

3537
  int i, CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
3538 3539
#ifdef USRP
  uint16_t N_TA_offset = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3540 3541
#else
  int j;
Raymond Knopp's avatar
 
Raymond Knopp committed
3542
#endif
3543
  LTE_DL_FRAME_PARMS *frame_parms;
3544

Raymond Knopp's avatar
 
Raymond Knopp committed
3545

3546 3547
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    if (phy_vars_eNB[CC_id]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3548 3549 3550
      frame_parms = &(phy_vars_eNB[CC_id]->lte_frame_parms);
      printf("setup_eNB_buffers: frame_parms = %p\n",frame_parms);
    } 
3551 3552 3553
    else {
      printf("phy_vars_eNB[%d] not initialized\n", CC_id);
      return(-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3554
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3555

Raymond Knopp's avatar
 
Raymond Knopp committed
3556
#ifdef USRP
3557 3558
    if (frame_parms->frame_type == TDD) {
      if (frame_parms->N_RB_DL == 100)
Raymond Knopp's avatar
 
Raymond Knopp committed
3559
	N_TA_offset = 624;
3560
      else if (frame_parms->N_RB_DL == 50)
Raymond Knopp's avatar
 
Raymond Knopp committed
3561
	N_TA_offset = 624/2;
3562
      else if (frame_parms->N_RB_DL == 25)
Raymond Knopp's avatar
 
Raymond Knopp committed
3563 3564
	N_TA_offset = 624/4;
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3565
#endif
3566 3567 3568 3569 3570
   

   

  
Raymond Knopp's avatar
 
Raymond Knopp committed
3571
    // replace RX signal buffers with mmaped HW versions
Raymond Knopp's avatar
 
Raymond Knopp committed
3572
#ifndef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
3573 3574 3575
    openair0_cfg[CC_id].tx_num_channels = 0;
    openair0_cfg[CC_id].rx_num_channels = 0;

3576 3577 3578 3579 3580 3581 3582 3583 3584 3585
    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];
3586
	openair0_cfg[rf_map[CC_id].card].rx_gain[rf_map[CC_id].chain+i] = rx_gain[CC_id][i];
3587 3588 3589
	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
3590
      for (j=0;j<16;j++) {
3591 3592
	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;
3593
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3594
    }
3595 3596 3597 3598 3599 3600 3601 3602 3603 3604
    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];
3605
	openair0_cfg[rf_map[CC_id].card].tx_gain[rf_map[CC_id].chain+i] = tx_gain[CC_id][i];
3606 3607 3608 3609
	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
3610
      for (j=0;j<16;j++) {
3611 3612
	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;
3613
      }
3614
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3615
#else // USRP
3616 3617 3618 3619 3620 3621
    for (i=0;i<frame_parms->nb_antennas_rx;i++) {
      free(phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i]);
      rxdata = (int32_t*)malloc16(samples_per_frame*sizeof(int32_t));
      phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i] = rxdata-N_TA_offset; // N_TA offset for TDD
      memset(rxdata, 0, samples_per_frame*sizeof(int32_t));
      printf("rxdata[%d] @ %p (%p)\n", i, phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i],rxdata);
Raymond Knopp's avatar
 
Raymond Knopp committed
3622
    }
3623 3624 3625 3626 3627 3628
    for (i=0;i<frame_parms->nb_antennas_tx;i++) {
      free(phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i]);
      txdata = (int32_t*)malloc16(samples_per_frame*sizeof(int32_t));
      phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i] = txdata;
      memset(txdata, 0, samples_per_frame*sizeof(int32_t));
      printf("txdata[%d] @ %p\n", i, phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i]);
3629

Raymond Knopp's avatar
 
Raymond Knopp committed
3630 3631
    }
#endif
3632
  }
3633
  return(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
3634
}
3635