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

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


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

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

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

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

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

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

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

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

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

#include "PHY/types.h"
71

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

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

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

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

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

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

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

#ifdef SMBV
#include "PHY/TOOLS/smbv.h"
unsigned short config_frames[4] = {2,9,11,13};
#endif
#include "UTIL/LOG/log_extern.h"
Navid Nikaein's avatar
Navid Nikaein committed
111
#include "UTIL/OTG/otg_tx.h"
112
#include "UTIL/OTG/otg_externs.h"
113 114
#include "UTIL/MATH/oml.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
115
#include "UTIL/OPT/opt.h"
116
#include "enb_config.h"
Navid Nikaein's avatar
Navid Nikaein committed
117
//#include "PHY/TOOLS/time_meas.h"
118

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

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

#define FRAME_PERIOD    100000000ULL
#define DAQ_PERIOD      66667ULL

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

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

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

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

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

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

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

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

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

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

179 180
//static int sync_thread;
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
181 182
pthread_t                       main_eNB_thread;
pthread_t                       main_ue_thread;
183
pthread_attr_t                  attr_dlsch_threads;
184 185
pthread_attr_t                  attr_UE_thread;

186
#ifndef LOWLATENCY
187
struct sched_param              sched_param_dlsch;
188
#endif 
Raymond Knopp's avatar
 
Raymond Knopp committed
189

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

Raymond Knopp's avatar
 
Raymond Knopp committed
195
RTIME T0;
196

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
217 218 219
openair0_device openair0;
openair0_timestamp timestamp;

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

228
int                             card = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
229

230

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

242
static char                     UE_flag=0;
243
static uint8_t                  eNB_id=0,UE_id=0;
244

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

openair0_rf_map rf_map[MAX_NUM_CCs];
251

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
279 280
double sample_rate=30.72e6;
double bw = 14e6;
281

282
static int                      tx_max_power[MAX_NUM_CCs] =  {0,0};
283

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

Raymond Knopp's avatar
 
Raymond Knopp committed
288 289 290
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
291

Raymond Knopp's avatar
 
Raymond Knopp committed
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
#ifndef USRP
//256 sample blocks
int sf_bounds_1_5[10]    = {8, 15, 23, 30, 38, 45, 53, 60, 68, 75};
int sf_bounds_1_5_tx[10] = {4, 11, 19, 26, 34, 41, 49, 56, 64, 71};

int sf_bounds_5[10] = {5,10,15,20,25,30,35,40,45,50};
int sf_bounds_5_tx[10] = {3,8,13,18,23,28,33,38,43,48};

int sf_bounds_10[10]    = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int sf_bounds_10_tx[10] = {5, 15, 25, 35, 45, 55, 65, 75, 85,95};

int sf_bounds_20[10] = {20, 40, 60, 80, 100, 120, 140, 160, 180, 200};
int sf_bounds_20_tx[10] = {10, 30, 50, 70, 90, 110, 130, 150, 170, 190};

#else

Raymond Knopp's avatar
 
Raymond Knopp committed
308 309 310
int sf_bounds_1_5[10]    = {8, 15, 23, 30, 38, 45, 53, 60, 68, 75};
int sf_bounds_1_5_tx[10] = {4, 11, 19, 26, 34, 41, 49, 56, 64, 71};

Raymond Knopp's avatar
 
Raymond Knopp committed
311 312 313
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
314
int sf_bounds_10[10] = {8, 15, 23, 30, 38, 45, 53, 60, 68, 75};
Raymond Knopp's avatar
 
Raymond Knopp committed
315 316
int sf_bounds_10_tx[10] = {4, 11, 19, 26, 34, 41, 49, 56, 64, 71};

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

Raymond Knopp's avatar
 
Raymond Knopp committed
321
int *sf_bounds;
Raymond Knopp's avatar
 
Raymond Knopp committed
322 323
int *sf_bounds_tx;

Raymond Knopp's avatar
 
Raymond Knopp committed
324 325 326 327
int max_cnt;
int tx_delay;

#endif
328
/*
Raymond Knopp's avatar
 
Raymond Knopp committed
329 330 331
  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};
332
*/
Raymond Knopp's avatar
 
Raymond Knopp committed
333 334
//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
335 336
//{8254617, 8254617, 8254617, 8254617}; //eNB khalifa
//{8255067,8254810,8257340,8257340}; // eNB PETRONAS
337

Raymond Knopp's avatar
 
Raymond Knopp committed
338 339 340 341 342
//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};
343 344 345

static runmode_t                mode;
static int                      rx_input_level_dBm;
346
static int                      UE_scan=1;
347
static int                      online_log_messages=0;
348
#ifdef XFORMS
349
extern int                      otg_enabled;
350
static char                     do_forms=0;
351
#else
352
int                             otg_enabled;
353
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
354
//int                             number_of_cards =   1;
Raymond Knopp's avatar
 
Raymond Knopp committed
355
#ifdef EXMIMO
356 357
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
358
#endif
359

Raymond Knopp's avatar
 
Raymond Knopp committed
360
static LTE_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
361

Raymond Knopp's avatar
 
Raymond Knopp committed
362
int multi_thread=1;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
363
uint32_t target_dl_mcs = 28; //maximum allowed mcs
364
uint32_t target_ul_mcs = 10;
365 366
uint8_t exit_missed_slots=1;
uint64_t num_missed_slots=0; // counter for the number of missed slots
367

Raymond Knopp's avatar
 
Raymond Knopp committed
368

369
time_stats_t softmodem_stats_mt; // main thread
Raymond Knopp's avatar
 
Raymond Knopp committed
370
time_stats_t softmodem_stats_hw; //  hw acquisition
371 372
time_stats_t softmodem_stats_tx_sf[10]; // total tx time 
time_stats_t softmodem_stats_rx_sf[10]; // total rx time 
Navid Nikaein's avatar
Navid Nikaein committed
373 374
void reset_opp_meas(void);
void print_opp_meas(void);
375
int transmission_mode=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
376

Raymond Knopp's avatar
 
Raymond Knopp committed
377

Lionel Gauthier's avatar
 
Lionel Gauthier committed
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
int16_t           glog_level         = LOG_DEBUG;
int16_t           glog_verbosity     = LOG_MED;
int16_t           hw_log_level       = LOG_DEBUG;
int16_t           hw_log_verbosity   = LOG_MED;
int16_t           phy_log_level      = LOG_DEBUG;
int16_t           phy_log_verbosity  = LOG_MED;
int16_t           mac_log_level      = LOG_DEBUG;
int16_t           mac_log_verbosity  = LOG_MED;
int16_t           rlc_log_level      = LOG_DEBUG;
int16_t           rlc_log_verbosity  = LOG_MED;
int16_t           pdcp_log_level     = LOG_DEBUG;
int16_t           pdcp_log_verbosity = LOG_MED;
int16_t           rrc_log_level      = LOG_DEBUG;
int16_t           rrc_log_verbosity  = LOG_MED;
# if defined(ENABLE_USE_MME)
int16_t           gtpu_log_level     = LOG_DEBUG;
int16_t           gtpu_log_verbosity = LOG_MED;
int16_t           udp_log_level      = LOG_DEBUG;
int16_t           udp_log_verbosity  = LOG_MED;
#endif
398 399 400 401
#if defined (ENABLE_SECURITY)
int16_t           osa_log_level      = LOG_INFO;
int16_t           osa_log_verbosity  = LOG_MED;
#endif 
402

Raymond Knopp's avatar
 
Raymond Knopp committed
403 404 405 406 407 408 409 410 411 412

#ifdef ETHERNET
char rrh_eNB_ip[20] = "127.0.0.1";
int rrh_eNB_port = 1500;
char *rrh_UE_ip = "127.0.0.1";
int rrh_UE_port = 1600;
#endif

char uecap_xer[1024],uecap_xer_in=0;

413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
#define KHz (1000UL)
#define MHz (1000 * KHz)

typedef struct eutra_band_s {
  int16_t band;
  uint32_t ul_min;
  uint32_t ul_max;
  uint32_t dl_min;
  uint32_t dl_max;
  lte_frame_type_t frame_type;
} eutra_band_t;

typedef struct band_info_s {
  int nbands;
  eutra_band_t band_info[100];
} band_info_t;

band_info_t bands_to_scan;

static const eutra_band_t eutra_bands[] =
  {
    { 1, 1920    * MHz, 1980    * MHz, 2110    * MHz, 2170    * MHz, FDD},
    { 2, 1850    * MHz, 1910    * MHz, 1930    * MHz, 1990    * MHz, FDD},
    { 3, 1710    * MHz, 1785    * MHz, 1805    * MHz, 1880    * MHz, FDD},
    { 4, 1710    * MHz, 1755    * MHz, 2110    * MHz, 2155    * MHz, FDD},
    { 5,  824    * MHz,  849    * MHz,  869    * MHz,  894    * MHz, FDD},
    { 6,  830    * MHz,  840    * MHz,  875    * MHz,  885    * MHz, FDD},
    { 7, 2500    * MHz, 2570    * MHz, 2620    * MHz, 2690    * MHz, FDD},
    { 8,  880    * MHz,  915    * MHz,  925    * MHz,  960    * MHz, FDD},
    { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD},
    {10, 1710    * MHz, 1770    * MHz, 2110    * MHz, 2170    * MHz, FDD},
    {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD},
    {12,  698    * MHz,  716    * MHz,  728    * MHz,  746    * MHz, FDD},
    {13,  777    * MHz,  787    * MHz,  746    * MHz,  756    * MHz, FDD},
    {14,  788    * MHz,  798    * MHz,  758    * MHz,  768    * MHz, FDD},

    {17,  704    * MHz,  716    * MHz,  734    * MHz,  746    * MHz, FDD},

    {33, 1900    * MHz, 1920    * MHz, 1900    * MHz, 1920    * MHz, TDD},
    {34, 2010    * MHz, 2025    * MHz, 2010    * MHz, 2025    * MHz, TDD},
    {35, 1850    * MHz, 1910    * MHz, 1850    * MHz, 1910    * MHz, TDD},
    {36, 1930    * MHz, 1990    * MHz, 1930    * MHz, 1990    * MHz, TDD},
    {37, 1910    * MHz, 1930    * MHz, 1910    * MHz, 1930    * MHz, TDD},
    {38, 2570    * MHz, 2620    * MHz, 2570    * MHz, 2630    * MHz, TDD},
    {39, 1880    * MHz, 1920    * MHz, 1880    * MHz, 1920    * MHz, TDD},
    {40, 2300    * MHz, 2400    * MHz, 2300    * MHz, 2400    * MHz, TDD},
    {41, 2496    * MHz, 2690    * MHz, 2496    * MHz, 2690    * MHz, TDD},
    {42, 3400    * MHz, 3600    * MHz, 3400    * MHz, 3600    * MHz, TDD},
    {43, 3600    * MHz, 3800    * MHz, 3600    * MHz, 3800    * MHz, TDD},
    {44, 703    * MHz, 803    * MHz, 703    * MHz, 803    * MHz, TDD},
  };

465
unsigned int build_rflocal(int txi, int txq, int rxi, int rxq)
466
{
Raymond Knopp's avatar
 
Raymond Knopp committed
467
  return (txi + (txq<<6) + (rxi<<12) + (rxq<<18));
468 469 470
}
unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
471
  return (dcoff_i_rxfe + (dcoff_q_rxfe<<8));
472 473
}

474 475 476 477 478 479 480 481 482 483 484 485
#ifdef LOWLATENCY
int sched_setattr(pid_t pid, const struct sched_attr *attr, unsigned int flags) {

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


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

  return syscall(__NR_sched_getattr, pid, attr, size, flags);
}
#endif 
486
#if !defined(ENABLE_ITTI)
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501
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 {
502
    printf("trying to exit gracefully...\n"); 
503
    oai_exit = 1;
504 505
  }
}
506
#endif
507 508 509

void exit_fun(const char* s)
{
510
  if (s != NULL) {
511
    printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s);
512 513 514 515 516
  }

  oai_exit = 1;

#if defined(ENABLE_ITTI)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
517
  sleep(1); //allow lte-softmodem threads to exit first
518
  itti_terminate_tasks (TASK_UNKNOWN);
519
#endif
520 521 522 523 524 525

  //rt_sleep_ns(FRAME_PERIOD);

  //exit (-1);
}

Raymond Knopp's avatar
 
Raymond Knopp committed
526 527 528
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
529 530 531 532 533 534 535 536 537
 * 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
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554
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
555
 
556
#ifdef XFORMS
557 558 559 560

void reset_stats(FL_OBJECT *button, long arg) {
  int i,j,k;
  PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[0][0];
561 562 563 564 565 566 567 568 569 570 571 572
  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;
Raymond Knopp's avatar
 
Raymond Knopp committed
573 574 575
	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;
576
      }
577
    }
578 579 580
    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;
581 582 583
  }
}

584
static void *scope_thread(void *arg) {
Raymond Knopp's avatar
 
Raymond Knopp committed
585
  char stats_buffer[16384];
586
# ifdef ENABLE_XFORMS_WRITE_STATS
Raymond Knopp's avatar
 
Raymond Knopp committed
587 588
  FILE *UE_stats, *eNB_stats;
  int len = 0;
589
# endif
Raymond Knopp's avatar
 
Raymond Knopp committed
590
  struct sched_param sched_param;
591

Raymond Knopp's avatar
 
Raymond Knopp committed
592 593
  sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1; 
  sched_setscheduler(0, SCHED_FIFO,&sched_param);
594

Raymond Knopp's avatar
 
Raymond Knopp committed
595
  printf("Scope thread has priority %d\n",sched_param.sched_priority);
596
    
597 598
# ifdef ENABLE_XFORMS_WRITE_STATS
  if (UE_flag==1) 
Raymond Knopp's avatar
 
Raymond Knopp committed
599
    UE_stats  = fopen("UE_stats.txt", "w");
600
  else 
Raymond Knopp's avatar
 
Raymond Knopp committed
601
    eNB_stats = fopen("eNB_stats.txt", "w");
602
#endif
603
    
Raymond Knopp's avatar
 
Raymond Knopp committed
604 605
  while (!oai_exit) {
    if (UE_flag==1) {
606
# ifdef ENABLE_XFORMS_WRITE_STATS
Raymond Knopp's avatar
 
Raymond Knopp committed
607
      len =
608
# endif
609
	dump_ue_stats (PHY_vars_UE_g[0][0], stats_buffer, 0, mode,rx_input_level_dBm);
Raymond Knopp's avatar
 
Raymond Knopp committed
610
      fl_set_object_label(form_stats->stats_text, stats_buffer);
611

Raymond Knopp's avatar
 
Raymond Knopp committed
612
      phy_scope_UE(form_ue[UE_id], 
613
		   PHY_vars_UE_g[UE_id][0],
Raymond Knopp's avatar
 
Raymond Knopp committed
614 615
		   eNB_id,
		   UE_id,7);
616
            
Raymond Knopp's avatar
 
Raymond Knopp committed
617
    } else {
618
# ifdef ENABLE_XFORMS_WRITE_STATS
Raymond Knopp's avatar
 
Raymond Knopp committed
619
      len =
620
# endif
Raymond Knopp's avatar
 
Raymond Knopp committed
621
	dump_eNB_l2_stats (stats_buffer, 0);
622
      fl_set_object_label(form_stats_l2->stats_text, stats_buffer);
623 624 625 626 627 628 629

# 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
630 631
      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
632
		      PHY_vars_eNB_g[eNB_id][0],
Raymond Knopp's avatar
 
Raymond Knopp committed
633 634
		      UE_id);
      }
635 636
              
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
637
    //printf("doing forms\n");
Florian Kaltenberger's avatar
Florian Kaltenberger committed
638 639
    //usleep(100000); // 100 ms
    sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
640
  }
641 642

  printf("%s",stats_buffer);
643
    
644
# ifdef ENABLE_XFORMS_WRITE_STATS
645 646 647 648 649 650 651 652 653 654 655 656 657 658
  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);
    }
  }
659
# endif
660
    
Raymond Knopp's avatar
 
Raymond Knopp committed
661
  pthread_exit((void*)arg);
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
}
#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;
687 688 689 690 691 692 693

  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);
694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715
 
  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);
    }
716 717
  else 
    printf("[EMOS] Opened GPS, gps_data=%p\n");
718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762
  
  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
763
	if (UE_flag==0)
764
	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
765
	else
766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826
	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

827 828


829
#if defined(ENABLE_ITTI)
830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847
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
848
#if defined(ENABLE_ITTI)
849
void *l2l1_task(void *arg)
850
{
Raymond Knopp's avatar
 
Raymond Knopp committed
851 852 853 854 855
  MessageDef *message_p = NULL;
  int         result;

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
856

Raymond Knopp's avatar
 
Raymond Knopp committed
857 858
  if (UE_flag == 0) {
    /* Wait for the initialize message */
859
    do {
Raymond Knopp's avatar
 
Raymond Knopp committed
860 861 862 863
      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);
      }
864 865 866
      itti_receive_msg (TASK_L2L1, &message_p);

      switch (ITTI_MSG_ID(message_p)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
867 868 869 870 871 872 873 874 875 876 877 878 879 880
      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;
881
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903
    } 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;
904

Raymond Knopp's avatar
 
Raymond Knopp committed
905 906 907 908 909 910 911 912 913 914 915 916
    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);
917

Raymond Knopp's avatar
 
Raymond Knopp committed
918
  return NULL;
919 920 921
}
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
922

Raymond Knopp's avatar
 
Raymond Knopp committed
923
void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) {
Raymond Knopp's avatar
 
Raymond Knopp committed
924 925 926 927

  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
928
  int slot_sizeF = (phy_vars_eNB->lte_frame_parms.ofdm_symbol_size)*
Raymond Knopp's avatar
 
Raymond Knopp committed
929
    ((phy_vars_eNB->lte_frame_parms.Ncp==1) ? 6 : 7);
Raymond Knopp's avatar
 
Raymond Knopp committed
930 931 932

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
939
    
Raymond Knopp's avatar
 
Raymond Knopp committed
940 941 942 943 944 945 946 947 948 949
    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
950 951 952 953 954 955 956 957
	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
958 959 960 961 962 963
      }
      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
964 965 966 967
	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
968
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
969 970

      for (i=0; i<phy_vars_eNB->lte_frame_parms.samples_per_tti; i++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
971 972 973 974 975 976
	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]=
Raymond Knopp's avatar
 
Raymond Knopp committed
977
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
978
	  ((short*)dummy_tx_b)[2*i]<<4;
Raymond Knopp's avatar
 
Raymond Knopp committed
979
#else
980
	((short*)dummy_tx_b)[2*i]<<5;
Raymond Knopp's avatar
 
Raymond Knopp committed
981
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
982
	((short*)&phy_vars_eNB->lte_eNB_common_vars.txdata[0][aa][tx_offset])[1]=
Raymond Knopp's avatar
 
Raymond Knopp committed
983
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
984
	  ((short*)dummy_tx_b)[2*i+1]<<4;
Raymond Knopp's avatar
 
Raymond Knopp committed
985
#else
986
	((short*)dummy_tx_b)[2*i+1]<<5;
Raymond Knopp's avatar
 
Raymond Knopp committed
987
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
988 989 990 991 992 993 994 995
      }
    }
  }
}


int eNB_thread_tx_status[10];
static void * eNB_thread_tx(void *param) {
Raymond Knopp's avatar
 
Raymond Knopp committed
996 997 998

  //unsigned long cpuid;
  eNB_proc_t *proc = (eNB_proc_t*)param;
Raymond Knopp's avatar
 
Raymond Knopp committed
999
  //  RTIME time_in,time_out;
Raymond Knopp's avatar
 
Raymond Knopp committed
1000 1001
#ifdef RTAI
  RT_TASK *task;
1002
  char task_name[8];
1003 1004 1005 1006
#else 
#ifdef LOWLATENCY
  struct sched_attr attr;
  unsigned int flags = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1007
#endif
1008
#endif 
Raymond Knopp's avatar
 
Raymond Knopp committed
1009 1010

 
Raymond Knopp's avatar
 
Raymond Knopp committed
1011
  /*#if defined(ENABLE_ITTI)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1012
  // Wait for eNB application initialization to be complete (eNB registration to MME)
Raymond Knopp's avatar
 
Raymond Knopp committed
1013
  wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
Raymond Knopp's avatar
 
Raymond Knopp committed
1014
  #endif*/
Raymond Knopp's avatar
 
Raymond Knopp committed
1015

Raymond Knopp's avatar
 
Raymond Knopp committed
1016
#ifdef RTAI
1017
  sprintf(task_name,"TXC%dS%d",proc->CC_id,proc->subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
1018 1019 1020
  task = rt_task_init_schmod(nam2num(task_name), 0, 0, 0, SCHED_FIFO, 0xF);

  if (task==NULL) {
1021 1022 1023
    LOG_E(PHY,"[SCHED][eNB] Problem starting eNB_proc_TX thread_index %d (%s)!!!!\n",proc->subframe,task_name);
    return 0;
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1024
  else {
1025 1026 1027 1028 1029
    LOG_I(PHY,"[SCHED][eNB] eNB TX thread CC %d SF %d started with id %p\n",
	  proc->CC_id,
	  proc->subframe,
	  task);
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1030
#else
1031 1032 1033 1034 1035 1036
#ifdef LOWLATENCY
  attr.size = sizeof(attr);
  attr.sched_flags = 0;
  attr.sched_nice = 0;
  attr.sched_priority = 0;
  
Navid Nikaein's avatar
Navid Nikaein committed
1037
  /* This creates a 1ms reservation every 10ms period*/
1038 1039 1040 1041 1042 1043
  attr.sched_policy = SCHED_DEADLINE;
  attr.sched_runtime = 1 * 1000000;  // each tx thread requires 1ms to finish its job
  attr.sched_deadline =1 * 1000000; // each tx thread will finish within 1ms
  attr.sched_period = 1 * 10000000; // each tx thread has a period of 10ms from the starting point
  
  if (sched_setattr(0, &attr, flags) < 0 ){
1044 1045 1046
    perror("[SCHED] eNB tx thread: sched_setattr failed\n");
    exit(-1);
  }
1047
  LOG_I(HW,"[SCHED] eNB TX deadline thread %d(id %ld) started on CPU %d\n",
1048
	proc->subframe, gettid(),sched_getcpu());
1049 1050
#else 
  LOG_I(HW,"[SCHED] eNB TX thread %d started on CPU %d\n",
1051
	proc->subframe,sched_getcpu());
1052 1053
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065
#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
1066
    
1067
    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
1068
    
1069 1070
    //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->instance_cnt_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1071

1072 1073 1074 1075 1076
    if (pthread_mutex_lock(&proc->mutex_tx) != 0) {
      LOG_E(PHY,"[SCHED][eNB] error locking mutex for eNB TX proc %d\n",proc->subframe);
      oai_exit=1;
    }
    else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1077
      
1078 1079 1080
      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));
	//printf("Waiting and unlocking mutex for eNB proc %d (subframe_tx %d)\n",proc->subframe,proc->instance_cnt_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1081
	
1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092
	pthread_cond_wait(&proc->cond_tx,&proc->mutex_tx);
      }
      //      LOG_I(PHY,"Waking up and unlocking mutex for eNB proc %d instance_cnt_tx %d\n",proc->subframe,proc->instance_cnt_tx);
      if (pthread_mutex_unlock(&proc->mutex_tx) != 0) {	
	LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for eNB TX proc %d\n",proc->subframe);
	oai_exit=1;
      }
    }
    vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_TX0+(2*proc->subframe),1);    
    vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB, proc->frame_tx);
    start_meas(&softmodem_stats_tx_sf[proc->subframe]);
1093

1094
    if (oai_exit) break;
Raymond Knopp's avatar
 
Raymond Knopp committed
1095

Raymond Knopp's avatar
 
Raymond Knopp committed
1096
    
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_tx)==SF_DL))||
	 (PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms.frame_type == FDD))) {
ghaddab's avatar
ghaddab committed
1100

1101
      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
1102
      
1103 1104 1105 1106
    }
    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
1107
    
1108
    do_OFDM_mod_rt(proc->subframe_tx,PHY_vars_eNB_g[0][proc->CC_id]);  
Raymond Knopp's avatar
 
Raymond Knopp committed
1109
    
1110 1111 1112 1113 1114
    if (pthread_mutex_lock(&proc->mutex_tx) != 0) {
      printf("[openair][SCHED][eNB] error locking mutex for eNB TX proc %d\n",proc->subframe);
    }
    else {
      proc->instance_cnt_tx--;
Raymond Knopp's avatar
 
Raymond Knopp committed
1115
      
1116 1117 1118 1119
      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
1120

Raymond Knopp's avatar
 
Raymond Knopp committed
1121
    
1122 1123 1124
    proc->frame_tx++;
    if (proc->frame_tx==1024)
      proc->frame_tx=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1125

1126
  }    
1127
  stop_meas(&softmodem_stats_tx_sf[proc->subframe]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1128 1129 1130 1131
  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
1132
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1133 1134 1135 1136 1137 1138 1139 1140 1141 1142
#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
1143
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1144 1145 1146 1147 1148
#ifdef DEBUG_THREADS
  printf("Exiting eNB TX thread %d\n",proc->subframe);
#endif
}

1149 1150
int eNB_thread_rx_status[10];
static void * eNB_thread_rx(void *param) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1151 1152 1153 1154 1155 1156

  //unsigned long cpuid;
  eNB_proc_t *proc = (eNB_proc_t*)param;
  //  RTIME time_in,time_out;
#ifdef RTAI
  RT_TASK *task;
1157
  char task_name[8];
1158 1159 1160 1161 1162
#else
#ifdef LOWLATENCY
  struct sched_attr attr;
  unsigned int flags = 0;
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1163 1164
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1165
  /*#if defined(ENABLE_ITTI)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1166
  // Wait for eNB application initialization to be complete (eNB registration to MME) 
Raymond Knopp's avatar
 
Raymond Knopp committed
1167
  wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
Raymond Knopp's avatar
 
Raymond Knopp committed
1168
  #endif*/
Raymond Knopp's avatar
 
Raymond Knopp committed
1169 1170

#ifdef RTAI
1171
  sprintf(task_name,"RXC%1dS%1d",proc->CC_id,proc->subframe);
Raymond Knopp's avatar
 
Raymond Knopp committed
1172 1173 1174
  task = rt_task_init_schmod(nam2num(task_name), 0, 0, 0, SCHED_FIFO, 0xF);

  if (task==NULL) {
1175 1176 1177
    LOG_E(PHY,"[SCHED][eNB] Problem starting eNB_proc_RX thread_index %d (%s)!!!!\n",proc->subframe,task_name);
    return 0;
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1178
  else {
1179 1180
    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
1181
	  proc->subframe,
1182
	  task); /*,rtai_cpuid()*/
Raymond Knopp's avatar
 
Raymond Knopp committed
1183 1184
  }
#else
1185 1186 1187 1188 1189 1190
#ifdef LOWLATENCY
  attr.size = sizeof(attr);
  attr.sched_flags = 0;
  attr.sched_nice = 0;
  attr.sched_priority = 0;
  
Navid Nikaein's avatar
Navid Nikaein committed
1191
  /* This creates a 2ms reservation every 10ms period*/
1192
  attr.sched_policy = SCHED_DEADLINE;
Navid Nikaein's avatar
Navid Nikaein committed
1193 1194 1195
  attr.sched_runtime  = 1 * 2000000;  // each rx thread must finish its job in the worst case in 2ms
  attr.sched_deadline = 1 * 2000000; // each rx thread will finish within 2ms
  attr.sched_period   = 1 * 10000000; // each rx thread has a period of 10ms from the starting point
1196 1197 1198 1199 1200 1201
  
  if (sched_setattr(0, &attr, flags) < 0 ){
    perror("[SCHED] eNB RX sched_setattr failed\n");
    exit(-1);
  }
  LOG_I(HW,"[SCHED] eNB RX deadline thread %d(id %ld) started on CPU %d\n",
Raymond Knopp's avatar
 
Raymond Knopp committed
1202
	proc->subframe, gettid(),sched_getcpu());
1203 1204
#else 
  LOG_I(HW,"[SCHED][eNB] eNB RX thread %d started on CPU %d\n",
Raymond Knopp's avatar
 
Raymond Knopp committed
1205
	proc->subframe,sched_getcpu());
1206 1207
#endif
 
Raymond Knopp's avatar
 
Raymond Knopp committed
1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221
#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
1222
    
ghaddab's avatar
ghaddab committed
1223
    // LOG_I(PHY,"Locking mutex for eNB proc %d (IC %d,mutex %p)\n",proc->subframe,proc->instance_cnt_rx,&proc->mutex_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1224 1225 1226 1227 1228 1229
    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) {
ghaddab's avatar
ghaddab committed
1230
	//	LOG_I(PHY,"Waiting and unlocking mutex for eNB proc %d (IC %d,lock %d)\n",proc->subframe,proc->instance_cnt_rx,pthread_mutex_trylock(&proc->mutex_rx));
Raymond Knopp's avatar
 
Raymond Knopp committed
1231 1232

	pthread_cond_wait(&proc->cond_rx,&proc->mutex_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1233
      }
ghaddab's avatar
ghaddab committed
1234
      //      LOG_I(PHY,"Waking up and unlocking mutex for eNB RX proc %d instance_cnt_rx %d\n",proc->subframe,proc->instance_cnt_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1235 1236
      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
1237 1238
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1239
    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
1240
    vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, proc->frame_rx);
1241 1242
    start_meas(&softmodem_stats_rx_sf[proc->subframe]);
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1243 1244
    if (oai_exit) break;
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1245 1246 1247
    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
1248
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1249 1250
    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
1251 1252 1253 1254
    }
      
    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
1255 1256
    }
    else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1257
      proc->instance_cnt_rx--;
Raymond Knopp's avatar
 
Raymond Knopp committed
1258
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1259 1260
      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
1261 1262
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1263 1264 1265 1266

    proc->frame_rx++;
    if (proc->frame_rx==1024)
      proc->frame_rx=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1267
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1268
  }
1269
  stop_meas(&softmodem_stats_rx_sf[proc->subframe]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1270
  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
1271
#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283
  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
1284 1285
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1286 1287 1288
#ifdef DEBUG_THREADS
  printf("Exiting eNB RX thread %d\n",proc->subframe);
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1289 1290 1291 1292
}



Raymond Knopp's avatar
 
Raymond Knopp committed
1293

1294
void init_eNB_proc(void) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1295 1296

  int i;
Raymond Knopp's avatar
 
Raymond Knopp committed
1297 1298 1299 1300
  int CC_id;

  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    for (i=0;i<10;i++) {
1301
      /*set the stack sizw */ 
Raymond Knopp's avatar
 
Raymond Knopp committed
1302
      pthread_attr_init (&attr_eNB_proc_tx[CC_id][i]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1303
      if (pthread_attr_setstacksize(&attr_eNB_proc_tx[CC_id][i],PTHREAD_STACK_MIN) != 0)
1304 1305 1306
	perror("[ENB_PROC_TX] setting thread stack size failed\n");

      pthread_attr_init (&attr_eNB_proc_rx[CC_id][i]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1307
      if (pthread_attr_setstacksize(&attr_eNB_proc_rx[CC_id][i],PTHREAD_STACK_MIN) != 0)
1308 1309 1310
	perror("[ENB_PROC_RX] setting thread stack size failed\n");
      /* set the kernel scheduling policy and priority */
#ifndef LOWLATENCY
Raymond Knopp's avatar
 
Raymond Knopp committed
1311 1312 1313 1314 1315 1316 1317 1318
      //attr_dlsch_threads.priority = 1;
      sched_param_eNB_proc_tx[CC_id][i].sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY;
      pthread_attr_setschedparam  (&attr_eNB_proc_tx[CC_id][i], &sched_param_eNB_proc_tx[CC_id][i]);
      pthread_attr_setschedpolicy (&attr_eNB_proc_tx[CC_id][i], SCHED_FIFO);
      //attr_dlsch_threads.priority = 1;
      sched_param_eNB_proc_rx[CC_id][i].sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY;
      pthread_attr_setschedparam  (&attr_eNB_proc_rx[CC_id][i], &sched_param_eNB_proc_rx[CC_id][i]);
      pthread_attr_setschedpolicy (&attr_eNB_proc_rx[CC_id][i], SCHED_FIFO);
1319
#endif       
Raymond Knopp's avatar
 
Raymond Knopp committed
1320
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332
      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;
1333
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1334 1335
      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
1336
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1337 1338
      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
1339
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1340 1341 1342
    }
  
  
1343
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1344 1345
    // 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
1346
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1347
    //PHY_vars_eNB_g[0][CC_id]->proc[0].frame_rx = 1023;
Raymond Knopp's avatar
 
Raymond Knopp committed
1348 1349
    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
1350
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1351 1352
    // 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
1353
    //    PHY_vars_eNB_g[0][CC_id]->proc[7].frame_tx = 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1354 1355
    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
1356
    //    PHY_vars_eNB_g[0][CC_id]->proc[0].frame_tx = 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1357
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1358 1359
  }
}
Raymond Knopp's avatar
 
Raymond Knopp committed
1360

1361
void kill_eNB_proc(void) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1362 1363

  int i;
1364
  void *status_tx,*status_rx;
Raymond Knopp's avatar
 
Raymond Knopp committed
1365
  int CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1366

Raymond Knopp's avatar
 
Raymond Knopp committed
1367 1368 1369
  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) 
    for (i=0;i<10;i++) {
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1370
#ifdef DEBUG_THREADS
Raymond Knopp's avatar
 
Raymond Knopp committed
1371
      printf("Killing TX CC_id %d thread %d\n",CC_id,i);
Raymond Knopp's avatar
 
Raymond Knopp committed
1372
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1373 1374
      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
1375
#ifdef DEBUG_THREADS
1376
      printf("Joining eNB TX CC_id %d thread %d...\n",CC_id,i);
Raymond Knopp's avatar
 
Raymond Knopp committed
1377
#endif
1378
      pthread_join(PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_tx,&status_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1379
#ifdef DEBUG_THREADS
1380
      if (status_tx) printf("status %p...\n",status_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1381 1382
#endif
#ifdef DEBUG_THREADS
Raymond Knopp's avatar
 
Raymond Knopp committed
1383
      printf("Killing RX CC_id %d thread %d\n",CC_id,i);
Raymond Knopp's avatar
 
Raymond Knopp committed
1384
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1385 1386
      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
1387
#ifdef DEBUG_THREADS
1388
      printf("Joining eNB RX CC_id %d thread %d...\n",CC_id,i);
Raymond Knopp's avatar
 
Raymond Knopp committed
1389
#endif
1390
      pthread_join(PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_rx,&status_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1391
#ifdef DEBUG_THREADS 
1392
      if (status_rx) printf("status %p...\n",status_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1393
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1394 1395 1396 1397 1398
      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
1399 1400 1401
}


Raymond Knopp's avatar
 
Raymond Knopp committed
1402 1403


Raymond Knopp's avatar
 
Raymond Knopp committed
1404 1405
  
/* This is the main eNB thread. */
Raymond Knopp's avatar
 
Raymond Knopp committed
1406 1407
int eNB_thread_status;

Raymond Knopp's avatar
 
Raymond Knopp committed
1408

Raymond Knopp's avatar
 
Raymond Knopp committed
1409

1410 1411 1412 1413
static void *eNB_thread(void *arg)
{
#ifdef RTAI
  RT_TASK *task;
1414 1415 1416 1417 1418 1419
#else 
#ifdef LOWLATENCY
  struct sched_attr attr;
  unsigned int flags = 0;
  unsigned long mask = 1; /* processor 0 */
#endif
1420
#endif
1421

1422 1423
#ifdef EXMIMO
  unsigned char slot=0;
1424 1425
#else
  unsigned char slot=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1426
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1427
  int frame=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1428
  int CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1429

1430
  RTIME time_in, time_diff;
Raymond Knopp's avatar
 
Raymond Knopp committed
1431

Raymond Knopp's avatar
 
Raymond Knopp committed
1432
  int sf;
1433
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1434
  volatile unsigned int *DAQ_MBOX = openair0_daq_cnt();
Raymond Knopp's avatar
 
Raymond Knopp committed
1435 1436
  int mbox_target=0,mbox_current=0;
  int hw_slot,delay_cnt;
Raymond Knopp's avatar
 
Raymond Knopp committed
1437 1438
  int diff;
  int ret;
1439
  int first_run=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1440
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1441 1442
  unsigned int rx_cnt = 0;
  unsigned int tx_cnt = tx_delay;
Raymond Knopp's avatar
 
Raymond Knopp committed
1443
  //  int tx_offset;
Raymond Knopp's avatar
 
Raymond Knopp committed
1444 1445
  void *rxp[2],*txp[2];
  int i;
Raymond Knopp's avatar
 
Raymond Knopp committed
1446

Raymond Knopp's avatar
 
Raymond Knopp committed
1447
  int trace_cnt=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1448
  hw_subframe = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1449
#endif
1450

Raymond Knopp's avatar
 
Raymond Knopp committed
1451 1452
  struct timespec trx_time0,trx_time1,trx_time2;

1453
  /*
Raymond Knopp's avatar
 
Raymond Knopp committed
1454 1455 1456 1457
    #if defined(ENABLE_ITTI)
    // Wait for eNB application initialization to be complete (eNB registration to MME) 
    wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
    #endif
1458
  */
1459

1460
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
1461
  task = rt_task_init_schmod(nam2num("TASK0"), 0, 0, 0, SCHED_FIFO, 0xF);
1462 1463
#else 
#ifdef LOWLATENCY
Raymond Knopp's avatar
 
Raymond Knopp committed
1464 1465 1466 1467
  attr.size = sizeof(attr);
  attr.sched_flags = 0;
  attr.sched_nice = 0;
  attr.sched_priority = 0;
1468
   
Raymond Knopp's avatar
 
Raymond Knopp committed
1469 1470 1471 1472 1473
  /* This creates a .5 ms  reservation */
  attr.sched_policy = SCHED_DEADLINE;
  attr.sched_runtime  = 0.5 * 1000000;
  attr.sched_deadline = 0.5 * 1000000;
  attr.sched_period   = 1   * 1000000;
1474
   
Raymond Knopp's avatar
 
Raymond Knopp committed
1475 1476 1477 1478
  /* pin the eNB main thread to CPU0*/
  /* if (pthread_setaffinity_np(pthread_self(), sizeof(mask),&mask) <0) {
     perror("[MAIN_ENB_THREAD] pthread_setaffinity_np failed\n");
     }*/
1479
   
Raymond Knopp's avatar
 
Raymond Knopp committed
1480 1481 1482 1483 1484 1485 1486
  if (sched_setattr(0, &attr, flags) < 0 ){
    perror("[SCHED] main eNB thread: sched_setattr failed\n");
    exit_fun("Nothing to add");
  } else {
    LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %ld started on CPU %d\n",
	  gettid(),sched_getcpu());
  }
1487
#endif
1488 1489 1490 1491
#endif

  if (!oai_exit) {
#ifdef RTAI
1492
    printf("[SCHED][eNB] Started eNB main thread (id %p)\n",task);
Raymond Knopp's avatar
 
Raymond Knopp committed
1493
#else
1494
    printf("[SCHED][eNB] Started eNB main thread on CPU %d\n",
Raymond Knopp's avatar
 
Raymond Knopp committed
1495
	   sched_getcpu());
1496 1497 1498
#endif

#ifdef HARD_RT
1499
    rt_make_hard_real_time();
1500 1501
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1502
    printf("eNB_thread: mlockall in ...\n");
1503
    mlockall(MCL_CURRENT | MCL_FUTURE);
Raymond Knopp's avatar
 
Raymond Knopp committed
1504
    printf("eNB_thread: mlockall out ...\n");
1505

1506 1507 1508 1509
    timing_info.time_min = 100000000ULL;
    timing_info.time_max = 0;
    timing_info.time_avg = 0;
    timing_info.n_samples = 0;
1510

1511
    printf("waiting for sync (eNB_thread)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1512 1513 1514
#ifdef RTAI
    rt_sem_wait(sync_sem);
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1515
    pthread_mutex_lock(&sync_mutex);
1516 1517
    while (sync_var<0)
      pthread_cond_wait(&sync_cond, &sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
1518
    pthread_mutex_unlock(&sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
1519 1520 1521
#endif
    //    printf("starting eNB thread @ %llu\n",get_usrp_time(&openair0));

Raymond Knopp's avatar
 
Raymond Knopp committed
1522
    while (!oai_exit) {
1523
      start_meas(&softmodem_stats_mt);
1524
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1525 1526
      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
1527 1528
      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
1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540
      //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;
      
1541 1542 1543 1544 1545
      //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;
1546
	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);
1547 1548
      } 

Raymond Knopp's avatar
 
Raymond Knopp committed
1549 1550
      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
1551
	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
1552
	slot++;
1553 1554 1555 1556 1557 1558 1559
	if (exit_missed_slots==1){
	  stop_meas(&softmodem_stats_mt);
	  exit_fun("[HW][eNB] missed slot");
	}else{
	  num_missed_slots++;
	  LOG_W(HW,"[eNB] just missed slot (total missed slots %ld)\n", num_missed_slots);
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
1560 1561 1562 1563
      }
      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
1564
      vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *DAQ_MBOX);
Raymond Knopp's avatar
 
Raymond Knopp committed
1565 1566 1567 1568 1569 1570 1571 1572 1573 1574
      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
1575
	vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *DAQ_MBOX);
Raymond Knopp's avatar
 
Raymond Knopp committed
1576 1577 1578 1579 1580 1581
	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) {
1582
	  stop_meas(&softmodem_stats_mt);
Raymond Knopp's avatar
 
Raymond Knopp committed
1583 1584 1585 1586 1587
	  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
1588
	  diff = 150-mbox_current+mbox_target;
Raymond Knopp's avatar
 
Raymond Knopp committed
1589
	else if ((mbox_current<15) && (mbox_target>=135))
Raymond Knopp's avatar
 
Raymond Knopp committed
1590
	  diff = -150+mbox_target-mbox_current;
Raymond Knopp's avatar
 
Raymond Knopp committed
1591
	else
Raymond Knopp's avatar
 
Raymond Knopp committed
1592
	  diff = mbox_target - mbox_current;
Raymond Knopp's avatar
 
Raymond Knopp committed
1593
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1594

1595
#else  // EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1596 1597
      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
1598 1599
      while (rx_cnt < sf_bounds[hw_subframe]) {

Raymond Knopp's avatar
 
Raymond Knopp committed
1600 1601
	openair0_timestamp time0,time1;
	unsigned int rxs;
Raymond Knopp's avatar
 
Raymond Knopp committed
1602
#ifndef USRP_DEBUG
Raymond Knopp's avatar
 
Raymond Knopp committed
1603
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1604

Raymond Knopp's avatar
 
Raymond Knopp committed
1605 1606
	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);
1607

Raymond Knopp's avatar
 
Raymond Knopp committed
1608

Raymond Knopp's avatar
 
Raymond Knopp committed
1609
	clock_gettime(CLOCK_MONOTONIC,&trx_time0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1610 1611
	for (i=0;i<PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_rx;i++)
	  rxp[i] = (void*)&rxdata[i][rx_cnt*samples_per_packets];
1612
	start_meas(&softmodem_stats_hw);
1613 1614
	//	printf("rxp[0] %p\n",rxp[0]);

Raymond Knopp's avatar
 
Raymond Knopp committed
1615 1616
	rxs = openair0.trx_read_func(&openair0, 
				     &timestamp, 
Raymond Knopp's avatar
 
Raymond Knopp committed
1617 1618 1619
				     rxp, 
				     samples_per_packets,
				     PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_rx);
1620
	stop_meas(&softmodem_stats_hw);
Raymond Knopp's avatar
 
Raymond Knopp committed
1621
	clock_gettime(CLOCK_MONOTONIC,&trx_time1);
ghaddab's avatar
ghaddab committed
1622

Raymond Knopp's avatar
 
Raymond Knopp committed
1623 1624
	if (rxs != samples_per_packets)
	  oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1625
 
Raymond Knopp's avatar
 
Raymond Knopp committed
1626

Raymond Knopp's avatar
 
Raymond Knopp committed
1627 1628
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,0);

Raymond Knopp's avatar
 
Raymond Knopp committed
1629
	// Transmit TX buffer based on timestamp from RX
Raymond Knopp's avatar
 
Raymond Knopp committed
1630
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1631 1632 1633
	
	for (i=0;i<PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_tx;i++)
	  txp[i] = (void*)&txdata[i][tx_cnt*samples_per_packets];
Raymond Knopp's avatar
 
Raymond Knopp committed
1634
		
Raymond Knopp's avatar
 
Raymond Knopp committed
1635 1636
	openair0.trx_write_func(&openair0, 
				(timestamp+samples_per_packets*tx_delay-tx_forward_nsamps), 
Raymond Knopp's avatar
 
Raymond Knopp committed
1637
				txp,
Raymond Knopp's avatar
 
Raymond Knopp committed
1638
				samples_per_packets, 
Raymond Knopp's avatar
 
Raymond Knopp committed
1639
				PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_tx,
Raymond Knopp's avatar
 
Raymond Knopp committed
1640
				1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1641
	
1642
	stop_meas(&softmodem_stats_mt);
Raymond Knopp's avatar
 
Raymond Knopp committed
1643 1644
	clock_gettime(CLOCK_MONOTONIC,&trx_time2);

Raymond Knopp's avatar
 
Raymond Knopp committed
1645
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1646
	/*
1647
	  if (trace_cnt++<10) 
Raymond Knopp's avatar
 
Raymond Knopp committed
1648
	  printf("TRX: t1 %llu (trx_read), t2 %llu (trx_write)\n",(long long unsigned int)(trx_time1.tv_nsec  - trx_time0.tv_nsec), (long long unsigned int)(trx_time2.tv_nsec - trx_time1.tv_nsec));
Raymond Knopp's avatar
 
Raymond Knopp committed
1649
	*/
Raymond Knopp's avatar
 
Raymond Knopp committed
1650 1651 1652 1653 1654 1655 1656 1657 1658
#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
1659
	      //	      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
1660 1661 1662 1663 1664 1665 1666 1667
	      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
1668
		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
1669 1670 1671 1672 1673
		oai_exit=1;
	      }
	    }
	  }
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
1674 1675
	rx_cnt++;
	tx_cnt++;
Raymond Knopp's avatar
 
Raymond Knopp committed
1676 1677 1678

	if(tx_cnt == max_cnt)
	  tx_cnt = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1679 1680
      }

Raymond Knopp's avatar
 
Raymond Knopp committed
1681 1682
      if(rx_cnt == max_cnt)
	rx_cnt = 0; 
Raymond Knopp's avatar
 
Raymond Knopp committed
1683
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1684 1685 1686

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1689

Raymond Knopp's avatar
 
Raymond Knopp committed
1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710
      
      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
1711
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
1712 1713
      */
      //}
1714
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1715
      if ((slot&1) == 1) {
1716
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1717 1718 1719 1720 1721
	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
1722
	
Raymond Knopp's avatar
 
Raymond Knopp committed
1723
	for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
1724
#ifdef EXMIMO 
Raymond Knopp's avatar
 
Raymond Knopp committed
1725 1726
	  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
1727
	  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1728 1729 1730 1731 1732 1733 1734
	  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);
1735
	      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1736 1737 1738 1739 1740
	    }
	    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
1741
	  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1742 1743 1744 1745 1746
#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 {
ghaddab's avatar
ghaddab committed
1747
	    //		      LOG_I(PHY,"[eNB] Waking up eNB process %d (IC %d) CC_id %d rx_cnt %d\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx,CC_id,rx_cnt); 
Raymond Knopp's avatar
 
Raymond Knopp committed
1748 1749 1750 1751 1752
	    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
1753
	      }
ghaddab's avatar
ghaddab committed
1754
              //else
Raymond Knopp's avatar
 
Raymond Knopp committed
1755
	      // LOG_I(PHY,"[eNB] pthread_cond_signal for eNB RX thread %d instance_cnt_rx %d\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
1756 1757
	    }
	    else {
ghaddab's avatar
ghaddab committed
1758
	      LOG_W(PHY,"[eNB] Frame %d, eNB RX thread %d busy!! instance_cnt %d CC_id %d\n",PHY_vars_eNB_g[0][CC_id]->proc[sf].frame_rx,sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx,CC_id);
Raymond Knopp's avatar
 
Raymond Knopp committed
1759
	      oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1760
	    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1761
	  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1762
	    
Raymond Knopp's avatar
 
Raymond Knopp committed
1763 1764
	}
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1765 1766
	  
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1767 1768 1769 1770 1771 1772 1773
#ifndef RTAI
      //pthread_mutex_lock(&tti_mutex);
#endif




Raymond Knopp's avatar
 
Raymond Knopp committed
1774
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
1775
      slot++;
Raymond Knopp's avatar
 
Raymond Knopp committed
1776 1777 1778 1779
      if (slot == 20) {
	frame++;
	slot = 0;
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1780
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1781 1782 1783
      hw_subframe++;
      slot+=2;
      if(hw_subframe==10) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1784
	hw_subframe = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1785
	frame++;
Raymond Knopp's avatar
 
Raymond Knopp committed
1786
	slot = 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1787
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1788
#endif     
Raymond Knopp's avatar
 
Raymond Knopp committed
1789 1790


1791
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1792
      itti_update_lte_time(frame, slot);
1793
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1794 1795 1796 1797 1798 1799
    }
  }
#ifdef DEBUG_THREADS
  printf("eNB_thread: finished, ran %d times.\n",frame);
#endif
  
1800
#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
1801
  rt_make_soft_real_time();
1802 1803
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1804 1805 1806 1807 1808

#ifdef DEBUG_THREADS
  printf("Exiting eNB_thread ...");
#endif
  // clean task
1809
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
1810 1811 1812 1813
  rt_task_delete(task);
#else
  eNB_thread_status = 0;
  pthread_exit(&eNB_thread_status);
1814
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1815 1816 1817 1818 1819
#ifdef DEBUG_THREADS
  printf("eNB_thread deleted. returning\n");
#endif
  return 0;
}
1820

Raymond Knopp's avatar
 
Raymond Knopp committed
1821 1822 1823
#ifdef USRP_DEBUG
int is_synchronized=1;
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1824
int is_synchronized=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1825
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1826

1827 1828 1829 1830 1831 1832
typedef enum {
  rssi=0,
  pbch=1,
  si=2
} sync_mode_t;

Raymond Knopp's avatar
 
Raymond Knopp committed
1833 1834
static void *UE_thread_synch(void *arg) {

1835
  int i,hw_slot_offset,CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1836
  PHY_VARS_UE *UE = arg;
1837 1838 1839 1840 1841
  int current_band = 0;
  int current_offset = 0;
  sync_mode_t sync_mode = rssi;
  int rssi_lin,rssi_min,rssi_max,rssi_avg;
  double rssi_dBm,rssi_min_dBm,rssi_max_dBm;
1842 1843
  int16_t spectrum[1024*2];
  int16_t power_avg[600];
Raymond Knopp's avatar
 
Raymond Knopp committed
1844

Raymond Knopp's avatar
 
Raymond Knopp committed
1845
  printf("UE_thread_sync in with PHY_vars_UE %p\n",arg);
Raymond Knopp's avatar
 
Raymond Knopp committed
1846
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
1847
  printf("waiting for USRP sync (UE_thread_synch) \n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1848 1849 1850
#ifdef RTAI
  rt_sem_wait(sync_sem);
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
1851 1852 1853

  pthread_mutex_lock(&sync_mutex);
  printf("Locked sync_mutex, waiting (UE_sync_thread)\n");
1854 1855
  while (sync_var<0)
    pthread_cond_wait(&sync_cond, &sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
1856 1857
  pthread_mutex_unlock(&sync_mutex);
  printf("unlocked sync_mutex (UE_sync_thread)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1858
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1859
  printf("starting UE synch thread\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1860
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1861

1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883
  if (UE_scan == 1) {
    for (card=0;card<MAX_CARDS;card++) {
      for (i=0; i<openair0_cfg[card].rx_num_channels; i++) {
	downlink_frequency[card][i] = bands_to_scan.band_info[0].dl_min;
	uplink_frequency_offset[card][i] = bands_to_scan.band_info[0].ul_min-bands_to_scan.band_info[0].dl_min;
    
	openair0_cfg[card].rx_freq[i] = downlink_frequency[card][i];
	openair0_cfg[card].tx_freq[i] = downlink_frequency[card][i]+uplink_frequency_offset[card][i];
	openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB-USRP_GAIN_OFFSET;  
#ifdef USRP
#ifndef USRP_DEBUG
	openair0_set_frequencies(&openair0,&openair0_cfg[0]);
	//	    openair0_set_gains(&openair0,&openair0_cfg[0]);
#endif
#endif
      }
      }    
	LOG_D(PHY,"[SCHED][UE] Scanning band %d, freq %u\n",bands_to_scan.band_info[0].band, bands_to_scan.band_info[0].dl_min);
      }
  else {
	LOG_D(PHY,"[SCHED][UE] Check absolute frequency %u\n",downlink_frequency[0][0]);
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1884 1885
  while (!oai_exit) {
    
1886 1887 1888 1889 1890 1891
	if (pthread_mutex_lock(&UE->mutex_synch) != 0) {
	LOG_E(PHY,"[SCHED][UE] error locking mutex for UE initial synch thread\n");
	oai_exit=1;
      }
	else {
	while (UE->instance_cnt_synch < 0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1892 1893
	pthread_cond_wait(&UE->cond_synch,&UE->mutex_synch);
      }
1894
	if (pthread_mutex_unlock(&UE->mutex_synch) != 0) {	
Raymond Knopp's avatar
 
Raymond Knopp committed
1895 1896 1897
	LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for UE Initial Synch thread\n");
	oai_exit=1;
      }
1898
      }  // mutex_lock      
Raymond Knopp's avatar
 
Raymond Knopp committed
1899

1900 1901 1902 1903 1904 1905

	switch (sync_mode) {
      case rssi:
	rssi_min = 1<<31;
	rssi_max = 0;
	rssi_avg = 0;
1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918
	memset(power_dBm_max,0,1024);
	for (i=0;i<76800*4;i+=1024) {
	  //compute frequency-domain representation of 1024-sample chunk
	  dft1024(&PHY_vars_UE_g[0][0]->lte_ue_common_vars.rxdata[0][i],
		  spectrum,
		  1);
	  compute_spectrum_stats(spectrum,
				 power_avg,
				 power_max,
				 power_min,
				 PHY_vars_UE_g[0][0]->rx_total_gain_dB);
	}
	  /*
1919 1920
	rssi_lin = signal_energy(&PHY_vars_UE_g[0][0]->lte_ue_common_vars.rxdata[0][i],7680);
	if (PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_rx>1)
1921
	  rssi_lin += signal_energy(&PHY_vars_UE_g[0][0]->lte_ue_common_vars.rxdata[1][i],7680);
1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960
	rssi_avg += rssi;
	rssi_min = (rssi < rssi_min) ? rssi : rssi_min;
	rssi_max = (rssi > rssi_max) ? rssi : rssi_max;
      }

	rssi_dBm = dB_fixed_times10(rssi_avg/10)/10.0 - PHY_vars_UE_g[0][0]->rx_total_gain_dB;
	rssi_max_dBm = dB_fixed_times10(rssi_max)/10.0 - PHY_vars_UE_g[0][0]->rx_total_gain_dB;
	rssi_min_dBm = dB_fixed_times10(rssi_min)/10.0 - PHY_vars_UE_g[0][0]->rx_total_gain_dB;

	LOG_D(PHY,"Band %d, DL Freq %u: RSSI (avg, min, max) %f,%f,%f dBm\n",
	  bands_to_scan.band_info[current_band].band,
	  downlink_frequency[0][0],
	  rssi_dBm,
	  rssi_min_dBm,
	  rssi_max_dBm);

	current_offset += 100000; // increase by 1 EARFCN (100kHz)
	if (current_offset+5000000 > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) {
	  current_band++;
	  current_offset=0;
      }
	if (current_band==bands_to_scan.nbands) {
	  current_band=0;
	  
      }

	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;
	openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB-USRP_GAIN_OFFSET;  // 65 calibrated for USRP B210 @ 2.6 GHz
#ifdef USRP
#ifndef USRP_DEBUG
	openair0_set_frequencies(&openair0,&openair0_cfg[0]);
	//	    openair0_set_gains(&openair0,&openair0_cfg[0]);
#endif
#endif
      }
    }	
1961
	  */
1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995
	  break;
      case pbch:
	
	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));
	*/
	  
	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 {
	  
	if (openair_daq_vars.freq_offset >= 0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1996 1997
	openair_daq_vars.freq_offset += 100;
	openair_daq_vars.freq_offset *= -1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1998
      }
1999
	else {
Raymond Knopp's avatar
 
Raymond Knopp committed
2000 2001
	openair_daq_vars.freq_offset *= -1;
      }
2002
	if (abs(openair_daq_vars.freq_offset) > 7500) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2003 2004
	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
2005
      }
2006
	else {
Raymond Knopp's avatar
 
Raymond Knopp committed
2007
	LOG_I(PHY,"[initial_sync] trying carrier off %d Hz, rxgain %d\n",openair_daq_vars.freq_offset,
2008
	  PHY_vars_UE_g[0][0]->rx_total_gain_dB);
Raymond Knopp's avatar
 
Raymond Knopp committed
2009
	for (card=0;card<MAX_CARDS;card++) {
2010 2011 2012 2013
	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;
	openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB-USRP_GAIN_OFFSET;  // 65 calibrated for USRP B210 @ 2.6 GHz
Navid Nikaein's avatar
Navid Nikaein committed
2014
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
2015
#ifndef USRP_DEBUG
2016 2017
	openair0_set_frequencies(&openair0,&openair0_cfg[0]);
	//	    openair0_set_gains(&openair0,&openair0_cfg[0]);
Navid Nikaein's avatar
Navid Nikaein committed
2018
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2019
#endif
2020 2021 2022
      }
    }
	    
Raymond Knopp's avatar
 
Raymond Knopp committed
2023
	//	    openair0_dump_config(&openair0_cfg[0],UE_flag);
2024
	    
Raymond Knopp's avatar
 
Raymond Knopp committed
2025
	//	    rt_sleep_ns(FRAME_PERIOD);
2026 2027 2028 2029 2030 2031 2032
  } // freq_offset
} // initial_sync=0
  break;
 case si:
 default:
break;
}
Raymond Knopp's avatar
 
Raymond Knopp committed
2033
    
2034 2035 2036 2037 2038
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--;
Raymond Knopp's avatar
 
Raymond Knopp committed
2039
      
2040 2041 2042 2043
   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
2044
    
2045 2046
}  // while !oai_exit
return(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
2047 2048 2049 2050
}

static void *UE_thread_tx(void *arg) {

Raymond Knopp's avatar
 
Raymond Knopp committed
2051 2052 2053 2054 2055
#ifdef LOWLATENCY
  struct sched_attr attr;
  unsigned int flags = 0;
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2056 2057 2058 2059 2060 2061 2062 2063 2064 2065
  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;

Raymond Knopp's avatar
 
Raymond Knopp committed
2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083
#ifdef LOWLATENCY
  attr.size = sizeof(attr);
  attr.sched_flags = 0;
  attr.sched_nice = 0;
  attr.sched_priority = 0;
  
  /* This creates a 1ms reservation every 10ms period*/
  attr.sched_policy = SCHED_DEADLINE;
  attr.sched_runtime = 1 * 1000000;  // each tx thread requires 1ms to finish its job
  attr.sched_deadline =1 * 1000000; // each tx thread will finish within 1ms
  attr.sched_period = 1 * 10000000; // each tx thread has a period of 10ms from the starting point
  
  if (sched_setattr(0, &attr, flags) < 0 ){
    perror("[SCHED] eNB tx thread: sched_setattr failed\n");
    exit(-1);
  }
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133
  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
2134
  
Raymond Knopp's avatar
 
Raymond Knopp committed
2135
  PHY_VARS_UE *UE = (PHY_VARS_UE*)arg;
Raymond Knopp's avatar
 
Raymond Knopp committed
2136
  int i;
2137
  /*
2138 2139 2140 2141
    #ifdef LOWLATENCY
    struct sched_attr attr;
    unsigned int flags = 0;
    #endif
2142
  */
Raymond Knopp's avatar
 
Raymond Knopp committed
2143
  UE->instance_cnt_rx=-1;
2144
  /*
2145 2146 2147 2148 2149
    #ifdef LOWLATENCY
    attr.size = sizeof(attr);
    attr.sched_flags = 0;
    attr.sched_nice = 0;
    attr.sched_priority = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2150
  
2151 2152 2153 2154 2155
    // This creates a 1ms reservation every 10ms period
    attr.sched_policy = SCHED_DEADLINE;
    attr.sched_runtime = 1 * 800000;  // each tx thread requires 1ms to finish its job
    attr.sched_deadline =1 * 1000000; // each tx thread will finish within 1ms
    attr.sched_period = 1 * 1000000; // each tx thread has a period of 10ms from the starting point
Raymond Knopp's avatar
 
Raymond Knopp committed
2156
  
2157
    if (sched_setattr(0, &attr, flags) < 0 ){
Raymond Knopp's avatar
 
Raymond Knopp committed
2158 2159
    perror("[SCHED] eNB tx thread: sched_setattr failed\n");
    exit(-1);
2160 2161 2162
    }  
    #endif
  */
Raymond Knopp's avatar
 
Raymond Knopp committed
2163
  mlockall(MCL_CURRENT | MCL_FUTURE);
Raymond Knopp's avatar
 
Raymond Knopp committed
2164
  
2165
#ifndef EXMIMO
ghaddab's avatar
ghaddab committed
2166
  printf("waiting for sync (UE_thread_rx)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
2167 2168 2169 2170 2171
#ifdef RTAI
  rt_sem_wait(sync_sem);
#else
  pthread_mutex_lock(&sync_mutex);
  printf("Locked sync_mutex, waiting (UE_thread_rx)\n");
2172 2173
  while (sync_var<0)
    pthread_cond_wait(&sync_cond, &sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
2174 2175 2176 2177
  pthread_mutex_unlock(&sync_mutex);
  printf("unlocked sync_mutex, waiting (UE_thread_rx)\n");
#endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2178

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

Raymond Knopp's avatar
 
Raymond Knopp committed
2181 2182
  while (!oai_exit) { 
    printf("UE_thread_rx: locking UE RX mutex\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
2183 2184 2185 2186 2187 2188
    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
2189
      printf("UE_thread_rx: unlocking UE RX mutex (IC %d)\n",UE->instance_cnt_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
2190
      while (UE->instance_cnt_rx < 0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2191
	printf("Waiting for cond_rx (%p)\n",(void*)&UE->cond_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
2192
	pthread_cond_wait(&UE->cond_rx,&UE->mutex_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
2193
	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
2194 2195 2196 2197 2198
      }
      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
2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215
      
      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
2216
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2217 2218 2219 2220 2221 2222 2223
    }
    
    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
2224
      
Raymond Knopp's avatar
 
Raymond Knopp committed
2225 2226 2227
      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
2228
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
2229
    printf("UE_thread_rx done\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
2230
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
2231
       
Raymond Knopp's avatar
 
Raymond Knopp committed
2232 2233 2234
  return(0);
}

Raymond Knopp's avatar
 
Raymond Knopp committed
2235 2236 2237



2238
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
2239 2240 2241 2242 2243
#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
2244

Raymond Knopp's avatar
 
Raymond Knopp committed
2245 2246 2247
  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
2248
  // unsigned int aa;
Raymond Knopp's avatar
 
Raymond Knopp committed
2249
  int dummy[2][samples_per_packets];
Raymond Knopp's avatar
 
Raymond Knopp committed
2250 2251 2252 2253 2254
  int dummy_dump = 0;
  int tx_enabled=0;
  int start_rx_stream=0;
  int rx_off_diff = 0;
  int rx_correction_timer = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2255
  int i;
Raymond Knopp's avatar
 
Raymond Knopp committed
2256 2257 2258

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

2261
  /*
2262 2263 2264 2265 2266 2267
    #ifdef LOWLATENCY
    struct sched_attr attr;
    unsigned int flags = 0;
    unsigned long mask = 1; // processor 0 
    #endif
  */
Raymond Knopp's avatar
 
Raymond Knopp committed
2268

ghaddab's avatar
ghaddab committed
2269
  printf("waiting for sync (UE_thread)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
2270 2271 2272
#ifdef RTAI
  rt_sem_wait(sync_sem);
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
2273 2274
  pthread_mutex_lock(&sync_mutex);
  printf("Locked sync_mutex, waiting (UE_thread)\n");
2275 2276
  while (sync_var<0)
    pthread_cond_wait(&sync_cond, &sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
2277 2278
  pthread_mutex_unlock(&sync_mutex);
  printf("unlocked sync_mutex, waiting (UE_thread)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
2279
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2280 2281

  printf("starting UE thread\n");
2282
  /*
2283 2284 2285 2286 2287
    #ifdef LOWLATENCY
    attr.size = sizeof(attr);
    attr.sched_flags = 0;
    attr.sched_nice = 0;
    attr.sched_priority = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2288
   
2289 2290 2291 2292 2293
    // This creates a .5 ms  reservation
    attr.sched_policy = SCHED_DEADLINE;
    attr.sched_runtime  = 0.5 * 1000000;
    attr.sched_deadline = 0.5 * 1000000;
    attr.sched_period   = 1   * 1000000;
Raymond Knopp's avatar
 
Raymond Knopp committed
2294
   
2295 2296 2297 2298
    // pin the UE main thread to CPU0
    // if (pthread_setaffinity_np(pthread_self(), sizeof(mask),&mask) <0) {
    //   perror("[MAIN_ENB_THREAD] pthread_setaffinity_np failed\n");
    //   }
Raymond Knopp's avatar
 
Raymond Knopp committed
2299
   
2300
    if (sched_setattr(0, &attr, flags) < 0 ){
Raymond Knopp's avatar
 
Raymond Knopp committed
2301 2302
    perror("[SCHED] main eNB thread: sched_setattr failed\n");
    exit_fun("Nothing to add");
2303
    } else {
Raymond Knopp's avatar
 
Raymond Knopp committed
2304
    LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %ld started on CPU %d\n",
2305 2306 2307 2308
    gettid(),sched_getcpu());
    }
    #endif
  */
Raymond Knopp's avatar
 
Raymond Knopp committed
2309
  mlockall(MCL_CURRENT | MCL_FUTURE);
Raymond Knopp's avatar
 
Raymond Knopp committed
2310 2311

  T0 = rt_get_time_ns();
Raymond Knopp's avatar
 
Raymond Knopp committed
2312 2313 2314
  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
2315

Raymond Knopp's avatar
 
Raymond Knopp committed
2316

Raymond Knopp's avatar
 
Raymond Knopp committed
2317
    while (rx_cnt < sf_bounds[hw_subframe]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2318
  
Raymond Knopp's avatar
 
Raymond Knopp committed
2319
      vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
2320 2321
  
#ifndef USRP_DEBUG
Raymond Knopp's avatar
 
Raymond Knopp committed
2322 2323 2324

      for (i=0;i<PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_rx;i++)
	rxp[i] = (dummy_dump==0) ? (void*)&rxdata[i][rx_cnt*samples_per_packets] : (void*)dummy[i];
Raymond Knopp's avatar
 
Raymond Knopp committed
2325 2326
      rxs = openair0.trx_read_func(&openair0,
				   &timestamp,
Raymond Knopp's avatar
 
Raymond Knopp committed
2327 2328 2329
				   rxp,
				   samples_per_packets - ((rx_cnt==0) ? rx_off_diff : 0),
				   PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
2330
      if (rxs != (samples_per_packets- ((rx_cnt==0) ? rx_off_diff : 0)))
Raymond Knopp's avatar
 
Raymond Knopp committed
2331
	oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
2332 2333

      rx_off_diff = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2334 2335 2336
      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
2337
      if (tx_enabled) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2338
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,1);
Raymond Knopp's avatar
 
Raymond Knopp committed
2339 2340
	for (i=0;i<PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_tx;i++)
	  txp[i] = (void*)&txdata[i][tx_cnt*samples_per_packets];
Raymond Knopp's avatar
 
Raymond Knopp committed
2341 2342
	openair0.trx_write_func(&openair0,
				(timestamp+samples_per_packets*tx_delay-tx_forward_nsamps),
Raymond Knopp's avatar
 
Raymond Knopp committed
2343
				txp,
Raymond Knopp's avatar
 
Raymond Knopp committed
2344
				samples_per_packets,
Raymond Knopp's avatar
 
Raymond Knopp committed
2345
				PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_tx,
Raymond Knopp's avatar
 
Raymond Knopp committed
2346
				1);
Raymond Knopp's avatar
 
Raymond Knopp committed
2347
				
Raymond Knopp's avatar
 
Raymond Knopp committed
2348 2349
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,0);
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2350 2351 2352
#else
      rt_sleep_ns(10000000);
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2353 2354 2355 2356 2357 2358 2359 2360
      rx_cnt++;
      tx_cnt++;
      
      if(tx_cnt == max_cnt)
	tx_cnt = 0;
    }
    
    if(rx_cnt == max_cnt)
Raymond Knopp's avatar
 
Raymond Knopp committed
2361 2362 2363
      rx_cnt = 0;


Raymond Knopp's avatar
 
Raymond Knopp committed
2364
    
Raymond Knopp's avatar
 
Raymond Knopp committed
2365
    if (is_synchronized==1)  {
Raymond Knopp's avatar
 
Raymond Knopp committed
2366 2367
      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
2368 2369 2370 2371 2372 2373 2374
      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
2375
 	  
Raymond Knopp's avatar
 
Raymond Knopp committed
2376 2377 2378 2379
	  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
2380
	    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
2381 2382 2383 2384 2385 2386 2387 2388 2389
	    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
2390
		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
2391 2392 2393 2394 2395 2396 2397 2398
		      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
2399 2400 2401
		      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
2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412
		      );
		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
2413 2414 2415
    }
    else {  // we are not yet synchronized
      
Raymond Knopp's avatar
 
Raymond Knopp committed
2416
      if ((hw_subframe == 9)&&(dummy_dump == 0)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2417
	// Wake up initial synch thread
Raymond Knopp's avatar
 
Raymond Knopp committed
2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437
	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
2438
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2439
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450
    /*
      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
2451 2452
      if (PHY_vars_UE_g[0][0]->instance_cnt_synch < 0) {
	if (is_synchronized == 1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2453
	  //	  openair0_set_gains(&openair0,&openair0_cfg[0]);
Raymond Knopp's avatar
 
Raymond Knopp committed
2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464
	  rx_off_diff = 0;
	  //	  LOG_D(PHY,"HW RESYNC: hw_frame %d: rx_offset = %d\n",frame,PHY_vars_UE_g[0][0]->rx_offset);
	  if ((PHY_vars_UE_g[0][0]->rx_offset > RX_OFF_MAX)&&(start_rx_stream==0)) {
	    start_rx_stream=1;
	    //LOG_D(PHY,"HW RESYNC: hw_frame %d: Resynchronizing sample stream\n");
	    frame=0;
	    // dump ahead in time to start of frame
#ifndef USRP_DEBUG
	    rxs = openair0.trx_read_func(&openair0,
					 &timestamp,
					 &rxdata[0],
Raymond Knopp's avatar
 
Raymond Knopp committed
2465 2466
					 PHY_vars_UE_g[0][0]->rx_offset,
					 PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484
#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
2485 2486 2487 2488 2489 2490 2491
    }
    
#if defined(ENABLE_ITTI)
    itti_update_lte_time(frame, slot);
#endif
  }
}
2492
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2493

Raymond Knopp's avatar
 
Raymond Knopp committed
2494 2495


2496
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
2497 2498
/* 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) {
2499
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2500 2501 2502
  RT_TASK *task;
#endif
  // RTIME in, out, diff;
Raymond Knopp's avatar
 
Raymond Knopp committed
2503
  int slot=0,frame=0,hw_slot,last_slot,next_slot;
Raymond Knopp's avatar
 
Raymond Knopp committed
2504 2505 2506 2507 2508 2509 2510
  // 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;
2511
  int CC_id,card;
Raymond Knopp's avatar
 
Raymond Knopp committed
2512 2513
  volatile unsigned int *DAQ_MBOX = openair0_daq_cnt();
#ifndef USRP
2514
  //exmimo_config_t *p_exmimo_config = openair0_exmimo_pci[card].exmimo_config_ptr;;
Raymond Knopp's avatar
 
Raymond Knopp committed
2515 2516
#endif

2517

2518
#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
Raymond Knopp's avatar
 
Raymond Knopp committed
2519 2520
  /* Wait for NAS UE to start cell selection */
  wait_system_ready ("Waiting for UE to be activated by UserProcess %s\r", &start_UE);
2521 2522
#endif

2523
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2524 2525
  task = rt_task_init_schmod(nam2num("TASK0"), 0, 0, 0, SCHED_FIFO, 0xF);
  LOG_D(HW,"Started UE thread (id %p)\n",task);
2526 2527 2528
#endif

#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
2529
  rt_make_hard_real_time();
2530 2531
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2532
  mlockall(MCL_CURRENT | MCL_FUTURE);
2533

Raymond Knopp's avatar
 
Raymond Knopp committed
2534 2535 2536 2537 2538 2539 2540 2541
  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;
    }
2542
    openair0_dump_config(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
2543 2544 2545
    }
  */
  while (!oai_exit)  {
Raymond Knopp's avatar
 
Raymond Knopp committed
2546

Raymond Knopp's avatar
 
Raymond Knopp committed
2547
    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
2548 2549

     
Raymond Knopp's avatar
 
Raymond Knopp committed
2550
    if (is_synchronized) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2551 2552


Raymond Knopp's avatar
 
Raymond Knopp committed
2553
      //this is the mbox counter that indicates the start of the frame
Raymond Knopp's avatar
 
Raymond Knopp committed
2554
      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
2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567
      //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;
2568
	
Raymond Knopp's avatar
 
Raymond Knopp committed
2569 2570
      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);
2571 2572 2573 2574 2575 2576 2577 2578
	if (frame>0){
	  if (exit_missed_slots==1)
	    exit_fun("[HW][UE] missed slot");
	  else{
	    num_missed_slots++;
	    LOG_W(HW,"[UE] just missed slot (total missed slots %ld)\n", num_missed_slots);
	  }
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
2579 2580 2581 2582
	slot++;
	if (slot==20) {
	  slot=0;
	  frame++;
Raymond Knopp's avatar
 
Raymond Knopp committed
2583
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607
	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);
2608
	  
Raymond Knopp's avatar
 
Raymond Knopp committed
2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633
	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;
2634 2635 2636 2637 2638 2639 2640 2641

    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
2642 2643
      
    if (is_synchronized)  {
2644
      phy_procedures_UE_lte (PHY_vars_UE_g[0][0], 0, 0, mode, 0, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
2645 2646 2647 2648 2649 2650
	
    }
    else {  // we are not yet synchronized
      hw_slot_offset = 0;
	
      slot = 0;
2651
      openair0_get_frame(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
2652 2653 2654 2655
      //          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
2656
      if (initial_sync(PHY_vars_UE_g[0][0],mode)==0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2657
	/*
Raymond Knopp's avatar
 
Raymond Knopp committed
2658 2659 2660 2661 2662
	  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
2663
	*/
Raymond Knopp's avatar
 
Raymond Knopp committed
2664 2665 2666 2667 2668 2669
	//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));
	*/
2670 2671
	
	/*if (mode == rx_calib_ue) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2672
	  exit_fun("[HW][UE] UE in RX calibration mode");
Raymond Knopp's avatar
 
Raymond Knopp committed
2673 2674 2675 2676 2677 2678 2679
	  }
	  else {*/
	is_synchronized = 1;
	//start the DMA transfers
	//LOG_D(HW,"Before openair0_start_rt_acquisition \n");
	for (card=0;card<openair0_num_detected_cards;card++)
	  openair0_start_rt_acquisition(card);
Raymond Knopp's avatar
 
Raymond Knopp committed
2680
	    
Raymond Knopp's avatar
 
Raymond Knopp committed
2681 2682 2683 2684
	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_D(HW,"Got synch: hw_slot_offset %d\n",hw_slot_offset);
	oai_exit=1;
	/*}*/
Raymond Knopp's avatar
 
Raymond Knopp committed
2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698
      }
      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
2699
	  //	  LOG_I(PHY,"[initial_sync] trying carrier off %d Hz\n",openair_daq_vars.freq_offset);
Raymond Knopp's avatar
 
Raymond Knopp committed
2700
#ifndef USRP
2701 2702 2703 2704 2705
	  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
2706
	  }
2707
	  openair0_config(&openair0_cfg[0],UE_flag);
2708
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2709 2710
	  rt_sleep_ns(FRAME_PERIOD);
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
2711
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
2712
    }
2713
    
Raymond Knopp's avatar
 
Raymond Knopp committed
2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727
    /*
      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);
2728 2729

#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
2730
  rt_make_soft_real_time();
2731 2732
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2733
  // clean task
2734
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
2735
  rt_task_delete(task);
2736
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2737 2738 2739
  LOG_D(HW,"Task deleted. returning\n");
  return 0;
}
2740

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

2743
#endif
2744

2745

Raymond Knopp's avatar
 
Raymond Knopp committed
2746 2747 2748 2749 2750
void init_UE_threads(void) {
  
  PHY_VARS_UE *UE=PHY_vars_UE_g[0][0];

  pthread_attr_init(&attr_UE_thread_tx);
Raymond Knopp's avatar
 
Raymond Knopp committed
2751
  pthread_attr_setstacksize(&attr_UE_thread_tx,PTHREAD_STACK_MIN);
Raymond Knopp's avatar
 
Raymond Knopp committed
2752 2753 2754 2755 2756
  sched_param_UE_thread_tx.sched_priority = sched_get_priority_max(SCHED_FIFO)-1;
  pthread_attr_setschedparam  (&attr_UE_thread_tx, &sched_param_UE_thread_tx);
  pthread_attr_setschedpolicy (&attr_UE_thread_tx, SCHED_FIFO);

  pthread_attr_init(&attr_UE_thread_rx);
Raymond Knopp's avatar
 
Raymond Knopp committed
2757
  pthread_attr_setstacksize(&attr_UE_thread_rx,PTHREAD_STACK_MIN);
Raymond Knopp's avatar
 
Raymond Knopp committed
2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775
  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;

2776
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787
  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
2788
}
Raymond Knopp's avatar
 
Raymond Knopp committed
2789

Raymond Knopp's avatar
 
Raymond Knopp committed
2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818


void fill_ue_band_info() {

  UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability;
  int i,j;

  bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count;
  
  for (i=0;i<bands_to_scan.nbands;i++) {

    for (j=0;j<sizeof (eutra_bands) / sizeof (eutra_bands[0]);j++)
      if (eutra_bands[j].band == UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA) {
	memcpy(&bands_to_scan.band_info[i],
	       &eutra_bands[j],
	       sizeof(eutra_band_t));
	
	printf("Band %d (%d) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n",
	       bands_to_scan.band_info[i].band,
	       UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA,
	       bands_to_scan.band_info[i].dl_min,
	       bands_to_scan.band_info[i].dl_max,
	       bands_to_scan.band_info[i].ul_min,
	       bands_to_scan.band_info[i].ul_max,
	       (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD");
	break;
      }
  }
}
Raymond Knopp's avatar
 
Raymond Knopp committed
2819

Raymond Knopp's avatar
 
Raymond Knopp committed
2820
static void get_options (int argc, char **argv) {
2821
  int c;
Raymond Knopp's avatar
 
Raymond Knopp committed
2822 2823
  //  char                          line[1000];
  //  int                           l;
2824
  int k;//i,j,k;
Raymond Knopp's avatar
 
Raymond Knopp committed
2825 2826 2827
#ifdef USRP
  int clock_src;
#endif
2828
  int CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
2829
#ifdef EXMIMO
2830 2831 2832
  char rxg_fname[256], line[1000];
  FILE *rxg_fd;
  int l;
Raymond Knopp's avatar
 
Raymond Knopp committed
2833 2834 2835 2836 2837
#endif


  size_t size; 
  FILE *f;
2838

Raymond Knopp's avatar
 
Raymond Knopp committed
2839 2840 2841 2842 2843 2844 2845 2846 2847
  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,
2848
    LONG_OPTION_NO_L2_CONNECT
Raymond Knopp's avatar
 
Raymond Knopp committed
2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859
  };
  
  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}};
  
Raymond Knopp's avatar
 
Raymond Knopp committed
2860
  while ((c = getopt_long (argc, argv, "C:dK:g:F:G:qO:m:SUVRM:r:P:s:t:x:",long_options,NULL)) != -1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892
    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
2893 2894 2895
#ifdef ETHERNET
      strcpy(rrh_eNB_ip,optarg);
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2896 2897
      break;
    case 'C':
2898
      for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
2899 2900 2901 2902 2903
	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]);
2904
      }
2905
      UE_scan=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2906 2907 2908 2909 2910
      break;
      
    case 'd':
#ifdef XFORMS
      do_forms=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
2911
      printf("Running with XFORMS!\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929
#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;
2930 2931 2932 2933 2934 2935 2936
    
    case 'm':
      target_dl_mcs = atoi (optarg);
      break;
    case 't':
      target_ul_mcs = atoi (optarg);
      break;
2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952
    case 'P':
      /* enable openair packet tracer (OPT)*/
      if ((strcmp(optarg, "wireshark") == 0) || 
	  (strcmp(optarg, "WIRESHARK") == 0)) {
	opt_type = OPT_WIRESHARK;
	printf("Enabling OPT for wireshark\n");
      } else if ((strcmp(optarg, "pcap") == 0) ||
		 (strcmp(optarg, "PCAP") == 0)){
	opt_type = OPT_PCAP;
	printf("Enabling OPT for pcap\n");
      } else {
	opt_type = OPT_NONE;
	printf("Unrecognized option for OPT module\n");
	printf("Possible values are either wireshark or pcap\n");
      }
      break;  
Raymond Knopp's avatar
 
Raymond Knopp committed
2953 2954 2955 2956
      
    case 'V':
      ouput_vcd = 1;
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
2957
    case  'q':
Raymond Knopp's avatar
 
Raymond Knopp committed
2958 2959 2960 2961 2962 2963
      opp_enabled = 1;
      break;
    case  'R' :
      online_log_messages =1;
      break;
    case 'r':
Raymond Knopp's avatar
 
Raymond Knopp committed
2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985
      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
2986
      }
2987
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
2988 2989
    case 's':
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
2990 2991 2992

      clock_src = atoi(optarg);
      if (clock_src == 0) {
2993
	//	char ref[128] = "internal";
Raymond Knopp's avatar
 
Raymond Knopp committed
2994 2995 2996
	//strncpy(uhd_ref, ref, strlen(ref)+1);
      }
      else if (clock_src == 1) {
2997
	//char ref[128] = "external";
Raymond Knopp's avatar
 
Raymond Knopp committed
2998 2999
	//strncpy(uhd_ref, ref, strlen(ref)+1);
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3000 3001 3002 3003
#else
      printf("Note: -s not defined for ExpressMIMO2\n");
#endif
      break;
3004 3005 3006 3007
    case 'S':
      exit_missed_slots=0;
      printf("Skip exit for missed slots\n");
      break;
3008
    case 'g':
Raymond Knopp's avatar
 
Raymond Knopp committed
3009
      glog_level=atoi(optarg); // value between 1 - 9
3010
      break;
3011 3012

    case 'F':
3013
#ifdef EXMIMO
3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030
      sprintf(rxg_fname,"%srxg.lime",optarg);
      rxg_fd = fopen(rxg_fname,"r");
      if (rxg_fd) {
	printf("Loading RX Gain parameters from %s\n",rxg_fname);
	l=0;
	while (fgets(line, sizeof(line), rxg_fd)) {
	  if ((strlen(line)==0) || (*line == '#')) continue; //ignore empty or comment lines
	  else {
	    if (l==0) sscanf(line,"%d %d %d %d",&rxg_max[0],&rxg_max[1],&rxg_max[2],&rxg_max[3]);
	    if (l==1) sscanf(line,"%d %d %d %d",&rxg_med[0],&rxg_med[1],&rxg_med[2],&rxg_med[3]);
	    if (l==2) sscanf(line,"%d %d %d %d",&rxg_byp[0],&rxg_byp[1],&rxg_byp[2],&rxg_byp[3]);
	    l++;
	  }
	}
      }
      else 
	printf("%s not found, running with defaults\n",rxg_fname);
3031
#endif
3032 3033
      break;
      
3034 3035 3036
    case 'G':
      glog_verbosity=atoi(optarg);// value from 0, 0x5, 0x15, 0x35, 0x75
      break;
3037 3038 3039 3040 3041 3042 3043
    case 'x':
      transmission_mode = atoi(optarg);
      if (transmission_mode > 2) {
	printf("Transmission mode > 2 (%d) not supported for the moment\n",transmission_mode);
	exit(-1);
      }
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
3044 3045
    default:
      break;
3046 3047
    }
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3048 3049
  
  if ((UE_flag == 0) && (conf_config_file_name != NULL)) {
3050
    int i,j;
Raymond Knopp's avatar
 
Raymond Knopp committed
3051 3052 3053 3054 3055 3056 3057 3058 3059
    
    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);
3060

Raymond Knopp's avatar
 
Raymond Knopp committed
3061
    /* Update some simulation parameters */
3062
    for (i=0; i < enb_properties->number; i++) {
3063 3064 3065 3066
      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
3067 3068 3069 3070 3071 3072
      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
3073
	//for (j=0; j < enb_properties->properties[i]->nb_cc; j++ ){
3074 3075
	frame_parms[CC_id]->Nid_cell            =  enb_properties->properties[i]->Nid_cell[CC_id];
	frame_parms[CC_id]->N_RB_DL             =  enb_properties->properties[i]->N_RB_DL[CC_id];
Raymond Knopp's avatar
 
Raymond Knopp committed
3076
	frame_parms[CC_id]->N_RB_UL             =  enb_properties->properties[i]->N_RB_DL[CC_id];
3077 3078 3079
	frame_parms[CC_id]->nb_antennas_tx      =  enb_properties->properties[i]->nb_antennas_tx[CC_id];
	frame_parms[CC_id]->nb_antennas_tx_eNB  =  enb_properties->properties[i]->nb_antennas_tx[CC_id];
	frame_parms[CC_id]->nb_antennas_rx      =  enb_properties->properties[i]->nb_antennas_rx[CC_id];
3080
	//} // j
Raymond Knopp's avatar
 
Raymond Knopp committed
3081 3082
      }

3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102
      
#ifdef OPENAIR2
      
      init_all_otg(0);
      g_otg->seed = 0;
      init_seeds(g_otg->seed);
      for (k=0; k<enb_properties->properties[i]->num_otg_elements; k++){
	j=enb_properties->properties[i]->otg_ue_id[k]; // ue_id
	g_otg->application_idx[i][j] = 1;
	//g_otg->packet_gen_type=SUBSTRACT_STRING;
	g_otg->background[i][j][0] =enb_properties->properties[i]->otg_bg_traffic[k];
	g_otg->application_type[i][j][0] =enb_properties->properties[i]->otg_app_type[k];// BCBR; //MCBR, BCBR
      
	printf("[OTG] configuring traffic type %d for  eNB %d UE %d (Background traffic is %s)\n",
	       g_otg->application_type[i][j][0], i, j,(g_otg->background[i][j][0]==1)?"Enabled":"Disabled");
      }
      init_predef_traffic(enb_properties->properties[i]->num_otg_elements, 1);
  
#endif
      
3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116
      glog_level                     = enb_properties->properties[i]->glog_level;
      glog_verbosity                 = enb_properties->properties[i]->glog_verbosity;
      hw_log_level                   = enb_properties->properties[i]->hw_log_level;
      hw_log_verbosity               = enb_properties->properties[i]->hw_log_verbosity ;
      phy_log_level                  = enb_properties->properties[i]->phy_log_level;
      phy_log_verbosity              = enb_properties->properties[i]->phy_log_verbosity;
      mac_log_level                  = enb_properties->properties[i]->mac_log_level;
      mac_log_verbosity              = enb_properties->properties[i]->mac_log_verbosity;
      rlc_log_level                  = enb_properties->properties[i]->rlc_log_level;
      rlc_log_verbosity              = enb_properties->properties[i]->rlc_log_verbosity;
      pdcp_log_level                 = enb_properties->properties[i]->pdcp_log_level;
      pdcp_log_verbosity             = enb_properties->properties[i]->pdcp_log_verbosity;
      rrc_log_level                  = enb_properties->properties[i]->rrc_log_level;
      rrc_log_verbosity              = enb_properties->properties[i]->rrc_log_verbosity;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
3117 3118 3119 3120 3121 3122
# if defined(ENABLE_USE_MME)
      gtpu_log_level                 = enb_properties->properties[i]->gtpu_log_level;
      gtpu_log_verbosity             = enb_properties->properties[i]->gtpu_log_verbosity;
      udp_log_level                  = enb_properties->properties[i]->udp_log_level;
      udp_log_verbosity              = enb_properties->properties[i]->udp_log_verbosity;
#endif
3123 3124 3125 3126
#if defined (ENABLE_SECURITY)
      osa_log_level                  = enb_properties->properties[i]->osa_log_level;
      osa_log_verbosity              = enb_properties->properties[i]->osa_log_verbosity;
#endif 
3127
    
Raymond Knopp's avatar
 
Raymond Knopp committed
3128
      // adjust the log
3129 3130
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
	for (k = 0 ; k < 4; k++) {
3131
	  downlink_frequency[CC_id][k]      =       enb_properties->properties[i]->downlink_frequency[CC_id];
3132
	  uplink_frequency_offset[CC_id][k] =  enb_properties->properties[i]->uplink_frequency_offset[CC_id];
3133 3134
	  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];
3135
	}
3136
	printf("Downlink frequency/ uplink offset of CC_id %d set to %ju/%d\n", CC_id,
3137 3138
	       enb_properties->properties[i]->downlink_frequency[CC_id],
	       enb_properties->properties[i]->uplink_frequency_offset[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
3139
      } // CC_id
3140
    }// i
Raymond Knopp's avatar
 
Raymond Knopp committed
3141
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3142 3143 3144 3145 3146 3147 3148
  else if ((UE_flag == 1) && (conf_config_file_name != NULL)) {

    // Here the configuration file is the XER encoded UE capabilities
    // Read it in and store in asn1c data structures
    strcpy(uecap_xer,conf_config_file_name);
    uecap_xer_in=1;
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3149
}
3150

Raymond Knopp's avatar
 
Raymond Knopp committed
3151
int main(int argc, char **argv) {
3152
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3153
  // RT_TASK *task;
Raymond Knopp's avatar
 
Raymond Knopp committed
3154
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3155
  int *eNB_thread_status_p;
Raymond Knopp's avatar
 
Raymond Knopp committed
3156
  //  int *eNB_thread_status_rx[10],*eNB_thread_status_tx[10];
3157
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3158
  int i,aa,card;
3159
#if defined (XFORMS) || defined (EMOS) || defined(EXMIMO)
Raymond Knopp's avatar
 
Raymond Knopp committed
3160
  void *status;
3161
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3162
  
Raymond Knopp's avatar
 
Raymond Knopp committed
3163
  int CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
3164
  uint16_t Nid_cell = 0;
3165
  uint8_t  cooperation_flag=0,  abstraction_flag=0;
3166
#ifndef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3167
  uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
3168 3169 3170
#endif

#ifdef ENABLE_TCXO
Raymond Knopp's avatar
 
Raymond Knopp committed
3171
  unsigned int tcxo = 114;
3172 3173
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3174
#if defined (XFORMS)
3175 3176
  int ret;
#endif
3177
#if defined (EMOS) || (! defined (RTAI))
Raymond Knopp's avatar
 
Raymond Knopp committed
3178
  int error_code;
3179
#endif
3180 3181

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

Raymond Knopp's avatar
 
Raymond Knopp committed
3183
  set_latency_target();
3184

Raymond Knopp's avatar
 
Raymond Knopp committed
3185
  mode = normal_txrx;
3186

Raymond Knopp's avatar
 
Raymond Knopp committed
3187 3188 3189
  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
3190
    frame_parms[CC_id]->frame_type         = FDD; /* TDD */
Raymond Knopp's avatar
 
Raymond Knopp committed
3191 3192 3193 3194
    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
3195
    frame_parms[CC_id]->Ncp                 = NORMAL;
Raymond Knopp's avatar
 
Raymond Knopp committed
3196 3197
    frame_parms[CC_id]->Ncp_UL              = NORMAL;
    frame_parms[CC_id]->Nid_cell            = Nid_cell;
Raymond Knopp's avatar
 
Raymond Knopp committed
3198
    frame_parms[CC_id]->num_MBSFN_config    = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3199
  }
3200

3201 3202 3203
  // initialize the log (see log.h for details)
  logInit();
  set_glog(glog_level, glog_verbosity);
winckel's avatar
winckel committed
3204

Raymond Knopp's avatar
 
Raymond Knopp committed
3205 3206
  //randominit (0);
  set_taus_seed (0);
winckel's avatar
winckel committed
3207

3208 3209
  get_options (argc, argv); //Command-line options
  
Raymond Knopp's avatar
 
Raymond Knopp committed
3210 3211 3212 3213

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

3215
      set_comp_log(HW,      LOG_DEBUG,  LOG_HIGH, 1);
3216
#ifdef OPENAIR2
3217
      set_comp_log(PHY,     LOG_DEBUG,   LOG_HIGH, 1);
3218
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3219
      set_comp_log(PHY,     LOG_INFO,   LOG_HIGH, 1);
3220
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3221 3222 3223 3224 3225
      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);
3226
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
3227
      set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
3228
# if defined(ENABLE_USE_MME)
Raymond Knopp's avatar
 
Raymond Knopp committed
3229
      set_comp_log(NAS,     LOG_INFO,   LOG_HIGH, 1);
3230 3231
# endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3232 3233 3234 3235
    }
  else
    {
      printf("configuring for eNB\n");
3236

3237
      set_comp_log(HW,      hw_log_level, hw_log_verbosity, 1);
3238
#ifdef OPENAIR2
3239
      set_comp_log(PHY,     phy_log_level,   phy_log_verbosity, 1);
3240
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3241
      set_comp_log(PHY,     LOG_INFO,   LOG_HIGH, 1);
3242
#endif
3243 3244 3245 3246
      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);
3247
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
3248
      set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
3249
# if defined(ENABLE_USE_MME)
Lionel Gauthier's avatar
 
Lionel Gauthier committed
3250 3251
      set_comp_log(UDP_,    udp_log_level,   udp_log_verbosity, 1);
      set_comp_log(GTPU,    gtpu_log_level,   gtpu_log_verbosity, 1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3252 3253
      set_comp_log(S1AP,    LOG_DEBUG,   LOG_HIGH, 1);
      set_comp_log(SCTP,    LOG_INFO,   LOG_HIGH, 1);
3254
# endif
3255
#if defined(ENABLE_SECURITY)
3256
      set_comp_log(OSA,    osa_log_level,   osa_log_verbosity, 1);
3257
#endif
3258
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3259
      set_comp_log(ENB_APP, LOG_INFO, LOG_HIGH, 1);
3260
      set_comp_log(OTG,     LOG_INFO,   LOG_HIGH, 1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3261 3262 3263
      if (online_log_messages == 1) { 
	set_component_filelog(RRC);
	set_component_filelog(PDCP);
Raymond Knopp's avatar
 
Raymond Knopp committed
3264 3265
      }
    }
3266

Raymond Knopp's avatar
 
Raymond Knopp committed
3267 3268 3269 3270 3271 3272
  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");
  }
3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286
  
  if (opp_enabled ==1)
    reset_opp_meas();

  if (opt_type != OPT_NONE) {
    radio_type_t radio_type;
    if (frame_parms[0]->frame_type == FDD)
      radio_type = RADIO_TYPE_FDD;
    else 
      radio_type = RADIO_TYPE_TDD;
    if (init_opt(NULL, NULL, NULL, radio_type) == -1)
      LOG_E(OPT,"failed to run OPT \n");
  }
  
3287
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
3288 3289 3290 3291 3292 3293
  if (UE_flag == 1) {
    log_set_instance_type (LOG_INSTANCE_UE);
  }
  else {
    log_set_instance_type (LOG_INSTANCE_ENB);
  }
3294

Raymond Knopp's avatar
 
Raymond Knopp committed
3295
  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
3296 3297
#endif

3298
#ifdef NAS_NETLINK
Raymond Knopp's avatar
 
Raymond Knopp committed
3299
  netlink_init();
3300 3301
#endif

3302
#if !defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
3303 3304 3305
  // to make a graceful exit when ctrl-c is pressed
  signal(SIGSEGV, signal_handler);
  signal(SIGINT, signal_handler);
3306
#endif
3307 3308

#ifndef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3309 3310 3311 3312
  check_clock();
#endif

  // init the parameters
Raymond Knopp's avatar
 
Raymond Knopp committed
3313 3314 3315 3316
  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    frame_parms[CC_id]->nushift            = 0;
    if (UE_flag==0)
      {
3317

Raymond Knopp's avatar
 
Raymond Knopp committed
3318
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3319 3320 3321 3322
    else
      { //UE_flag==1
	frame_parms[CC_id]->nb_antennas_tx     = 1;
	frame_parms[CC_id]->nb_antennas_rx     = 1;
3323
	frame_parms[CC_id]->nb_antennas_tx_eNB = (transmission_mode == 1) ? 1 : 2; //initial value overwritten by initial sync later
Raymond Knopp's avatar
 
Raymond Knopp committed
3324 3325 3326 3327 3328 3329 3330 3331 3332
      }
    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;
3333 3334
    init_ul_hopping(frame_parms[CC_id]);
    init_frame_parms(frame_parms[CC_id],1);
3335
    phy_init_top(frame_parms[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347
  }

  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
3348
    // N_ZC = (prach_fmt <4)?839:139;
Raymond Knopp's avatar
 
Raymond Knopp committed
3349
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3350 3351

  if (UE_flag==1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3352 3353 3354
    NB_UE_INST=1;
    NB_INST=1;

Raymond Knopp's avatar
 
Raymond Knopp committed
3355 3356 3357
    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++) {
3358
      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
3359
      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
3360 3361
#ifndef OPENAIR2
      for (i=0;i<NUMBER_OF_eNB_MAX;i++) {
3362 3363 3364
	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
3365
	
3366 3367 3368
	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
3369
      }
3370
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3371
      
3372 3373 3374
      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
3375
      
3376
      PHY_vars_UE_g[0][CC_id]->lte_ue_pdcch_vars[0]->crnti = 0x1234;
3377
#ifndef OPENAIR2
3378
      PHY_vars_UE_g[0][CC_id]->lte_ue_pdcch_vars[0]->crnti = 0x1235;
3379
#endif
3380
    
3381
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3382 3383 3384 3385 3386
      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];
      }
3387

Raymond Knopp's avatar
 
Raymond Knopp committed
3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402
      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;
      }
3403
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3404
      PHY_vars_UE_g[0][CC_id]->rx_total_gain_dB =  (int)rx_gain[CC_id][0]; 
3405
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3406
    
Raymond Knopp's avatar
 
Raymond Knopp committed
3407
      PHY_vars_UE_g[0][CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
Raymond Knopp's avatar
 
Raymond Knopp committed
3408
    
3409

3410
   
3411
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423
      //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;
      }
3424
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3425 3426
      //already taken care of in lte-softmodem
      PHY_vars_UE_g[UE_id][CC_id]->N_TA_offset = 0;
3427
#endif 
Raymond Knopp's avatar
 
Raymond Knopp committed
3428
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3429 3430 3431 3432 3433
    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;
    
3434
  
Raymond Knopp's avatar
 
Raymond Knopp committed
3435 3436 3437 3438 3439
    
    //  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
3440 3441 3442
      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
3443
	PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],eNB_id,Nid_cell,cooperation_flag,transmission_mode,abstraction_flag);
3444
	PHY_vars_eNB_g[0][CC_id]->CC_id = CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
3445
       
3446
#ifndef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3447 3448 3449 3450 3451 3452 3453 3454 3455
	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
3456
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3457 3458 3459 3460
      
	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
3461

3462
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3463

3464
	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
3465

3466
#else
3467
	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
3468 3469 3470

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

3471 3472
	// set eNB to max gain
	for (i=0;i<4;i++)
3473 3474
	  rx_gain_mode[CC_id][i] = max_gain;
#endif
3475

3476
#ifdef EXMIMO
3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493
	//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
3494
      }
3495 3496


Raymond Knopp's avatar
 
Raymond Knopp committed
3497 3498
      NB_eNB_INST=1;
      NB_INST=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
3499

Raymond Knopp's avatar
 
Raymond Knopp committed
3500
      openair_daq_vars.ue_dl_rb_alloc=0x1fff;
3501
      openair_daq_vars.target_ue_dl_mcs=target_dl_mcs;
Raymond Knopp's avatar
 
Raymond Knopp committed
3502
      openair_daq_vars.ue_ul_nb_rb=6;
3503
      openair_daq_vars.target_ue_ul_mcs=target_ul_mcs;
Raymond Knopp's avatar
 
Raymond Knopp committed
3504 3505

    }
3506

3507

3508

Raymond Knopp's avatar
 
Raymond Knopp committed
3509
  dump_frame_parms(frame_parms[0]);
3510

Raymond Knopp's avatar
 
Raymond Knopp committed
3511
  if(frame_parms[0]->N_RB_DL == 100) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3512
    sample_rate = 30.72e6;
3513
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3514 3515 3516 3517 3518
    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
3519
    sf_bounds_tx = sf_bounds_20_tx;
Raymond Knopp's avatar
 
Raymond Knopp committed
3520
    max_cnt = 150;
3521
    tx_delay = 8;
Raymond Knopp's avatar
 
Raymond Knopp committed
3522 3523
#endif
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3524
  else if(frame_parms[0]->N_RB_DL == 50){
3525
    sample_rate = 15.36e6;
3526
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3527 3528 3529 3530
    samples_per_packets = 2048;
    samples_per_frame = 153600;
    tx_forward_nsamps = 95;
    sf_bounds = sf_bounds_10;
Raymond Knopp's avatar
 
Raymond Knopp committed
3531
    sf_bounds_tx = sf_bounds_10_tx;
Raymond Knopp's avatar
 
Raymond Knopp committed
3532 3533 3534 3535
    max_cnt = 75;
    tx_delay = 4;
#endif
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3536
  else if (frame_parms[0]->N_RB_DL == 25) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3537
    sample_rate = 7.68e6;
3538
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3539 3540 3541 3542
    samples_per_packets = 1024;
    samples_per_frame = 76800;
    tx_forward_nsamps = 70;
    sf_bounds = sf_bounds_5;
Raymond Knopp's avatar
 
Raymond Knopp committed
3543
    sf_bounds_tx = sf_bounds_5_tx;
Raymond Knopp's avatar
 
Raymond Knopp committed
3544
    max_cnt = 75;
Raymond Knopp's avatar
 
Raymond Knopp committed
3545
    tx_delay = 5;
Raymond Knopp's avatar
 
Raymond Knopp committed
3546 3547
#endif
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559
  else if (frame_parms[0]->N_RB_DL == 6) {
    sample_rate = 1.92e6;
#ifndef EXMIMO
    samples_per_packets = 256;
    samples_per_frame = 19200;
    tx_forward_nsamps = 40;
    sf_bounds = sf_bounds_1_5;
    sf_bounds_tx = sf_bounds_1_5_tx;
    max_cnt = 75;
    tx_delay = 5;
#endif
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3560 3561 3562 3563 3564 3565 3566 3567 3568

#ifdef ETHERNET
  if (frame_parms[0]->N_RB_DL == 6) samples_per_packets = 256;
  else samples_per_packets = 1536;

  max_cnt = sf_bounds[9]; 
  printf("HW: samples_per_packets %d, max_cnt %d\n",samples_per_packets,max_cnt);
#endif

3569

3570
  for (card=0;card<MAX_CARDS;card++) {
3571
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3572
    openair0_cfg[card].samples_per_packet = samples_per_packets;
3573 3574 3575 3576
#endif
    printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card,
	   ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_tx),
	   ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_rx)); 
Raymond Knopp's avatar
 
Raymond Knopp committed
3577 3578
    openair0_cfg[card].Mod_id = 0;
#ifdef ETHERNET
ghaddab's avatar
ghaddab committed
3579
    if (UE_flag){
Raymond Knopp's avatar
 
Raymond Knopp committed
3580 3581 3582
      printf("ETHERNET: Configuring UE ETH for %s:%d\n",rrh_UE_ip,rrh_UE_port);
      openair0_cfg[card].rrh_ip   = &rrh_UE_ip[0];
      openair0_cfg[card].rrh_port = rrh_UE_port;
ghaddab's avatar
ghaddab committed
3583 3584
    }
    else
Raymond Knopp's avatar
 
Raymond Knopp committed
3585 3586 3587 3588 3589
      {
	printf("ETHERNET: Configuring eNB ETH for %s:%d\n",rrh_eNB_ip,rrh_eNB_port);
	openair0_cfg[card].rrh_ip   = &rrh_eNB_ip[0];
	openair0_cfg[card].rrh_port = rrh_eNB_port;
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3590
#endif
3591 3592 3593
    openair0_cfg[card].sample_rate = sample_rate;
    openair0_cfg[card].tx_bw = bw;
    openair0_cfg[card].rx_bw = bw;
3594 3595 3596
    // 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
3597
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3598 3599
    openair0_cfg[card].tx_num_channels=min(2,((UE_flag==0) ? PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_tx));
    openair0_cfg[card].rx_num_channels=min(2,((UE_flag==0) ? PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_rx));
3600
    for (i=0;i<4;i++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3601

3602
      openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
Raymond Knopp's avatar
 
Raymond Knopp committed
3603
      openair0_cfg[card].rx_gain[i] = ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->rx_total_gain_eNB_dB : 
3604
                                       PHY_vars_UE_g[0][0]->rx_total_gain_dB) - USRP_GAIN_OFFSET;  // calibrated for USRP B210 @ 2.6 GHz
3605 3606
      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
3607 3608 3609 3610 3611 3612
      printf("Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n",
	     openair0_cfg[card].tx_gain[i],
	     openair0_cfg[card].rx_gain[i],
	     openair0_cfg[card].tx_freq[i],
	     openair0_cfg[card].rx_freq[i]);
      
Raymond Knopp's avatar
 
Raymond Knopp committed
3613
    }
3614
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3615
  }
3616 3617

  if (openair0_device_init(&openair0, &openair0_cfg[0]) <0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3618 3619 3620
    printf("Exiting, cannot initialize device\n");
    exit(-1);
  }
3621 3622 3623

  mac_xface = malloc(sizeof(MAC_xface));

3624
#ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3625
  int eMBMS_active=0;
3626

Raymond Knopp's avatar
 
Raymond Knopp committed
3627
  l2_init(frame_parms[0],eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL,
Raymond Knopp's avatar
 
Raymond Knopp committed
3628 3629 3630 3631 3632 3633
	  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);
3634 3635
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3636
  mac_xface->macphy_exit = &exit_fun;
3637

winckel's avatar
winckel committed
3638
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
3639
  if (create_tasks(UE_flag ? 0 : 1, UE_flag ? 1 : 0) < 0) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
3640
    printf("cannot create ITTI tasks\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
3641 3642 3643
    exit(-1); // need a softer mode
  }
  printf("ITTI tasks created\n");
winckel's avatar
winckel committed
3644 3645
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3646 3647 3648
  if (UE_flag==1)
    fill_ue_band_info();

3649
  /* #ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3650 3651 3652 3653 3654 3655
  //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++){
Raymond Knopp's avatar
 
Raymond Knopp committed
3656 3657 3658 3659 3660 3661
  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
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3662 3663 3664
  }
  init_predef_traffic(UE_flag ? 1 : 0, UE_flag ? 0 : 1);
  //  }
3665
  #endif */
Raymond Knopp's avatar
 
Raymond Knopp committed
3666

3667
#ifdef EXMIMO
3668
  number_of_cards = openair0_num_detected_cards;
3669 3670 3671
#else
  number_of_cards = 1;
#endif 
3672

Raymond Knopp's avatar
 
Raymond Knopp committed
3673
  openair_daq_vars.timing_advance = 0;
3674

Florian Kaltenberger's avatar
Florian Kaltenberger committed
3675 3676
  for(CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    rf_map[CC_id].card=0;
ouni's avatar
ouni committed
3677
    rf_map[CC_id].chain=CC_id;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
3678
  }
3679

Raymond Knopp's avatar
 
Raymond Knopp committed
3680 3681
  // connect the TX/RX buffers
  if (UE_flag==1) {
3682 3683 3684 3685
    if (setup_ue_buffers(PHY_vars_UE_g[0],&openair0_cfg[0],rf_map)!=0) {
      printf("Error setting up eNB buffer\n");
      exit(-1);
    }
3686 3687
    printf("Setting UE buffer to all-RX\n");
    // Set LSBs for antenna switch (ExpressMIMO)
Raymond Knopp's avatar
 
Raymond Knopp committed
3688
    for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3689
      for (i=0; i<frame_parms[CC_id]->samples_per_tti*10; i++)
3690
	for (aa=0; aa<frame_parms[CC_id]->nb_antennas_tx; aa++)
3691
	  PHY_vars_UE_g[0][CC_id]->lte_ue_common_vars.txdata[aa][i] = 0x00010001;
Raymond Knopp's avatar
 
Raymond Knopp committed
3692
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3693 3694 3695
    //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX;
  }
  else {
3696 3697 3698 3699 3700 3701
    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
3702
    for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3703 3704
      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++)
3705
	  PHY_vars_eNB_g[0][CC_id]->lte_eNB_common_vars.txdata[0][aa][i] = 0x00010001;
Raymond Knopp's avatar
 
Raymond Knopp committed
3706
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3707
  }
3708
#ifdef EXMIMO
3709
  openair0_config(&openair0_cfg[0],UE_flag);
Raymond Knopp's avatar
 
Raymond Knopp committed
3710 3711
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3712
  /*  
Raymond Knopp's avatar
 
Raymond Knopp committed
3713 3714
      for (ant=0;ant<4;ant++)
      p_exmimo_config->rf.do_autocal[ant] = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3715
  */
3716 3717

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3718 3719 3720 3721 3722 3723 3724 3725 3726
  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);
3727 3728
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3729
  mlockall(MCL_CURRENT | MCL_FUTURE);
3730 3731

#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752
  // 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);
3753

Raymond Knopp's avatar
 
Raymond Knopp committed
3754 3755 3756
  sync_sem = rt_typed_sem_init(nam2num("syncsem"), 0, BIN_SEM|FIFO_Q);
  if(sync_sem == 0)
    printf("error init sync semphore\n");
3757

Raymond Knopp's avatar
 
Raymond Knopp committed
3758 3759 3760
#else
  pthread_cond_init(&sync_cond,NULL);
  pthread_mutex_init(&sync_mutex, NULL);
3761 3762
#endif

3763
#if defined(ENABLE_ITTI)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
3764 3765 3766 3767 3768
  // 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);
  }
3769
#endif
3770

Raymond Knopp's avatar
 
Raymond Knopp committed
3771 3772

  // this starts the DMA transfers
3773
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3774
  if (UE_flag!=1)
3775 3776
    for (card=0;card<openair0_num_detected_cards;card++)
      openair0_start_rt_acquisition(card);
Raymond Knopp's avatar
 
Raymond Knopp committed
3777
#endif
3778 3779

#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
3780 3781
  if (do_forms==1) {
    fl_initialize (&argc, argv, NULL, 0, 0);
3782 3783

    if (UE_flag==0) {
3784
      form_stats_l2 = create_form_stats_form();
3785 3786 3787
      fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats");
      form_stats = create_form_stats_form();
      fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
Raymond Knopp's avatar
 
Raymond Knopp committed
3788 3789 3790 3791 3792 3793 3794
      for(UE_id=0;UE_id<scope_enb_num_ue;UE_id++) {
	form_enb[UE_id] = create_lte_phy_scope_enb();
	sprintf (title, "UE%d LTE UL SCOPE eNB",UE_id+1);
	fl_show_form (form_enb[UE_id]->lte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
	if (otg_enabled) {
	  fl_set_button(form_enb[UE_id]->button_0,1);
	  fl_set_object_label(form_enb[UE_id]->button_0,"DL Traffic ON");
Raymond Knopp's avatar
 
Raymond Knopp committed
3795 3796
	}
	else {
Raymond Knopp's avatar
 
Raymond Knopp committed
3797 3798
	  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
3799
	}
3800 3801
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3802
    else {
3803 3804 3805 3806 3807 3808 3809
      form_stats = create_form_stats_form();
      fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
      UE_id = 0;
      form_ue[UE_id] = create_lte_phy_scope_ue();
      sprintf (title, "LTE DL SCOPE UE");
      fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);

Raymond Knopp's avatar
 
Raymond Knopp committed
3810 3811 3812 3813 3814 3815 3816 3817 3818 3819
      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
3820
    ret = pthread_create(&forms_thread, NULL, scope_thread, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
3821 3822
    printf("Scope thread created, ret=%d\n",ret);
  }
3823 3824 3825
#endif

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
3826 3827
  ret = pthread_create(&thread3, NULL, emos_thread, NULL);
  printf("EMOS thread created, ret=%d\n",ret);
3828 3829
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3830
  rt_sleep_ns(10*FRAME_PERIOD);
3831 3832

#ifndef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3833
  pthread_attr_init (&attr_dlsch_threads);
Raymond Knopp's avatar
 
Raymond Knopp committed
3834
  pthread_attr_setstacksize(&attr_dlsch_threads,PTHREAD_STACK_MIN);
3835

3836 3837 3838
  pthread_attr_init (&attr_UE_thread);
  pthread_attr_setstacksize(&attr_UE_thread,4*PTHREAD_STACK_MIN);

3839
#ifndef LOWLATENCY
3840
  sched_param_dlsch.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY;
Raymond Knopp's avatar
 
Raymond Knopp committed
3841 3842
  pthread_attr_setschedparam  (&attr_dlsch_threads, &sched_param_dlsch);
  pthread_attr_setschedpolicy (&attr_dlsch_threads, SCHED_FIFO);
3843
#endif 
Raymond Knopp's avatar
 
Raymond Knopp committed
3844
  pthread_attr_init (&attr_UE_init_synch);
Raymond Knopp's avatar
 
Raymond Knopp committed
3845
  pthread_attr_setstacksize(&attr_UE_init_synch,PTHREAD_STACK_MIN);
3846
  sched_param_UE_init_synch.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY;
Raymond Knopp's avatar
 
Raymond Knopp committed
3847 3848 3849
  pthread_attr_setschedparam  (&attr_UE_init_synch, &sched_param_UE_init_synch);
  pthread_attr_setschedpolicy (&attr_UE_init_synch, SCHED_FIFO);

3850 3851
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3852 3853
  // start the main thread
  if (UE_flag == 1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3854
    init_UE_threads();
3855
    sleep(1);
3856
#ifdef RTAI
3857
    main_ue_thread = rt_thread_create(UE_thread, NULL, 100000000);
3858
#else
3859
    error_code = pthread_create(&main_ue_thread, &attr_UE_thread, UE_thread, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
3860 3861 3862 3863 3864 3865 3866
    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");
    }
3867 3868
#endif
#ifdef DLSCH_THREAD
Raymond Knopp's avatar
 
Raymond Knopp committed
3869 3870 3871
    init_rx_pdsch_thread();
    rt_sleep_ns(FRAME_PERIOD/10);
    init_dlsch_threads();
3872
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3873 3874 3875
    printf("UE threads created\n");
  }
  else {
3876

Raymond Knopp's avatar
 
Raymond Knopp committed
3877 3878
    if (multi_thread>0) {
      init_eNB_proc();
3879
      sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3880 3881
      LOG_D(HW,"[lte-softmodem.c] eNB threads created\n");
    }
3882
    printf("Creating main eNB_thread \n");
Raymond Knopp's avatar
 
Raymond Knopp committed
3883
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3884
    main_eNB_thread = rt_thread_create(eNB_thread, NULL, PTHREAD_STACK_MIN);
Raymond Knopp's avatar
 
Raymond Knopp committed
3885
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3886
    error_code = pthread_create(&main_eNB_thread, &attr_dlsch_threads, eNB_thread, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
3887 3888 3889 3890 3891 3892
    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
3893
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3894 3895
#endif
  }
3896

Raymond Knopp's avatar
 
Raymond Knopp committed
3897
  // Sleep to allow all threads to setup
Raymond Knopp's avatar
 
Raymond Knopp committed
3898
  sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3899

3900
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3901
#ifndef USRP_DEBUG
Raymond Knopp's avatar
 
Raymond Knopp committed
3902
  openair0.trx_start_func(&openair0);
Raymond Knopp's avatar
 
Raymond Knopp committed
3903
  //  printf("returning from usrp start streaming: %llu\n",get_usrp_time(&openair0));
Raymond Knopp's avatar
 
Raymond Knopp committed
3904
#endif
3905 3906
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3907 3908 3909
#ifdef RTAI
  rt_sem_signal(sync_sem);
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3910 3911
  pthread_mutex_lock(&sync_mutex);
  printf("Sending sync ...\n");
3912
  sync_var=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3913 3914
  pthread_cond_broadcast(&sync_cond);
  pthread_mutex_unlock(&sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
3915
#endif
3916

Raymond Knopp's avatar
 
Raymond Knopp committed
3917 3918 3919
  // wait for end of program
  printf("TYPE <CTRL-C> TO TERMINATE\n");
  //getchar();
3920 3921

#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
3922 3923
  printf("Entering ITTI signals handler\n");
  itti_wait_tasks_end();
3924
  oai_exit=1;
3925
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3926 3927
  while (oai_exit==0)
    rt_sleep_ns(FRAME_PERIOD);
3928
#endif
3929

Raymond Knopp's avatar
 
Raymond Knopp committed
3930
  // stop threads
3931
#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
3932 3933 3934
  printf("waiting for XFORMS thread\n");
  if (do_forms==1)
    {
Raymond Knopp's avatar
 
Raymond Knopp committed
3935
      pthread_join(forms_thread,&status);
Raymond Knopp's avatar
 
Raymond Knopp committed
3936 3937 3938 3939 3940 3941
      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 {
3942 3943
	fl_hide_form(form_stats_l2->stats_form);
	fl_free_form(form_stats_l2->stats_form);
Raymond Knopp's avatar
 
Raymond Knopp committed
3944 3945 3946 3947
	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
3948
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3949
    }
3950 3951
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
3952 3953 3954
  printf("stopping MODEM threads\n");
  // cleanup
  if (UE_flag == 1) {
3955
#ifdef EXMIMO
3956
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3957
    rt_thread_join(main_ue_thread); 
3958
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3959
    pthread_join(main_ue_thread,&status); 
3960 3961
#endif
#ifdef DLSCH_THREAD
Raymond Knopp's avatar
 
Raymond Knopp committed
3962 3963
    cleanup_dlsch_threads();
    cleanup_rx_pdsch_thread();
3964
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3965 3966 3967
#endif
  }
  else {
Raymond Knopp's avatar
 
Raymond Knopp committed
3968
#ifdef DEBUG_THREADS
Raymond Knopp's avatar
 
Raymond Knopp committed
3969
    printf("Joining eNB_thread ...");
Raymond Knopp's avatar
 
Raymond Knopp committed
3970
#endif
3971 3972 3973
#ifdef RTAI
    rt_thread_join(main_eNB_thread); 
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
3974
    pthread_join(main_eNB_thread,(void**)&eNB_thread_status_p); 
Raymond Knopp's avatar
 
Raymond Knopp committed
3975
#ifdef DEBUG_THREADS
Raymond Knopp's avatar
 
Raymond Knopp committed
3976
    printf("status %d\n",*eNB_thread_status_p);
Raymond Knopp's avatar
 
Raymond Knopp committed
3977
#endif
3978
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3979

Raymond Knopp's avatar
 
Raymond Knopp committed
3980 3981 3982
    if (multi_thread>0) {
      printf("Killing eNB processing threads\n");
      kill_eNB_proc();
Raymond Knopp's avatar
 
Raymond Knopp committed
3983

Raymond Knopp's avatar
 
Raymond Knopp committed
3984
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3985
  }
3986

3987
#ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3988
  //cleanup_pdcp_thread();
3989 3990
#endif

3991
#ifdef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3992
  rt_sem_delete(sync_sem);
Raymond Knopp's avatar
 
Raymond Knopp committed
3993
  stop_rt_timer();
Raymond Knopp's avatar
 
Raymond Knopp committed
3994 3995 3996
#else
  pthread_cond_destroy(&sync_cond);
  pthread_mutex_destroy(&sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
3997
#endif
3998

3999
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
4000
  printf("stopping card\n");
4001
  openair0_stop(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
4002 4003
  printf("closing openair0_lib\n");
  openair0_close();
Raymond Knopp's avatar
 
Raymond Knopp committed
4004
#endif
4005 4006

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
4007 4008 4009
  printf("waiting for EMOS thread\n");
  pthread_cancel(thread3);
  pthread_join(thread3,&status);
4010 4011 4012
#endif

#ifdef EMOS
Raymond Knopp's avatar
 
Raymond Knopp committed
4013 4014
  error_code = rtf_destroy(CHANSOUNDER_FIFO_MINOR);
  printf("[OPENAIR][SCHED][CLEANUP] EMOS FIFO closed, error_code %d\n", error_code);
4015 4016
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
4017 4018
  if (ouput_vcd)
    vcd_signal_dumper_close();
4019

4020 4021 4022
  if (opt_type != OPT_NONE)
    terminate_opt();

Raymond Knopp's avatar
 
Raymond Knopp committed
4023
  logClean();
4024

Raymond Knopp's avatar
 
Raymond Knopp committed
4025 4026
  return 0;
}
4027

4028 4029
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
4030

4031
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
4032 4033 4034
  uint16_t N_TA_offset = 0;
#endif

4035 4036 4037 4038 4039
  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
4040
    }
4041 4042 4043
    else {
      printf("phy_vars_eNB[%d] not initialized\n", CC_id);
      return(-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
4044
    }
4045

Raymond Knopp's avatar
 
Raymond Knopp committed
4046

4047
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
4048 4049 4050 4051 4052 4053
    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
4054
	N_TA_offset = 624/4;
Raymond Knopp's avatar
 
Raymond Knopp committed
4055 4056 4057
    }
#endif
   
4058
#ifdef EXMIMO
4059 4060 4061 4062 4063
    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++) {
4064
      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);
4065 4066 4067 4068 4069 4070 4071 4072
      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];
4073 4074
	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];
4075 4076
	openair0_cfg[rf_map[CC_id].card].rx_num_channels++;
      }
4077

4078
      printf("rxdata[%d] @ %p\n",i,phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i]);
Raymond Knopp's avatar
 
Raymond Knopp committed
4079
    }
4080
    for (i=0;i<frame_parms->nb_antennas_tx;i++) {
4081
      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);
4082 4083 4084 4085 4086 4087 4088 4089
      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];
4090
	openair0_cfg[rf_map[CC_id].card].tx_gain[rf_map[CC_id].chain+i] = tx_gain[CC_id][i];
4091 4092
	openair0_cfg[rf_map[CC_id].card].tx_num_channels++;
      }
4093

4094
      printf("txdata[%d] @ %p\n",i,phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i]);
4095
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
4096
  
Raymond Knopp's avatar
 
Raymond Knopp committed
4097
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
4098
    // replace RX signal buffers with mmaped HW versions
4099 4100
    rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*));
    txdata = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));
Raymond Knopp's avatar
 
Raymond Knopp committed
4101 4102 4103
    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]);
4104 4105
      rxdata[i] = (int32_t*)malloc16(samples_per_frame*sizeof(int32_t));
      phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i] = rxdata[i]-N_TA_offset; // N_TA offset for TDD
Raymond Knopp's avatar
 
Raymond Knopp committed
4106 4107 4108 4109
    }
    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]);
4110 4111 4112
      txdata[i] = (int32_t*)malloc16(samples_per_frame*sizeof(int32_t));
      phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i] = txdata[i];
      memset(txdata[i], 0, samples_per_frame*sizeof(int32_t));
Raymond Knopp's avatar
 
Raymond Knopp committed
4113 4114
    }
    
Raymond Knopp's avatar
 
Raymond Knopp committed
4115
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
4116 4117 4118 4119
    
  }
  return(0);

Raymond Knopp's avatar
 
Raymond Knopp committed
4120
}
4121

4122 4123 4124 4125 4126
/* 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]) {
4127

4128
  int i, CC_id;
4129
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
4130
  uint16_t N_TA_offset = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
4131 4132
#else
  int j;
Raymond Knopp's avatar
 
Raymond Knopp committed
4133
#endif
4134
  LTE_DL_FRAME_PARMS *frame_parms;
4135

Raymond Knopp's avatar
 
Raymond Knopp committed
4136

4137 4138
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    if (phy_vars_eNB[CC_id]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
4139 4140 4141
      frame_parms = &(phy_vars_eNB[CC_id]->lte_frame_parms);
      printf("setup_eNB_buffers: frame_parms = %p\n",frame_parms);
    } 
4142 4143 4144
    else {
      printf("phy_vars_eNB[%d] not initialized\n", CC_id);
      return(-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
4145
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
4146

4147
#ifndef EXMIMO
4148 4149
    if (frame_parms->frame_type == TDD) {
      if (frame_parms->N_RB_DL == 100)
Raymond Knopp's avatar
 
Raymond Knopp committed
4150
	N_TA_offset = 624;
4151
      else if (frame_parms->N_RB_DL == 50)
Raymond Knopp's avatar
 
Raymond Knopp committed
4152
	N_TA_offset = 624/2;
4153
      else if (frame_parms->N_RB_DL == 25)
Raymond Knopp's avatar
 
Raymond Knopp committed
4154 4155
	N_TA_offset = 624/4;
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
4156
#endif
4157 4158 4159 4160 4161
   

   

  
Raymond Knopp's avatar
 
Raymond Knopp committed
4162
    // replace RX signal buffers with mmaped HW versions
4163
#ifdef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
4164 4165 4166
    openair0_cfg[CC_id].tx_num_channels = 0;
    openair0_cfg[CC_id].rx_num_channels = 0;

4167 4168 4169 4170 4171 4172 4173 4174 4175 4176
    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];
4177
	openair0_cfg[rf_map[CC_id].card].rx_gain[rf_map[CC_id].chain+i] = rx_gain[CC_id][i];
4178 4179 4180
	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
4181
      for (j=0;j<16;j++) {
4182 4183
	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;
4184
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
4185
    }
4186 4187 4188 4189 4190 4191 4192 4193 4194 4195
    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];
4196
	openair0_cfg[rf_map[CC_id].card].tx_gain[rf_map[CC_id].chain+i] = tx_gain[CC_id][i];
4197 4198 4199 4200
	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
4201
      for (j=0;j<16;j++) {
4202 4203
	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;
4204
      }
4205
    }
4206
#else // not EXMIMO
4207 4208 4209
    rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*));
    txdata = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));

4210 4211
    for (i=0;i<frame_parms->nb_antennas_rx;i++) {
      free(phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i]);
Raymond Knopp's avatar
 
Raymond Knopp committed
4212
      rxdata[i] = (int32_t*)(16 + malloc16(16+samples_per_frame*sizeof(int32_t)));
4213 4214 4215
      phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i] = rxdata[i]-N_TA_offset; // N_TA offset for TDD
      memset(rxdata[i], 0, samples_per_frame*sizeof(int32_t));
      printf("rxdata[%d] @ %p (%p) (N_TA_OFFSET %d)\n", i, phy_vars_eNB[CC_id]->lte_eNB_common_vars.rxdata[0][i],rxdata[i],N_TA_offset);
Raymond Knopp's avatar
 
Raymond Knopp committed
4216
    }
4217 4218
    for (i=0;i<frame_parms->nb_antennas_tx;i++) {
      free(phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i]);
ghaddab's avatar
ghaddab committed
4219
      txdata[i] = (int32_t*)(16 + malloc16(16 + samples_per_frame*sizeof(int32_t)));
4220 4221
      phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i] = txdata[i];
      memset(txdata[i], 0, samples_per_frame*sizeof(int32_t));
4222
      printf("txdata[%d] @ %p\n", i, phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i]);
4223

Raymond Knopp's avatar
 
Raymond Knopp committed
4224 4225
    }
#endif
4226
  }
4227
  return(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
4228
}
4229

4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248
void reset_opp_meas(void){
  int sfn;
  reset_meas(&softmodem_stats_mt);
  reset_meas(&softmodem_stats_hw);
  for (sfn=0; sfn < 10; sfn++) {
    reset_meas(&softmodem_stats_tx_sf[sfn]);
    reset_meas(&softmodem_stats_rx_sf[sfn]);
  }
}

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