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

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


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

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

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

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

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

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

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

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

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

#include "PHY/types.h"
69

70
#include "PHY/defs.h"
71
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
Raymond Knopp's avatar
 
Raymond Knopp committed
72
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
73

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

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

#include "PHY/vars.h"
#include "MAC_INTERFACE/vars.h"
84
//#include "SCHED/defs.h"
85 86 87 88 89 90 91 92 93 94
#include "SCHED/vars.h"
#include "LAYER2/MAC/vars.h"

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

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

#ifdef OPENAIR2
95
#include "otg_tx.h"
96 97
#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/vars.h"
98
#include "LAYER2/MAC/proto.h"
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
#ifndef CELLULAR
#include "RRC/LITE/vars.h"
#endif
#include "PHY_INTERFACE/vars.h"
#endif

#ifdef SMBV
#include "PHY/TOOLS/smbv.h"
unsigned short config_frames[4] = {2,9,11,13};
#endif
#include "UTIL/LOG/log_extern.h"
#include "UTIL/OTG/otg.h"
#include "UTIL/OTG/otg_vars.h"
#include "UTIL/MATH/oml.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
114
#include "enb_config.h"
115

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

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

#define FRAME_PERIOD    100000000ULL
#define DAQ_PERIOD      66667ULL

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

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

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

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

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

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

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

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

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

172 173
static long                      main_eNB_thread;
static long                      main_ue_thread;
Raymond Knopp's avatar
 
Raymond Knopp committed
174 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

184
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
185 186
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
#ifndef EXMIMO
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)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
398
  sleep(1); //allow lte-softmodem threads to exit first
399
  itti_terminate_tasks (TASK_UNKNOWN);
400
#endif
401 402 403 404 405 406

  //rt_sleep_ns(FRAME_PERIOD);

  //exit (-1);
}

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

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

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

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

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

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

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

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

  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);
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
 
  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);
    }
597 598
  else 
    printf("[EMOS] Opened GPS, gps_data=%p\n");
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 643
  
  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
644
	if (UE_flag==0)
645
	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
646
	else
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 707
	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

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

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

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

    openair0_reconfig(&openair0_cfg[0]);

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

  pthread_exit((void*) arg);

}
#endif


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

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
768

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

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
834

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

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

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

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

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

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

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

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

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
#endif

Florian Kaltenberger's avatar
Florian Kaltenberger committed
1039 1040
/*#if defined(ENABLE_ITTI)
  // Wait for eNB application initialization to be complete (eNB registration to MME) 
Raymond Knopp's avatar
 
Raymond Knopp committed
1041
  wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1042
#endif*/
Raymond Knopp's avatar
 
Raymond Knopp committed
1043 1044

#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;
1178
#ifdef EXMIMO
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
    }
  
  
1188
#ifdef EXMIMO
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
1260
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1261
  unsigned char slot=1;
1262 1263
#else
  unsigned char slot=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1264
#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;
1271
#ifdef EXMIMO
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
#ifdef EXMIMO
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  // EXMIMO
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);
1418

Raymond Knopp's avatar
 
Raymond Knopp committed
1419 1420 1421 1422
	rxs = openair0.trx_read_func(&openair0, 
				     &timestamp, 
				     &rxdata[rx_cnt*samples_per_packets], 
				     samples_per_packets);
1423

Raymond Knopp's avatar
 
Raymond Knopp committed
1424 1425 1426
	if (rxs != samples_per_packets)
	  oai_exit=1;

Raymond Knopp's avatar
 
Raymond Knopp committed
1427 1428
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,0);

Raymond Knopp's avatar
 
Raymond Knopp committed
1429
	// Transmit TX buffer based on timestamp from RX
Raymond Knopp's avatar
 
Raymond Knopp committed
1430
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1431 1432 1433 1434 1435
	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
1436
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1437
	/*
Raymond Knopp's avatar
 
Raymond Knopp committed
1438 1439 1440
	// 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
1441 1442 1443
	&timestamp, 
	&rxdata[(rx_cnt*samples_per_packets)+(samples_per_packets>>2)], 
	3*((samples_per_packets>>2)));
Raymond Knopp's avatar
 
Raymond Knopp committed
1444 1445
	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
1446
	oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1447
	*/
Raymond Knopp's avatar
 
Raymond Knopp committed
1448 1449 1450 1451 1452 1453 1454 1455 1456
#else
	rt_sleep_ns(1000000);
#endif
	if (rx_cnt == sf_bounds_tx[hw_subframe]) {
	  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
	    if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].mutex_tx) != 0) {
	      LOG_E(PHY,"[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n",hw_subframe,PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].instance_cnt_tx);   
	    }
	    else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1457
	      //	      LOG_I(PHY,"[eNB] Waking up eNB process %d (IC %d,rx_cnt %d)\n",hw_subframe,PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].instance_cnt_tx,rx_cnt); 
Raymond Knopp's avatar
 
Raymond Knopp committed
1458 1459 1460 1461 1462 1463 1464 1465
	      PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].instance_cnt_tx++;
	      pthread_mutex_unlock(&PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].mutex_tx);
	      if (PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].instance_cnt_tx == 0) {
		if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].cond_tx) != 0) {
		  LOG_E(PHY,"[eNB] ERROR pthread_cond_signal for eNB TX thread %d\n",hw_subframe);
		}
	      }
	      else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1466
		LOG_W(PHY,"[eNB] Frame %d, eNB TX thread %d busy!! (rx_cnt %d)\n",PHY_vars_eNB_g[0][CC_id]->proc[hw_subframe].frame_tx,hw_subframe,rx_cnt);
Raymond Knopp's avatar
 
Raymond Knopp committed
1467 1468 1469 1470 1471
		oai_exit=1;
	      }
	    }
	  }
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
1472 1473
	rx_cnt++;
	tx_cnt++;
Raymond Knopp's avatar
 
Raymond Knopp committed
1474 1475 1476

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1487

Raymond Knopp's avatar
 
Raymond Knopp committed
1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508
      
      timing_info.time_last = timing_info.time_now;
      timing_info.time_now = rt_get_time_ns();
      
      if (timing_info.n_samples>0) {
	time_diff = timing_info.time_now - timing_info.time_last;
	if (time_diff < timing_info.time_min)
	  timing_info.time_min = time_diff;
	if (time_diff > timing_info.time_max)
	  timing_info.time_max = time_diff;
	timing_info.time_avg += time_diff;
      }
      
      timing_info.n_samples++;
      /*
	if ((timing_info.n_samples%2000)==0) {
	LOG_D(HW,"frame %d (%d), slot %d, hw_slot %d: diff=%llu, min=%llu, max=%llu, avg=%llu (n_samples %d)\n",
	frame, PHY_vars_eNB_g[0]->frame, slot, hw_slot,time_diff,
	timing_info.time_min,timing_info.time_max,timing_info.time_avg/timing_info.n_samples,timing_info.n_samples);
	timing_info.n_samples = 0;
	timing_info.time_avg = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1509
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
1510 1511
      */
      //}
1512
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1513
      if ((slot&1) == 1) {
1514
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1515 1516 1517 1518 1519
	sf = ((slot>>1)+1)%10;
#else
	sf = hw_subframe;
#endif
	//		    LOG_I(PHY,"[eNB] Multithread slot %d (IC %d)\n",slot,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt);
Raymond Knopp's avatar
 
Raymond Knopp committed
1520
	
Raymond Knopp's avatar
 
Raymond Knopp committed
1521
	for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
1522
#ifdef EXMIMO 
Raymond Knopp's avatar
 
Raymond Knopp committed
1523 1524
	  if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_tx) != 0) {
	    LOG_E(PHY,"[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx);   
Raymond Knopp's avatar
 
Raymond Knopp committed
1525
	  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1526 1527 1528 1529 1530 1531 1532
	  else {
	    //		      LOG_I(PHY,"[eNB] Waking up eNB process %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt); 
	    PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx++;
	    pthread_mutex_unlock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_tx);
	    if (PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx == 0) {
	      if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[sf].cond_tx) != 0) {
		LOG_E(PHY,"[eNB] ERROR pthread_cond_signal for eNB TX thread %d\n",sf);
1533
	      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1534 1535 1536 1537 1538
	    }
	    else {
	      LOG_W(PHY,"[eNB] Frame %d, eNB TX thread %d busy!!\n",PHY_vars_eNB_g[0][CC_id]->proc[sf].frame_tx,sf);
	      oai_exit=1;
	    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1539
	  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550
#endif	    
	  if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_rx) != 0) {
	    LOG_E(PHY,"[eNB] ERROR pthread_mutex_lock for eNB RX thread %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx);   
	  }
	  else {
	    //		      LOG_I(PHY,"[eNB] Waking up eNB process %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt); 
	    PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx++;
	    pthread_mutex_unlock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_rx);
	    if (PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx == 0) {
	      if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[sf].cond_rx) != 0) {
		LOG_E(PHY,"[eNB] ERROR pthread_cond_signal for eNB RX thread %d\n",sf);
Raymond Knopp's avatar
 
Raymond Knopp committed
1551
	      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1552 1553 1554 1555
	    }
	    else {
	      LOG_W(PHY,"[eNB] Frame %d, eNB RX thread %d busy!!\n",PHY_vars_eNB_g[0][CC_id]->proc[sf].frame_rx,sf);
	      oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1556
	    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1557
	  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1558
	    
Raymond Knopp's avatar
 
Raymond Knopp committed
1559 1560
	}
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1561 1562
	  
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1563 1564 1565 1566 1567 1568 1569
#ifndef RTAI
      //pthread_mutex_lock(&tti_mutex);
#endif




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


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

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

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

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

static void *UE_thread_synch(void *arg) {

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

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

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

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

	//	    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
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 1800 1801
    
  }  // 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
1802
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1803
  PHY_VARS_UE *UE = (PHY_VARS_UE*)arg;
Raymond Knopp's avatar
 
Raymond Knopp committed
1804 1805
  int i;
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1806
  UE->instance_cnt_rx=-1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1807
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1808
  mlockall(MCL_CURRENT | MCL_FUTURE);
Raymond Knopp's avatar
 
Raymond Knopp committed
1809
  
1810
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821
  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
1822

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1879 1880 1881



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

Raymond Knopp's avatar
 
Raymond Knopp committed
1889 1890 1891
  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
1892
  // unsigned int aa;
Raymond Knopp's avatar
 
Raymond Knopp committed
1893 1894 1895 1896 1897 1898 1899 1900 1901
  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
1902

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

  printf("starting UE thread\n");

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1921

Raymond Knopp's avatar
 
Raymond Knopp committed
1922
    while (rx_cnt < sf_bounds[hw_subframe]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1923
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1924
      vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1925 1926 1927 1928 1929 1930 1931
  
#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
1932
	oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1933 1934

      rx_off_diff = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1935 1936 1937
      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
1938
      if (tx_enabled) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1939
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1940 1941 1942 1943
	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
1944 1945 1946
				1);
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,0);
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1947 1948 1949
#else
      rt_sleep_ns(10000000);
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1950 1951 1952 1953 1954 1955 1956 1957
      rx_cnt++;
      tx_cnt++;
      
      if(tx_cnt == max_cnt)
	tx_cnt = 0;
    }
    
    if(rx_cnt == max_cnt)
Raymond Knopp's avatar
 
Raymond Knopp committed
1958 1959 1960
      rx_cnt = 0;


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

Raymond Knopp's avatar
 
Raymond Knopp committed
2090 2091


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

2113

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

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

#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
2125
  rt_make_hard_real_time();
2126 2127
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2128
  mlockall(MCL_CURRENT | MCL_FUTURE);
2129

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

Raymond Knopp's avatar
 
Raymond Knopp committed
2143
    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
2144 2145

     
Raymond Knopp's avatar
 
Raymond Knopp committed
2146
    if (is_synchronized) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2147 2148


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

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

#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
2320
  rt_make_soft_real_time();
2321 2322
#endif

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

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

2333
#endif
2334

2335

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

2366
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377
  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
2378
}
Raymond Knopp's avatar
 
Raymond Knopp committed
2379 2380


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

Raymond Knopp's avatar
 
Raymond Knopp committed
2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414
  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}};
  
2415
  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
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 2446 2447
    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
2448
      multi_thread=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2449 2450
      break;
    case 'C':
2451
      for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
2452 2453 2454 2455 2456
	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]);
2457
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2458 2459 2460 2461 2462
      break;
      
    case 'd':
#ifdef XFORMS
      do_forms=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
2463
      printf("Running with XFORMS!\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481
#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;
2482 2483 2484 2485 2486 2487 2488
    
    case 'm':
      target_dl_mcs = atoi (optarg);
      break;
    case 't':
      target_ul_mcs = atoi (optarg);
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
2489 2490 2491 2492
      
    case 'V':
      ouput_vcd = 1;
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
2493
    case  'q':
Raymond Knopp's avatar
 
Raymond Knopp committed
2494 2495 2496 2497 2498 2499
      opp_enabled = 1;
      break;
    case  'R' :
      online_log_messages =1;
      break;
    case 'r':
Raymond Knopp's avatar
 
Raymond Knopp committed
2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521
      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
2522
      }
2523
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
2524 2525
    case 's':
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
2526 2527 2528

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

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

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

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

#ifdef ENABLE_TCXO
Raymond Knopp's avatar
 
Raymond Knopp committed
2633
  unsigned int tcxo = 114;
2634 2635
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2636
  //  int amp;
Raymond Knopp's avatar
 
Raymond Knopp committed
2637 2638
  // uint8_t prach_fmt;
  // int N_ZC;
2639

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
2651
  set_latency_target();
2652

Raymond Knopp's avatar
 
Raymond Knopp committed
2653
  mode = normal_txrx;
2654

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
2671 2672
  //randominit (0);
  set_taus_seed (0);
winckel's avatar
winckel committed
2673

Raymond Knopp's avatar
 
Raymond Knopp committed
2674 2675 2676
  // initialize the log (see log.h for details)
  logInit();

2677
  set_glog(glog_level, glog_verbosity);
Raymond Knopp's avatar
 
Raymond Knopp committed
2678 2679 2680
  if (UE_flag==1)
    {
      printf("configuring for UE\n");
2681

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
2734 2735 2736 2737 2738 2739 2740
  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");
  }

2741
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
2742 2743 2744 2745 2746 2747
  if (UE_flag == 1) {
    log_set_instance_type (LOG_INSTANCE_UE);
  }
  else {
    log_set_instance_type (LOG_INSTANCE_ENB);
  }
2748

Raymond Knopp's avatar
 
Raymond Knopp committed
2749
  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
2750 2751
#endif

2752
#ifdef NAS_NETLINK
Raymond Knopp's avatar
 
Raymond Knopp committed
2753
  netlink_init();
2754 2755
#endif

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

#ifndef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2763 2764 2765 2766
  check_clock();
#endif

  // init the parameters
Raymond Knopp's avatar
 
Raymond Knopp committed
2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785
  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
2786
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800
    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;
2801 2802
    init_ul_hopping(frame_parms[CC_id]);
    init_frame_parms(frame_parms[CC_id],1);
2803
    phy_init_top(frame_parms[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815
  }

  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
2816
    // N_ZC = (prach_fmt <4)?839:139;
Raymond Knopp's avatar
 
Raymond Knopp committed
2817
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
2818 2819

  if (UE_flag==1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2820 2821 2822
    NB_UE_INST=1;
    NB_INST=1;

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

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

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

2930
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
2931

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

2934
#else
2935
	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
2936 2937 2938

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

2939 2940
	// set eNB to max gain
	for (i=0;i<4;i++)
2941 2942
	  rx_gain_mode[CC_id][i] = max_gain;
#endif
2943

2944
#ifdef EXMIMO
2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961
	//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
2962
      }
2963 2964


Raymond Knopp's avatar
 
Raymond Knopp committed
2965 2966
      NB_eNB_INST=1;
      NB_INST=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
2967

Raymond Knopp's avatar
 
Raymond Knopp committed
2968
      openair_daq_vars.ue_dl_rb_alloc=0x1fff;
2969
      openair_daq_vars.target_ue_dl_mcs=target_dl_mcs;
Raymond Knopp's avatar
 
Raymond Knopp committed
2970
      openair_daq_vars.ue_ul_nb_rb=6;
2971
      openair_daq_vars.target_ue_ul_mcs=target_ul_mcs;
Raymond Knopp's avatar
 
Raymond Knopp committed
2972 2973

    }
2974

2975

2976

Raymond Knopp's avatar
 
Raymond Knopp committed
2977
  dump_frame_parms(frame_parms[0]);
2978

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

3018 3019 3020 3021
  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;
3022 3023 3024
    // 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
3025
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3026 3027
    openair0_cfg[card].tx_num_channels=1;
    openair0_cfg[card].rx_num_channels=1;
3028 3029
    for (i=0;i<4;i++) {
      openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
Raymond Knopp's avatar
 
Raymond Knopp committed
3030 3031
      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
3032 3033
      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
3034
    }
3035
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3036
  }
3037 3038

  if (openair0_device_init(&openair0, &openair0_cfg[0]) <0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3039 3040 3041
    printf("Exiting, cannot initialize device\n");
    exit(-1);
  }
3042 3043 3044

  mac_xface = malloc(sizeof(MAC_xface));

3045
#ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3046
  int eMBMS_active=0;
3047

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

Raymond Knopp's avatar
 
Raymond Knopp committed
3057
  mac_xface->macphy_exit = &exit_fun;
3058

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
3085
  //  number_of_cards = openair0_num_detected_cards;
3086

Raymond Knopp's avatar
 
Raymond Knopp committed
3087
  openair_daq_vars.timing_advance = 0;
3088

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

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
3143
  mlockall(MCL_CURRENT | MCL_FUTURE);
3144 3145

#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166
  // 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);
3167
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3168 3169 3170 3171 3172
  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
3173
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3174 3175 3176
  pthread_cond_init(&sync_cond,NULL);
  pthread_mutex_init(&sync_mutex, NULL);
#endif
3177 3178
#endif

Florian Kaltenberger's avatar
Florian Kaltenberger committed
3179 3180 3181 3182 3183 3184 3185
  /*#if defined(ENABLE_ITTI)
  // Wait for eNB application initialization to be complete (eNB registration to MME)
  if (UE_flag==0) {
    printf("Waiting for eNB application to be ready\n");
    wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
  }
  #endif*/
3186

Raymond Knopp's avatar
 
Raymond Knopp committed
3187 3188

  // this starts the DMA transfers
3189
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3190
  if (UE_flag!=1)
3191 3192
    for (card=0;card<openair0_num_detected_cards;card++)
      openair0_start_rt_acquisition(card);
Raymond Knopp's avatar
 
Raymond Knopp committed
3193
#endif
3194 3195

#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
3196 3197 3198 3199 3200 3201 3202 3203
  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 {
3204
      form_stats_l2 = create_form_stats_form();
Raymond Knopp's avatar
 
Raymond Knopp committed
3205 3206 3207 3208
      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);
3209
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3210 3211 3212
    }
    fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
    if (UE_flag==0) {
3213 3214
      fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats");

Raymond Knopp's avatar
 
Raymond Knopp committed
3215 3216 3217 3218
      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
3219 3220
	}
	else {
Raymond Knopp's avatar
 
Raymond Knopp committed
3221 3222
	  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
3223
	}
3224 3225
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236
    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
3237
    ret = pthread_create(&forms_thread, NULL, scope_thread, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
3238 3239
    printf("Scope thread created, ret=%d\n",ret);
  }
3240 3241 3242
#endif

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3243 3244
  ret = pthread_create(&thread3, NULL, emos_thread, NULL);
  printf("EMOS thread created, ret=%d\n",ret);
3245 3246
#endif

3247 3248 3249 3250 3251
#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
3252
  rt_sleep_ns(10*FRAME_PERIOD);
3253 3254

#ifndef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3255 3256 3257 3258 3259
  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
3260 3261 3262 3263 3264 3265 3266

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

3267 3268
#endif

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

Raymond Knopp's avatar
 
Raymond Knopp committed
3294 3295
    if (multi_thread>0) {
      init_eNB_proc();
3296
      sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3297 3298
      LOG_D(HW,"[lte-softmodem.c] eNB threads created\n");
    }
3299
    printf("Creating main eNB_thread \n");
Raymond Knopp's avatar
 
Raymond Knopp committed
3300
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3301
    main_eNB_thread = rt_thread_create(eNB_thread, NULL, OPENAIR_THREAD_STACK_SIZE);
Raymond Knopp's avatar
 
Raymond Knopp committed
3302
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3303
    error_code = pthread_create(&main_eNB_thread, &attr_dlsch_threads, eNB_thread, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
3304 3305 3306 3307 3308 3309
    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
3310
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3311 3312
#endif
  }
3313

Raymond Knopp's avatar
 
Raymond Knopp committed
3314
  // Sleep to allow all threads to setup
Florian Kaltenberger's avatar
Florian Kaltenberger committed
3315
  //sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3316

Raymond Knopp's avatar
 
Raymond Knopp committed
3317

3318
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3319
#ifndef USRP_DEBUG
Raymond Knopp's avatar
 
Raymond Knopp committed
3320
  openair0.trx_start_func(&openair0);
Raymond Knopp's avatar
 
Raymond Knopp committed
3321
  //  printf("returning from usrp start streaming: %llu\n",get_usrp_time(&openair0));
Raymond Knopp's avatar
 
Raymond Knopp committed
3322
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3323 3324 3325
#ifdef RTAI
  rt_sem_signal(sync_sem);
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3326 3327 3328 3329
  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
3330 3331
#endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3332 3333 3334
  // wait for end of program
  printf("TYPE <CTRL-C> TO TERMINATE\n");
  //getchar();
3335 3336

#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
3337 3338
  printf("Entering ITTI signals handler\n");
  itti_wait_tasks_end();
3339
  oai_exit=1;
3340
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3341 3342
  while (oai_exit==0)
    rt_sleep_ns(FRAME_PERIOD);
3343
#endif
3344

Raymond Knopp's avatar
 
Raymond Knopp committed
3345
  // stop threads
3346
#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
3347 3348 3349
  printf("waiting for XFORMS thread\n");
  if (do_forms==1)
    {
Raymond Knopp's avatar
 
Raymond Knopp committed
3350
      pthread_join(forms_thread,&status);
Raymond Knopp's avatar
 
Raymond Knopp committed
3351 3352 3353 3354 3355 3356
      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 {
3357 3358
	fl_hide_form(form_stats_l2->stats_form);
	fl_free_form(form_stats_l2->stats_form);
Raymond Knopp's avatar
 
Raymond Knopp committed
3359 3360 3361 3362
	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
3363
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3364
    }
3365 3366
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3367 3368 3369
  printf("stopping MODEM threads\n");
  // cleanup
  if (UE_flag == 1) {
3370
#ifdef EXMIMO
3371
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3372
    rt_thread_join(main_ue_thread); 
3373
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3374
    pthread_join(main_ue_thread,&status); 
3375 3376
#endif
#ifdef DLSCH_THREAD
Raymond Knopp's avatar
 
Raymond Knopp committed
3377 3378
    cleanup_dlsch_threads();
    cleanup_rx_pdsch_thread();
3379
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3380 3381 3382
#endif
  }
  else {
Raymond Knopp's avatar
 
Raymond Knopp committed
3383
#ifdef DEBUG_THREADS
Raymond Knopp's avatar
 
Raymond Knopp committed
3384
    printf("Joining eNB_thread ...");
Raymond Knopp's avatar
 
Raymond Knopp committed
3385
#endif
3386 3387 3388
#ifdef RTAI
    rt_thread_join(main_eNB_thread); 
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3389
    pthread_join(main_eNB_thread,(void**)&eNB_thread_status_p); 
Raymond Knopp's avatar
 
Raymond Knopp committed
3390
#ifdef DEBUG_THREADS
Raymond Knopp's avatar
 
Raymond Knopp committed
3391
    printf("status %d\n",*eNB_thread_status_p);
Raymond Knopp's avatar
 
Raymond Knopp committed
3392
#endif
3393
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3394

Raymond Knopp's avatar
 
Raymond Knopp committed
3395 3396 3397
    if (multi_thread>0) {
      printf("Killing eNB processing threads\n");
      kill_eNB_proc();
Raymond Knopp's avatar
 
Raymond Knopp committed
3398

Raymond Knopp's avatar
 
Raymond Knopp committed
3399
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3400
  }
3401

3402
#ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3403
  //cleanup_pdcp_thread();
3404 3405
#endif

3406
#ifndef EXMIMO
3407
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3408
  rt_sem_delete(sync_sem);
Raymond Knopp's avatar
 
Raymond Knopp committed
3409
  stop_rt_timer();
Raymond Knopp's avatar
 
Raymond Knopp committed
3410 3411 3412
#else
  pthread_cond_destroy(&sync_cond);
  pthread_mutex_destroy(&sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
3413
#endif
3414 3415
#endif

3416
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3417
  printf("stopping card\n");
3418
  openair0_stop(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
3419 3420
  printf("closing openair0_lib\n");
  openair0_close();
Raymond Knopp's avatar
 
Raymond Knopp committed
3421
#endif
3422 3423

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3424 3425 3426
  printf("waiting for EMOS thread\n");
  pthread_cancel(thread3);
  pthread_join(thread3,&status);
3427 3428 3429
#endif

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3430 3431
  error_code = rtf_destroy(CHANSOUNDER_FIFO_MINOR);
  printf("[OPENAIR][SCHED][CLEANUP] EMOS FIFO closed, error_code %d\n", error_code);
3432 3433
#endif

3434 3435 3436 3437 3438 3439
#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
3440 3441
  if (ouput_vcd)
    vcd_signal_dumper_close();
3442

Raymond Knopp's avatar
 
Raymond Knopp committed
3443
  logClean();
3444

Raymond Knopp's avatar
 
Raymond Knopp committed
3445 3446
  return 0;
}
3447

3448 3449
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
3450

3451
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3452 3453 3454
  uint16_t N_TA_offset = 0;
#endif

3455 3456 3457 3458 3459
  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
3460
    }
3461 3462 3463
    else {
      printf("phy_vars_eNB[%d] not initialized\n", CC_id);
      return(-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3464
    }
3465

Raymond Knopp's avatar
 
Raymond Knopp committed
3466

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

3498
      printf("rxdata[%d] @ %p\n",i,phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i]);
Raymond Knopp's avatar
 
Raymond Knopp committed
3499
    }
3500
    for (i=0;i<frame_parms->nb_antennas_tx;i++) {
3501
      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);
3502 3503 3504 3505 3506 3507 3508 3509
      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];
3510
	openair0_cfg[rf_map[CC_id].card].tx_gain[rf_map[CC_id].chain+i] = tx_gain[CC_id][i];
3511 3512
	openair0_cfg[rf_map[CC_id].card].tx_num_channels++;
      }
3513

3514
      printf("txdata[%d] @ %p\n",i,phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i]);
3515
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3516
  
Raymond Knopp's avatar
 
Raymond Knopp committed
3517
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532
    // 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
3533
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3534 3535 3536 3537
    
  }
  return(0);

Raymond Knopp's avatar
 
Raymond Knopp committed
3538
}
3539

3540 3541 3542 3543 3544
/* 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]) {
3545

3546
  int i, CC_id;
3547
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3548
  uint16_t N_TA_offset = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3549 3550
#else
  int j;
Raymond Knopp's avatar
 
Raymond Knopp committed
3551
#endif
3552
  LTE_DL_FRAME_PARMS *frame_parms;
3553

Raymond Knopp's avatar
 
Raymond Knopp committed
3554

3555 3556
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    if (phy_vars_eNB[CC_id]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3557 3558 3559
      frame_parms = &(phy_vars_eNB[CC_id]->lte_frame_parms);
      printf("setup_eNB_buffers: frame_parms = %p\n",frame_parms);
    } 
3560 3561 3562
    else {
      printf("phy_vars_eNB[%d] not initialized\n", CC_id);
      return(-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3563
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3564

3565
#ifndef EXMIMO
3566 3567
    if (frame_parms->frame_type == TDD) {
      if (frame_parms->N_RB_DL == 100)
Raymond Knopp's avatar
 
Raymond Knopp committed
3568
	N_TA_offset = 624;
3569
      else if (frame_parms->N_RB_DL == 50)
Raymond Knopp's avatar
 
Raymond Knopp committed
3570
	N_TA_offset = 624/2;
3571
      else if (frame_parms->N_RB_DL == 25)
Raymond Knopp's avatar
 
Raymond Knopp committed
3572 3573
	N_TA_offset = 624/4;
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3574
#endif
3575 3576 3577 3578 3579
   

   

  
Raymond Knopp's avatar
 
Raymond Knopp committed
3580
    // replace RX signal buffers with mmaped HW versions
3581
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3582 3583 3584
    openair0_cfg[CC_id].tx_num_channels = 0;
    openair0_cfg[CC_id].rx_num_channels = 0;

3585 3586 3587 3588 3589 3590 3591 3592 3593 3594
    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];
3595
	openair0_cfg[rf_map[CC_id].card].rx_gain[rf_map[CC_id].chain+i] = rx_gain[CC_id][i];
3596 3597 3598
	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
3599
      for (j=0;j<16;j++) {
3600 3601
	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;
3602
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3603
    }
3604 3605 3606 3607 3608 3609 3610 3611 3612 3613
    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];
3614
	openair0_cfg[rf_map[CC_id].card].tx_gain[rf_map[CC_id].chain+i] = tx_gain[CC_id][i];
3615 3616 3617 3618
	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
3619
      for (j=0;j<16;j++) {
3620 3621
	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;
3622
      }
3623
    }
3624
#else // not EXMIMO
3625 3626 3627 3628 3629 3630
    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
3631
    }
3632 3633 3634 3635 3636 3637
    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]);
3638

Raymond Knopp's avatar
 
Raymond Knopp committed
3639 3640
    }
#endif
3641
  }
3642
  return(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
3643
}
3644