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
  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
Raymond Knopp's avatar
 
Raymond Knopp committed
1873 1874
	openair0_set_rx_frequencies(&openair0,&openair0_cfg[0]);
	openair0_set_gains(&openair0,&openair0_cfg[0]);
1875 1876 1877
#endif
#endif
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1878 1879 1880
    }    
    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);
  }
1881
  else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1882 1883 1884
    LOG_D(PHY,"[SCHED][UE] Check absolute frequency %u\n",downlink_frequency[0][0]);
  }

Raymond Knopp's avatar
 
Raymond Knopp committed
1885 1886
  while (!oai_exit) {
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1887 1888 1889 1890 1891 1892
    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
1893 1894
	pthread_cond_wait(&UE->cond_synch,&UE->mutex_synch);
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1895
      if (pthread_mutex_unlock(&UE->mutex_synch) != 0) {	
Raymond Knopp's avatar
 
Raymond Knopp committed
1896 1897 1898
	LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for UE Initial Synch thread\n");
	oai_exit=1;
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1899 1900 1901 1902 1903 1904 1905 1906 1907 1908
    }  // mutex_lock      
    
    vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SYNCH,1); 
    switch (sync_mode) {
    case rssi:
      rssi_min = (1<<31)-1;
      rssi_max = 0;
      rssi_avg = 0;
      for (i=0;i<76800;i+=7680) {
	
1909 1910
	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)
1911
	  rssi_lin += signal_energy(&PHY_vars_UE_g[0][0]->lte_ue_common_vars.rxdata[1][i],7680);
Raymond Knopp's avatar
 
Raymond Knopp committed
1912 1913 1914
	rssi_avg += rssi_lin;
	rssi_min = (rssi_lin < rssi_min) ? rssi_lin : rssi_min;
	rssi_max = (rssi_lin > rssi_max) ? rssi_lin : rssi_max;
1915
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934
      
      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 (%d,%d,%d) (avg, min, max) %f,%f,%f dBm\n",
	    bands_to_scan.band_info[current_band].band,
	    downlink_frequency[0][0],
	    rssi_avg/10,
	    rssi_min,
	    rssi_max,
	    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;
1935
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1936 1937 1938
      if (current_band==bands_to_scan.nbands) {
	current_band=0;
	oai_exit=1; 
1939
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1940 1941
      
      for (card=0;card<MAX_CARDS;card++) {
1942
	for (i=0; i<openair0_cfg[card].rx_num_channels; i++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1943 1944 1945 1946 1947 1948 1949
	  downlink_frequency[card][i] = bands_to_scan.band_info[current_band].dl_min+current_offset;
	  uplink_frequency_offset[card][i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset;
	  
	  
	  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
1950 1951
#ifdef USRP
#ifndef USRP_DEBUG
Raymond Knopp's avatar
 
Raymond Knopp committed
1952 1953
	openair0_set_rx_frequencies(&openair0,&openair0_cfg[0]);
	//	openair0_set_gains(&openair0,&openair0_cfg[0]);
1954 1955
#endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
1956 1957 1958 1959 1960 1961 1962
	}
      }	
      
      break;
    case pbch:
      
      if (initial_sync(PHY_vars_UE_g[0][0],mode)==0) {
1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975
	/*
	  lte_adjust_synch(&PHY_vars_UE_g[0]->lte_frame_parms,
	  PHY_vars_UE_g[0],
	  0,
	  1,
	  16384);
	*/
	//for better visualization afterwards
	/*
	  for (aa=0; aa<PHY_vars_UE_g[0]->lte_frame_parms.nb_antennas_rx; aa++)
	  memset(PHY_vars_UE_g[0]->lte_ue_common_vars.rxdata[aa],0,
	  PHY_vars_UE_g[0]->lte_frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int));
	*/
Raymond Knopp's avatar
 
Raymond Knopp committed
1976
	
1977
	T0 = rt_get_time_ns();
Raymond Knopp's avatar
 
Raymond Knopp committed
1978
	
1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992
	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
1993 1994
	openair_daq_vars.freq_offset += 100;
	openair_daq_vars.freq_offset *= -1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1995
      }
1996
	else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1997 1998
	openair_daq_vars.freq_offset *= -1;
      }
1999
	if (abs(openair_daq_vars.freq_offset) > 7500) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2000 2001
	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
2002
      }
2003
	else {
Raymond Knopp's avatar
 
Raymond Knopp committed
2004
	LOG_I(PHY,"[initial_sync] trying carrier off %d Hz, rxgain %d\n",openair_daq_vars.freq_offset,
2005
	  PHY_vars_UE_g[0][0]->rx_total_gain_dB);
Raymond Knopp's avatar
 
Raymond Knopp committed
2006
	for (card=0;card<MAX_CARDS;card++) {
2007 2008 2009 2010
	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
2011
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
2012
#ifndef USRP_DEBUG
2013 2014
	openair0_set_frequencies(&openair0,&openair0_cfg[0]);
	//	    openair0_set_gains(&openair0,&openair0_cfg[0]);
Navid Nikaein's avatar
Navid Nikaein committed
2015
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2016
#endif
2017 2018 2019
      }
    }
	    
Raymond Knopp's avatar
 
Raymond Knopp committed
2020
	//	    openair0_dump_config(&openair0_cfg[0],UE_flag);
2021
	    
Raymond Knopp's avatar
 
Raymond Knopp committed
2022
	//	    rt_sleep_ns(FRAME_PERIOD);
2023 2024 2025 2026 2027 2028 2029
  } // freq_offset
} // initial_sync=0
  break;
 case si:
 default:
break;
}
Raymond Knopp's avatar
 
Raymond Knopp committed
2030
     vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SYNCH,0);  
2031 2032 2033 2034 2035
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
2036
      
2037 2038 2039 2040
   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
2041
   vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SYNCH,0); 
2042 2043
}  // while !oai_exit
return(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
2044 2045 2046 2047
}

static void *UE_thread_tx(void *arg) {

Raymond Knopp's avatar
 
Raymond Knopp committed
2048 2049 2050 2051 2052
#ifdef LOWLATENCY
  struct sched_attr attr;
  unsigned int flags = 0;
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2053 2054 2055 2056 2057 2058 2059 2060 2061 2062
  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
2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080
#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
2081 2082 2083 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
  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
2131
  
Raymond Knopp's avatar
 
Raymond Knopp committed
2132
  PHY_VARS_UE *UE = (PHY_VARS_UE*)arg;
Raymond Knopp's avatar
 
Raymond Knopp committed
2133
  int i;
2134
  /*
2135 2136 2137 2138
    #ifdef LOWLATENCY
    struct sched_attr attr;
    unsigned int flags = 0;
    #endif
2139
  */
Raymond Knopp's avatar
 
Raymond Knopp committed
2140
  UE->instance_cnt_rx=-1;
2141
  /*
2142 2143 2144 2145 2146
    #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
2147
  
2148 2149 2150 2151 2152
    // 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
2153
  
2154
    if (sched_setattr(0, &attr, flags) < 0 ){
Raymond Knopp's avatar
 
Raymond Knopp committed
2155 2156
    perror("[SCHED] eNB tx thread: sched_setattr failed\n");
    exit(-1);
2157 2158 2159
    }  
    #endif
  */
Raymond Knopp's avatar
 
Raymond Knopp committed
2160
  mlockall(MCL_CURRENT | MCL_FUTURE);
Raymond Knopp's avatar
 
Raymond Knopp committed
2161
  
2162
#ifndef EXMIMO
ghaddab's avatar
ghaddab committed
2163
  printf("waiting for sync (UE_thread_rx)\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
2164 2165 2166 2167 2168
#ifdef RTAI
  rt_sem_wait(sync_sem);
#else
  pthread_mutex_lock(&sync_mutex);
  printf("Locked sync_mutex, waiting (UE_thread_rx)\n");
2169 2170
  while (sync_var<0)
    pthread_cond_wait(&sync_cond, &sync_mutex);
Raymond Knopp's avatar
 
Raymond Knopp committed
2171 2172 2173 2174
  pthread_mutex_unlock(&sync_mutex);
  printf("unlocked sync_mutex, waiting (UE_thread_rx)\n");
#endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2175

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
2232 2233 2234



2235
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
2236 2237 2238 2239 2240
#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
2241

Raymond Knopp's avatar
 
Raymond Knopp committed
2242 2243 2244
  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
2245
  // unsigned int aa;
Raymond Knopp's avatar
 
Raymond Knopp committed
2246
  int dummy[2][samples_per_packets];
Raymond Knopp's avatar
 
Raymond Knopp committed
2247 2248 2249 2250 2251
  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
2252
  int i;
Raymond Knopp's avatar
 
Raymond Knopp committed
2253 2254 2255

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

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

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

  printf("starting UE thread\n");
2279
  /*
2280 2281 2282 2283 2284
    #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
2285
   
2286 2287 2288 2289 2290
    // 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
2291
   
2292 2293 2294 2295
    // 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
2296
   
2297
    if (sched_setattr(0, &attr, flags) < 0 ){
Raymond Knopp's avatar
 
Raymond Knopp committed
2298 2299
    perror("[SCHED] main eNB thread: sched_setattr failed\n");
    exit_fun("Nothing to add");
2300
    } else {
Raymond Knopp's avatar
 
Raymond Knopp committed
2301
    LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %ld started on CPU %d\n",
2302 2303 2304 2305
    gettid(),sched_getcpu());
    }
    #endif
  */
Raymond Knopp's avatar
 
Raymond Knopp committed
2306
  mlockall(MCL_CURRENT | MCL_FUTURE);
Raymond Knopp's avatar
 
Raymond Knopp committed
2307 2308

  T0 = rt_get_time_ns();
Raymond Knopp's avatar
 
Raymond Knopp committed
2309 2310 2311
  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
2312

Raymond Knopp's avatar
 
Raymond Knopp committed
2313

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

      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
2322 2323
      rxs = openair0.trx_read_func(&openair0,
				   &timestamp,
Raymond Knopp's avatar
 
Raymond Knopp committed
2324 2325 2326
				   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
2327
      if (rxs != (samples_per_packets- ((rx_cnt==0) ? rx_off_diff : 0)))
Raymond Knopp's avatar
 
Raymond Knopp committed
2328
	oai_exit=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
2329 2330

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


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

Raymond Knopp's avatar
 
Raymond Knopp committed
2491 2492


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

2514

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

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

#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
2526
  rt_make_hard_real_time();
2527 2528
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
2529
  mlockall(MCL_CURRENT | MCL_FUTURE);
2530

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

Raymond Knopp's avatar
 
Raymond Knopp committed
2544
    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
2545 2546

     
Raymond Knopp's avatar
 
Raymond Knopp committed
2547
    if (is_synchronized) {
Raymond Knopp's avatar
 
Raymond Knopp committed
2548 2549


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

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

#ifdef HARD_RT
Raymond Knopp's avatar
 
Raymond Knopp committed
2727
  rt_make_soft_real_time();
2728 2729
#endif

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

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

2740
#endif
2741

2742

Raymond Knopp's avatar
 
Raymond Knopp committed
2743 2744 2745 2746 2747
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
2748
  pthread_attr_setstacksize(&attr_UE_thread_tx,PTHREAD_STACK_MIN);
Raymond Knopp's avatar
 
Raymond Knopp committed
2749 2750 2751 2752 2753
  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
2754
  pthread_attr_setstacksize(&attr_UE_thread_rx,PTHREAD_STACK_MIN);
Raymond Knopp's avatar
 
Raymond Knopp committed
2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772
  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;

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

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


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
2816

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


  size_t size; 
  FILE *f;
2835

Raymond Knopp's avatar
 
Raymond Knopp committed
2836 2837 2838 2839 2840 2841 2842 2843 2844
  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,
2845
    LONG_OPTION_NO_L2_CONNECT
Raymond Knopp's avatar
 
Raymond Knopp committed
2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856
  };
  
  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
2857
  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
2858 2859 2860 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
    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
2890 2891 2892
#ifdef ETHERNET
      strcpy(rrh_eNB_ip,optarg);
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2893 2894
      break;
    case 'C':
2895
      for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
2896 2897 2898 2899 2900
	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]);
2901
      }
2902
      UE_scan=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
2903 2904 2905 2906 2907
      break;
      
    case 'd':
#ifdef XFORMS
      do_forms=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
2908
      printf("Running with XFORMS!\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926
#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;
2927 2928 2929 2930 2931 2932 2933
    
    case 'm':
      target_dl_mcs = atoi (optarg);
      break;
    case 't':
      target_ul_mcs = atoi (optarg);
      break;
2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949
    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
2950 2951 2952 2953
      
    case 'V':
      ouput_vcd = 1;
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
2954
    case  'q':
Raymond Knopp's avatar
 
Raymond Knopp committed
2955 2956 2957 2958 2959 2960
      opp_enabled = 1;
      break;
    case  'R' :
      online_log_messages =1;
      break;
    case 'r':
Raymond Knopp's avatar
 
Raymond Knopp committed
2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982
      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
2983
      }
2984
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
2985 2986
    case 's':
#ifdef USRP
Raymond Knopp's avatar
 
Raymond Knopp committed
2987 2988 2989

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

    case 'F':
3010
#ifdef EXMIMO
3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027
      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);
3028
#endif
3029 3030
      break;
      
3031 3032 3033
    case 'G':
      glog_verbosity=atoi(optarg);// value from 0, 0x5, 0x15, 0x35, 0x75
      break;
3034 3035 3036 3037 3038 3039 3040
    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
3041 3042
    default:
      break;
3043 3044
    }
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3045 3046
  
  if ((UE_flag == 0) && (conf_config_file_name != NULL)) {
3047
    int i,j;
Raymond Knopp's avatar
 
Raymond Knopp committed
3048 3049 3050 3051 3052 3053 3054 3055 3056
    
    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);
3057

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

3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099
      
#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
      
3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113
      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
3114 3115 3116 3117 3118 3119
# 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
3120 3121 3122 3123
#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 
3124
    
Raymond Knopp's avatar
 
Raymond Knopp committed
3125
      // adjust the log
3126 3127
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
	for (k = 0 ; k < 4; k++) {
3128
	  downlink_frequency[CC_id][k]      =       enb_properties->properties[i]->downlink_frequency[CC_id];
3129
	  uplink_frequency_offset[CC_id][k] =  enb_properties->properties[i]->uplink_frequency_offset[CC_id];
3130 3131
	  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];
3132
	}
3133
	printf("Downlink frequency/ uplink offset of CC_id %d set to %ju/%d\n", CC_id,
3134 3135
	       enb_properties->properties[i]->downlink_frequency[CC_id],
	       enb_properties->properties[i]->uplink_frequency_offset[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
3136
      } // CC_id
3137
    }// i
Raymond Knopp's avatar
 
Raymond Knopp committed
3138
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
3139 3140 3141 3142 3143 3144 3145
  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
3146
}
3147

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

#ifdef ENABLE_TCXO
Raymond Knopp's avatar
 
Raymond Knopp committed
3168
  unsigned int tcxo = 114;
3169 3170
#endif

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
3180
  set_latency_target();
3181

Raymond Knopp's avatar
 
Raymond Knopp committed
3182
  mode = normal_txrx;
3183

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

3198 3199 3200
  // initialize the log (see log.h for details)
  logInit();
  set_glog(glog_level, glog_verbosity);
winckel's avatar
winckel committed
3201

Raymond Knopp's avatar
 
Raymond Knopp committed
3202 3203
  //randominit (0);
  set_taus_seed (0);
winckel's avatar
winckel committed
3204

3205 3206
  get_options (argc, argv); //Command-line options
  
Raymond Knopp's avatar
 
Raymond Knopp committed
3207 3208 3209 3210

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
3264 3265 3266 3267 3268 3269
  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");
  }
3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283
  
  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");
  }
  
3284
#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
3285 3286 3287 3288 3289 3290
  if (UE_flag == 1) {
    log_set_instance_type (LOG_INSTANCE_UE);
  }
  else {
    log_set_instance_type (LOG_INSTANCE_ENB);
  }
3291

Raymond Knopp's avatar
 
Raymond Knopp committed
3292
  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
3293 3294
#endif

3295
#ifdef NAS_NETLINK
Raymond Knopp's avatar
 
Raymond Knopp committed
3296
  netlink_init();
3297 3298
#endif

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

#ifndef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3306 3307 3308 3309
  check_clock();
#endif

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

Raymond Knopp's avatar
 
Raymond Knopp committed
3315
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
3316 3317 3318 3319
    else
      { //UE_flag==1
	frame_parms[CC_id]->nb_antennas_tx     = 1;
	frame_parms[CC_id]->nb_antennas_rx     = 1;
3320
	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
3321 3322 3323 3324 3325 3326 3327 3328 3329
      }
    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;
3330 3331
    init_ul_hopping(frame_parms[CC_id]);
    init_frame_parms(frame_parms[CC_id],1);
3332
    phy_init_top(frame_parms[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344
  }

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

  if (UE_flag==1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3349 3350 3351
    NB_UE_INST=1;
    NB_INST=1;

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

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

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

3459
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3460

3461
	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
3462

3463
#else
3464
	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
3465 3466 3467

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

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

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


Raymond Knopp's avatar
 
Raymond Knopp committed
3494 3495
      NB_eNB_INST=1;
      NB_INST=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
3496

Raymond Knopp's avatar
 
Raymond Knopp committed
3497
      openair_daq_vars.ue_dl_rb_alloc=0x1fff;
3498
      openair_daq_vars.target_ue_dl_mcs=target_dl_mcs;
Raymond Knopp's avatar
 
Raymond Knopp committed
3499
      openair_daq_vars.ue_ul_nb_rb=6;
3500
      openair_daq_vars.target_ue_ul_mcs=target_ul_mcs;
Raymond Knopp's avatar
 
Raymond Knopp committed
3501 3502

    }
3503

3504

3505

Raymond Knopp's avatar
 
Raymond Knopp committed
3506
  dump_frame_parms(frame_parms[0]);
3507

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

#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

3566

3567
  for (card=0;card<MAX_CARDS;card++) {
3568
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3569
    openair0_cfg[card].samples_per_packet = samples_per_packets;
3570 3571 3572 3573
#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
3574 3575
    openair0_cfg[card].Mod_id = 0;
#ifdef ETHERNET
ghaddab's avatar
ghaddab committed
3576
    if (UE_flag){
Raymond Knopp's avatar
 
Raymond Knopp committed
3577 3578 3579
      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
3580 3581
    }
    else
Raymond Knopp's avatar
 
Raymond Knopp committed
3582 3583 3584 3585 3586
      {
	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
3587
#endif
3588 3589 3590
    openair0_cfg[card].sample_rate = sample_rate;
    openair0_cfg[card].tx_bw = bw;
    openair0_cfg[card].rx_bw = bw;
3591 3592 3593
    // 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
3594
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
3595 3596
    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));
3597
    for (i=0;i<4;i++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3598

3599
      openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
Raymond Knopp's avatar
 
Raymond Knopp committed
3600
      openair0_cfg[card].rx_gain[i] = ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->rx_total_gain_eNB_dB : 
3601
                                       PHY_vars_UE_g[0][0]->rx_total_gain_dB) - USRP_GAIN_OFFSET;  // calibrated for USRP B210 @ 2.6 GHz
3602 3603
      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
3604 3605 3606 3607 3608 3609
      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
3610
    }
3611
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
3612
  }
3613 3614

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

  mac_xface = malloc(sizeof(MAC_xface));

3621
#ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3622
  int eMBMS_active=0;
3623

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

Raymond Knopp's avatar
 
Raymond Knopp committed
3633
  mac_xface->macphy_exit = &exit_fun;
3634

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

Raymond Knopp's avatar
 
Raymond Knopp committed
3643 3644 3645
  if (UE_flag==1)
    fill_ue_band_info();

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

3664
#ifdef EXMIMO
3665
  number_of_cards = openair0_num_detected_cards;
3666 3667 3668
#else
  number_of_cards = 1;
#endif 
3669

Raymond Knopp's avatar
 
Raymond Knopp committed
3670
  openair_daq_vars.timing_advance = 0;
3671

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

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
3726
  mlockall(MCL_CURRENT | MCL_FUTURE);
3727 3728

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
3755 3756 3757
#else
  pthread_cond_init(&sync_cond,NULL);
  pthread_mutex_init(&sync_mutex, NULL);
3758 3759
#endif

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

Raymond Knopp's avatar
 
Raymond Knopp committed
3768 3769

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

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

    if (UE_flag==0) {
3781
      form_stats_l2 = create_form_stats_form();
3782 3783 3784
      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
3785 3786 3787 3788 3789 3790 3791
      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
3792 3793
	}
	else {
Raymond Knopp's avatar
 
Raymond Knopp committed
3794 3795
	  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
3796
	}
3797 3798
      }
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3799
    else {
3800 3801 3802 3803 3804 3805 3806
      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
3807 3808 3809 3810 3811 3812 3813 3814 3815 3816
      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
3817
    ret = pthread_create(&forms_thread, NULL, scope_thread, NULL);
Raymond Knopp's avatar
 
Raymond Knopp committed
3818 3819
    printf("Scope thread created, ret=%d\n",ret);
  }
3820 3821 3822
#endif

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

Raymond Knopp's avatar
 
Raymond Knopp committed
3827
  rt_sleep_ns(10*FRAME_PERIOD);
3828 3829

#ifndef RTAI
Raymond Knopp's avatar
 
Raymond Knopp committed
3830
  pthread_attr_init (&attr_dlsch_threads);
Raymond Knopp's avatar
 
Raymond Knopp committed
3831
  pthread_attr_setstacksize(&attr_dlsch_threads,PTHREAD_STACK_MIN);
3832

3833 3834 3835
  pthread_attr_init (&attr_UE_thread);
  pthread_attr_setstacksize(&attr_UE_thread,4*PTHREAD_STACK_MIN);

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

3847 3848
#endif

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
3894
  // Sleep to allow all threads to setup
Raymond Knopp's avatar
 
Raymond Knopp committed
3895
  sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
3896

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

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

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

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

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
3981
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
3982
  }
3983

3984
#ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
3985
  //cleanup_pdcp_thread();
3986 3987
#endif

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

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
4014 4015
  if (ouput_vcd)
    vcd_signal_dumper_close();
4016

4017 4018 4019
  if (opt_type != OPT_NONE)
    terminate_opt();

Raymond Knopp's avatar
 
Raymond Knopp committed
4020
  logClean();
4021

Raymond Knopp's avatar
 
Raymond Knopp committed
4022 4023
  return 0;
}
4024

4025 4026
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
4027

4028
#ifndef EXMIMO
Raymond Knopp's avatar
 
Raymond Knopp committed
4029 4030 4031
  uint16_t N_TA_offset = 0;
#endif

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

Raymond Knopp's avatar
 
Raymond Knopp committed
4043

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

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

4091
      printf("txdata[%d] @ %p\n",i,phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i]);
4092
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
4093
  
Raymond Knopp's avatar
 
Raymond Knopp committed
4094
#else
Raymond Knopp's avatar
 
Raymond Knopp committed
4095
    // replace RX signal buffers with mmaped HW versions
4096 4097
    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
4098 4099 4100
    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]);
4101 4102
      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
4103 4104 4105 4106
    }
    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]);
4107 4108 4109
      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
4110 4111
    }
    
Raymond Knopp's avatar
 
Raymond Knopp committed
4112
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
4113 4114 4115 4116
    
  }
  return(0);

Raymond Knopp's avatar
 
Raymond Knopp committed
4117
}
4118

4119 4120 4121 4122 4123
/* 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]) {
4124

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

Raymond Knopp's avatar
 
Raymond Knopp committed
4133

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

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

   

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

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

4207 4208
    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
4209
      rxdata[i] = (int32_t*)(16 + malloc16(16+samples_per_frame*sizeof(int32_t)));
4210 4211 4212
      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
4213
    }
4214 4215
    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
4216
      txdata[i] = (int32_t*)(16 + malloc16(16 + samples_per_frame*sizeof(int32_t)));
4217 4218
      phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i] = txdata[i];
      memset(txdata[i], 0, samples_per_frame*sizeof(int32_t));
4219
      printf("txdata[%d] @ %p\n", i, phy_vars_eNB[CC_id]->lte_eNB_common_vars.txdata[0][i]);
4220

Raymond Knopp's avatar
 
Raymond Knopp committed
4221 4222
    }
#endif
4223
  }
4224
  return(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
4225
}
4226

4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245
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);
  }
}