lte-ue.c 61.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

/*! \file lte-ue.c
 * \brief threads and support functions for real-time LTE UE target
 * \author R. Knopp, F. Kaltenberger, Navid Nikaein
 * \date 2015
 * \version 0.1
 * \company Eurecom
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
 * \note
 * \warning
 */
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sched.h>
#include <linux/sched.h>
#include <signal.h>
#include <execinfo.h>
#include <getopt.h>
#include <syscall.h>
48
#include <sys/sysinfo.h>
49
50
51
52
53
54

#include "rt_wrapper.h"
#include "assertions.h"
#include "PHY/types.h"

#include "PHY/defs.h"
knopp's avatar
   
knopp committed
55
#ifdef OPENAIR2
56
57
#include "LAYER2/MAC/defs.h"
#include "RRC/LITE/extern.h"
knopp's avatar
   
knopp committed
58
#endif
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include "PHY_INTERFACE/extern.h"

#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all

#include "../../ARCH/COMMON/common_lib.h"

#include "PHY/extern.h"
#include "SCHED/extern.h"
#include "LAYER2/MAC/extern.h"
#include "LAYER2/MAC/proto.h"

#include "UTIL/LOG/log_extern.h"
#include "UTIL/OTG/otg_tx.h"
#include "UTIL/OTG/otg_externs.h"
#include "UTIL/MATH/oml.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"

Bilel's avatar
Bilel committed
78
79
#include "T.h"

80
81
82
83
84
85
86
87
88
#define FRAME_PERIOD    100000000ULL
#define DAQ_PERIOD      66667ULL

typedef enum {
  pss=0,
  pbch=1,
  si=2
} sync_mode_t;

knopp's avatar
knopp committed
89
void init_UE_threads(int nb_inst);
90
void *UE_thread(void *arg);
knopp's avatar
knopp committed
91
void init_UE(int nb_inst);
92
93
94
95
96

extern pthread_cond_t sync_cond;
extern pthread_mutex_t sync_mutex;
extern int sync_var;

97

98
99
extern openair0_config_t openair0_cfg[MAX_CARDS];
extern uint32_t          downlink_frequency[MAX_NUM_CCs][4];
100
extern int32_t           uplink_frequency_offset[MAX_NUM_CCs][4];
101
102
extern int oai_exit;

103
104
int32_t **rxdata;
int32_t **txdata;
105

106
107
//extern unsigned int tx_forward_nsamps;
//extern int tx_delay;
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

extern int rx_input_level_dBm;
extern uint8_t exit_missed_slots;
extern uint64_t num_missed_slots; // counter for the number of missed slots

extern void exit_fun(const char* s);

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

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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},
  {20,  832    * MHz,  862    * MHz,  791    * MHz,  821    * MHz, FDD},
151
  {22, 3510    * MHz, 3590    * MHz, 3410    * MHz, 3490    * MHz, FDD},
152
153
154
155
156
157
158
159
160
161
162
163
164
165
  {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},
};

166
167
168
169
pthread_t                       main_ue_thread;
pthread_attr_t                  attr_UE_thread;
struct sched_param              sched_param_UE_thread;

knopp's avatar
knopp committed
170
void init_UE(int nb_inst) {
171
172

  int error_code;
knopp's avatar
knopp committed
173
174
  int inst;
  PHY_VARS_UE *UE;
knopp's avatar
knopp committed
175
  int ret;
knopp's avatar
knopp committed
176
177
178
179
180
181

  for (inst=0;inst<nb_inst;inst++) {
    printf("Intializing UE Threads for instance %d ...\n",inst);
    init_UE_threads(inst);
    sleep(1);
    UE = PHY_vars_UE_g[inst][0];
knopp's avatar
knopp committed
182
183

    ret = openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]);
Rohit Gupta's avatar
Rohit Gupta committed
184
185
186
    if (ret !=0){
       exit_fun("Error loading device library");
    }
knopp's avatar
knopp committed
187
    UE->rfdevice.host_type = BBU_HOST;
knopp's avatar
knopp committed
188
    //    UE->rfdevice.type      = NONE_DEV;
knopp's avatar
knopp committed
189
190
191
192
193
194
195
196
197
    error_code = pthread_create(&UE->proc.pthread_ue, &UE->proc.attr_ue, UE_thread, NULL);
    
    if (error_code!= 0) {
      LOG_D(HW,"[lte-softmodem.c] Could not allocate UE_thread, error %d\n",error_code);
      return;
    } else {
      LOG_D(HW, "[lte-softmodem.c] Allocate UE_thread successful\n" );
      pthread_setname_np( UE->proc.pthread_ue, "main UE" );
    }
198
199
200
201
202
203
204
205
206
207
208
209
210
  }

  printf("UE threads created\n");
#ifdef USE_MME
  
  while (start_UE == 0) {
    sleep(1);
  }
  
#endif
  
}

211
212
/*!
 * \brief This is the UE synchronize thread.
213
 * It performs band scanning and synchonization.
214
215
216
 * \param arg is a pointer to a \ref PHY_VARS_UE structure.
 * \returns a pointer to an int. The storage is not on the heap and must not be freed.
 */
217
218
static void *UE_thread_synch(void *arg)
{
219
220
221
  static int UE_thread_synch_retval;
  int i, hw_slot_offset;
  PHY_VARS_UE *UE = (PHY_VARS_UE*) arg;
222
223
  int current_band = 0;
  int current_offset = 0;
224
  sync_mode_t sync_mode = pbch;
225
  int CC_id = UE->CC_id;
226
227
  int ind;
  int found;
228
  int freq_offset=0;
229
230
231
232
233

  UE->is_synchronized = 0;
  printf("UE_thread_sync in with PHY_vars_UE %p\n",arg);
  printf("waiting for sync (UE_thread_synch) \n");

laurent's avatar
laurent committed
234
#ifndef DEADLINE_SCHEDULER
235
236
237
238
239
240
241
242
243
  int policy, s, j;
  struct sched_param sparam;
  char cpu_affinity[1024];
  cpu_set_t cpuset;

  /* Set affinity mask to include CPUs 1 to MAX_CPUS */
  /* CPU 0 is reserved for UHD threads */
  CPU_ZERO(&cpuset);

Rohit Gupta's avatar
Rohit Gupta committed
244
245
  #ifdef CPU_AFFINITY
  if (get_nprocs() >2)
246
  {
Rohit Gupta's avatar
Rohit Gupta committed
247
248
249
250
251
252
253
254
255
    for (j = 1; j < get_nprocs(); j++)
      CPU_SET(j, &cpuset);

    s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
    if (s != 0)
    {
      perror( "pthread_setaffinity_np");
      exit_fun("Error setting processor affinity");
    }
256
  }
Rohit Gupta's avatar
Rohit Gupta committed
257
258
  #endif

259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
  /* Check the actual affinity mask assigned to the thread */

  s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
  if (s != 0)
  {
    perror( "pthread_getaffinity_np");
    exit_fun("Error getting processor affinity ");
  }
  memset(cpu_affinity, 0 , sizeof(cpu_affinity));
  for (j = 0; j < CPU_SETSIZE; j++)
  if (CPU_ISSET(j, &cpuset))
  {  
     char temp[1024];
     sprintf(temp, " CPU_%d ", j);    
     strcat(cpu_affinity, temp);
  }

  memset(&sparam, 0 , sizeof (sparam));
  sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1;
  policy = SCHED_FIFO ; 
  
  s = pthread_setschedparam(pthread_self(), policy, &sparam);
  if (s != 0)
     {
     perror("pthread_setschedparam : ");
     exit_fun("Error setting thread priority");
     }
  s = pthread_getschedparam(pthread_self(), &policy, &sparam);
  if (s != 0)
   {
     perror("pthread_getschedparam : ");
     exit_fun("Error getting thread priority");

   }

  LOG_I( HW, "[SCHED][UE] Started UE synch thread on CPU %d TID %ld , sched_policy = %s, priority = %d, CPU Affinity = %s \n", (int)sched_getcpu(), gettid(),
                   (policy == SCHED_FIFO)  ? "SCHED_FIFO" :
                   (policy == SCHED_RR)    ? "SCHED_RR" :
                   (policy == SCHED_OTHER) ? "SCHED_OTHER" :
                   "???",
                   (int) sparam.sched_priority, cpu_affinity);

#endif


304

305

306
  printf("starting UE synch thread (IC %d)\n",UE->proc.instance_cnt_synch);
307
308
  ind = 0;
  found = 0;
309
310


311
312
  if (UE->UE_scan == 0) {
    do  {
313
      current_band = eutra_bands[ind].band;
knopp's avatar
   
knopp committed
314
      printf( "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min);
315

316
      if ((eutra_bands[ind].dl_min <= downlink_frequency[0][0]) && (eutra_bands[ind].dl_max >= downlink_frequency[0][0])) {
317
318
	for (i=0; i<4; i++)
	  uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min;
319
320
321
322

        found = 1;
        break;
      }
323

324
      ind++;
325
326
    } while (ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]));
  
327
328
    if (found == 0) {
      exit_fun("Can't find EUTRA band for frequency");
329
      return &UE_thread_synch_retval;
330
    }
331

332
333


334

335
336


337
    LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0],oai_exit, openair0_cfg[0].rx_num_channels);
338

339
340
341
342
343
344
    for (i=0;i<openair0_cfg[UE->rf_map.card].rx_num_channels;i++) {
      openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
      openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
      openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
      if (uplink_frequency_offset[CC_id][i] != 0) // 
	openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD;
345
      else //FDD
346
	openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD;
347
348
    }

349
    sync_mode = pbch;
350

351
  } else if  (UE->UE_scan == 1) {
352
    current_band=0;
353

354
355
356
357
358
359
360
    for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
      downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min;
      uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min;
      
      openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
      openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
      openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;
361
362
    }
  }
363

knopp's avatar
knopp committed
364

365
366
367
368
369
370
371
372
373
  pthread_mutex_lock(&sync_mutex);
  printf("Locked sync_mutex, waiting (UE_sync_thread)\n");

  while (sync_var<0)
    pthread_cond_wait(&sync_cond, &sync_mutex);

  pthread_mutex_unlock(&sync_mutex);
  printf("Started device, unlocked sync_mutex (UE_sync_thread)\n");

knopp's avatar
knopp committed
374
375
376
377
378
  if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { 
    LOG_E(HW,"Could not start the device\n");
    oai_exit=1;
  }

379
  while (oai_exit==0) {
380

381
    if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) {
382
      LOG_E( PHY, "[SCHED][UE] error locking mutex for UE initial synch thread\n" );
383
      exit_fun("noting to add");
384
385
      return &UE_thread_synch_retval;
    }
386
    
387

388
    while (UE->proc.instance_cnt_synch < 0) {
389
      // the thread waits here most of the time
390
      pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch );
391
    }
392

393
    if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) {
394
395
396
397
      LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for UE Initial Synch thread\n" );
      exit_fun("nothing to add");
      return &UE_thread_synch_retval;
    }
398

399
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 1 );
400
401

    switch (sync_mode) {
402
    case pss:
403
404
      LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
      lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
405
406
407
408
409
410
411
      current_offset += 20000000; // increase by 20 MHz

      if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) {
        current_band++;
        current_offset=0;
      }

412
      if (current_band==bands_to_scan.nbands) {
413
414
        current_band=0;
        oai_exit=1;
415
      }
416

417
418
419
      for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
	downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset;
	uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset;
420

421
422
423
424
425
	openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
	openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
	openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;
	if (UE->UE_scan_carrier) {
	  openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
426
	}
427
	
428
      }
429

430
431
      break;
 
432
    case pbch:
433

Rohit Gupta's avatar
Rohit Gupta committed
434
      LOG_I(PHY,"[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
435
      if (initial_sync( UE, UE->mode ) == 0) {
436

437
        hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti;
438
439
440
441
442
443
444
445
        LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n",
          hw_slot_offset,
          freq_offset,
          UE->rx_total_gain_dB,
          downlink_frequency[0][0]+freq_offset,
          downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset,
          UE->UE_scan_carrier );

446
447
448
449
	if (UE->UE_scan_carrier == 1) {

	  UE->UE_scan_carrier = 0;
	  // rerun with new cell parameters and frequency-offset
450
451
452
453
454
	  for (i=0;i<openair0_cfg[UE->rf_map.card].rx_num_channels;i++) {
	    openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
	    openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= UE->common_vars.freq_offset;
	    openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =  openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i];
	    downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i];
455
456
457
	    freq_offset=0;	    
	  }

458
	  // reconfigure for potentially different bandwidth
459
	  switch(UE->frame_parms.N_RB_DL) {
460
	  case 6:
461
462
463
	    openair0_cfg[UE->rf_map.card].sample_rate =1.92e6;
	    openair0_cfg[UE->rf_map.card].rx_bw          =.96e6;
	    openair0_cfg[UE->rf_map.card].tx_bw          =.96e6;
464
	    //            openair0_cfg[0].rx_gain[0] -= 12;
465
466
	    break;
	  case 25:
467
468
469
	    openair0_cfg[UE->rf_map.card].sample_rate =7.68e6;
	    openair0_cfg[UE->rf_map.card].rx_bw          =2.5e6;
	    openair0_cfg[UE->rf_map.card].tx_bw          =2.5e6;
470
	    //            openair0_cfg[0].rx_gain[0] -= 6;
471
472
	    break;
	  case 50:
473
474
475
	    openair0_cfg[UE->rf_map.card].sample_rate =15.36e6;
	    openair0_cfg[UE->rf_map.card].rx_bw          =5.0e6;
	    openair0_cfg[UE->rf_map.card].tx_bw          =5.0e6;
476
	    //            openair0_cfg[0].rx_gain[0] -= 3;
477
478
	    break;
	  case 100:
479
480
481
	    openair0_cfg[UE->rf_map.card].sample_rate=30.72e6;
	    openair0_cfg[UE->rf_map.card].rx_bw=10.0e6;
	    openair0_cfg[UE->rf_map.card].tx_bw=10.0e6;
482
	    //            openair0_cfg[0].rx_gain[0] -= 0;
483
484
	    break;
	  }
485
	
Rohit Gupta's avatar
Rohit Gupta committed
486
	  UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
knopp's avatar
knopp committed
487
488
	  //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]);
	  UE->rfdevice.trx_stop_func(&UE->rfdevice);	  
489
	  sleep(1);
490
	  init_frame_parms(&UE->frame_parms,1);
knopp's avatar
knopp committed
491
	  if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { 
492
493
494
	    LOG_E(HW,"Could not start the device\n");
	    oai_exit=1;
	  }
495
496
497
	}
	else {
	  UE->is_synchronized = 1;
498

499
500
	  if( UE->mode == rx_dump_frame ){
	    FILE *fd;
501
	    if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) {  // this guarantees SIB1 is present 
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
	      if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) {
		fwrite((void*)&UE->common_vars.rxdata[0][0],
		       sizeof(int32_t),
		       10*UE->frame_parms.samples_per_tti,
		       fd);
		LOG_I(PHY,"Dummping Frame ... bye bye \n");
		fclose(fd);
		exit(0);
	      }
	      else {
		LOG_E(PHY,"Cannot open file for writing\n");
		exit(0);
	      }
	    }
	    else {
	      UE->is_synchronized = 0;
	    }
	  }
520
	}
521
522
523
      } else {
        // initial sync failed
        // calculate new offset and try again
524
525
526
527
528
529
530
531
532
533
	if (UE->UE_scan_carrier == 1) {
	  if (freq_offset >= 0) {
	    freq_offset += 100;
	    freq_offset *= -1;
	  } else {
	    freq_offset *= -1;
	  }
	
	  if (abs(freq_offset) > 7500) {
	    LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" );
534
	    FILE *fd;
535
	    if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) {
536
	      fwrite((void*)&UE->common_vars.rxdata[0][0],
537
		     sizeof(int32_t),
538
		     10*UE->frame_parms.samples_per_tti,
539
540
541
542
543
		     fd);
	      LOG_I(PHY,"Dummping Frame ... bye bye \n");
	      fclose(fd);
	      exit(0);
	    }
544
545
546
547
548
549
550
551
552
	    mac_xface->macphy_exit("No cell synchronization found, abandoning");
	    return &UE_thread_synch_retval; // not reached
	  }
	}
	else {
	  
	}
        LOG_I( PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", 
	       freq_offset,
553
               UE->rx_total_gain_dB,
554
555
               downlink_frequency[0][0]+freq_offset,
               downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset );
556

557
558
559
560
561
562
563
564
	for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
	  openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset;
	  openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset;
	  
	  openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
	  
	  if (UE->UE_scan_carrier==1) {
	    openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
565
	  }
566
	}
567

568
569
	UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
	    
570
      }// initial_sync=0
571

572
      break;
573

574
575
576
577
    case si:
    default:
      break;
    }
578

579

580
    if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) {
581
582
583
584
      LOG_E( PHY, "[SCHED][UE] error locking mutex for UE synch\n" );
      exit_fun("noting to add");
      return &UE_thread_synch_retval;
    }
585

586
    // indicate readiness
587
    UE->proc.instance_cnt_synch--;
588

589
    if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) {
590
591
592
      LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE synch\n" );
      exit_fun("noting to add");
      return &UE_thread_synch_retval;
593
    }
594

595
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 );
596
  }  // while !oai_exit
597

598
  return &UE_thread_synch_retval;
599
600
}

601

602

603
/*!
604
 * \brief This is the UE thread for RX subframe n and TX subframe n+4.
605
 * This thread performs the phy_procedures_UE_RX() on every received slot.
606
 * then, if TX is enabled it performs TX for n+4. 
607
608
609
 * \param arg is a pointer to a \ref PHY_VARS_UE structure.
 * \returns a pointer to an int. The storage is not on the heap and must not be freed.
 */
610

611
static void *UE_thread_rxn_txnp4(void *arg)
612
{
knopp's avatar
knopp committed
613
  static int UE_thread_rxtx_retval;
614
  UE_rxtx_proc_t *proc = (UE_rxtx_proc_t *)arg;
615
  int ret;
616
617
  PHY_VARS_UE *UE=PHY_vars_UE_g[0][proc->CC_id];
  proc->instance_cnt_rxtx=-1;
618

619

laurent's avatar
laurent committed
620
#ifdef DEADLINE_SCHEDULER
621

622
623
624
  struct sched_attr attr;
  unsigned int flags = 0;

625
626
627
  attr.size = sizeof(attr);
  attr.sched_flags = 0;
  attr.sched_nice = 0;
628
  attr.sched_priority = 0;
629

630
  // This creates a .5ms reservation every 1ms period
631
632
633
634
  attr.sched_policy   = SCHED_DEADLINE;
  attr.sched_runtime  = 900000;  // each rx thread requires 1ms to finish its job
  attr.sched_deadline = 1000000; // each rx thread will finish within 1ms
  attr.sched_period   = 1000000; // each rx thread has a period of 1ms from the starting point
635
636

  if (sched_setattr(0, &attr, flags) < 0 ) {
knopp's avatar
knopp committed
637
638
    perror("[SCHED] UE_thread_rxtx : sched_setattr failed\n");
    return &UE_thread_rxtx_retval;
639
640
  }

641
#else
642
643
644
645
646
647
648
649
650
  int policy, s, j;
  struct sched_param sparam;
  char cpu_affinity[1024];
  cpu_set_t cpuset;

  /* Set affinity mask to include CPUs 1 to MAX_CPUS */
  /* CPU 0 is reserved for UHD threads */
  CPU_ZERO(&cpuset);

Rohit Gupta's avatar
Rohit Gupta committed
651
652
  #ifdef CPU_AFFINITY
  if (get_nprocs() >2)
653
  {
Rohit Gupta's avatar
Rohit Gupta committed
654
655
656
657
658
659
660
661
662
    for (j = 1; j < get_nprocs(); j++)
      CPU_SET(j, &cpuset);

    s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
    if (s != 0)
    {
      perror( "pthread_setaffinity_np");
      exit_fun("Error setting processor affinity");
    }
663
  }
Rohit Gupta's avatar
Rohit Gupta committed
664
665
  #endif

666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
  /* Check the actual affinity mask assigned to the thread */

  s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
  if (s != 0)
  {
    perror( "pthread_getaffinity_np");
    exit_fun("Error getting processor affinity ");
  }
  memset(cpu_affinity, 0 , sizeof(cpu_affinity));
  for (j = 0; j < CPU_SETSIZE; j++)
  if (CPU_ISSET(j, &cpuset))
  {  
     char temp[1024];
     sprintf(temp, " CPU_%d ", j);    
     strcat(cpu_affinity, temp);
  }

  memset(&sparam, 0 , sizeof (sparam));
  sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1;
  policy = SCHED_FIFO ; 
  
  s = pthread_setschedparam(pthread_self(), policy, &sparam);
  if (s != 0)
     {
     perror("pthread_setschedparam : ");
     exit_fun("Error setting thread priority");
     }
  s = pthread_getschedparam(pthread_self(), &policy, &sparam);
  if (s != 0)
   {
     perror("pthread_getschedparam : ");
     exit_fun("Error getting thread priority");

   }

  LOG_I( HW, "[SCHED][UE] Started UE RX thread on CPU %d TID %ld , sched_policy = %s, priority = %d, CPU Affinity = %s \n", (int)sched_getcpu(), gettid(),
                   (policy == SCHED_FIFO)  ? "SCHED_FIFO" :
                   (policy == SCHED_RR)    ? "SCHED_RR" :
                   (policy == SCHED_OTHER) ? "SCHED_OTHER" :
                   "???",
                   (int) sparam.sched_priority, cpu_affinity);

708

709
#endif
710

711
  // Lock memory from swapping. This is a process wide call (not constraint to this thread).
712
  mlockall(MCL_CURRENT | MCL_FUTURE);
713

714
  printf("waiting for sync (UE_thread_rxn_txnp4)\n");
Florian Kaltenberger's avatar
   
Florian Kaltenberger committed
715

716
  pthread_mutex_lock(&sync_mutex);
717
  printf("Locked sync_mutex, waiting (UE_thread_rxn_txnp4)\n");
718

719
720
  while (sync_var<0)
    pthread_cond_wait(&sync_cond, &sync_mutex);
721

722
723
724
725
726
727
728
729
730
#define THREAD_NAME_LEN 16
  char threadname[THREAD_NAME_LEN];
  ret = pthread_getname_np(proc->pthread_rxtx, threadname, THREAD_NAME_LEN);
  if (ret != 0)
  {
   perror("pthread_getname_np : ");
   exit_fun("Error getting thread name");
  }

731
  pthread_mutex_unlock(&sync_mutex);
knopp's avatar
knopp committed
732
  printf("unlocked sync_mutex, waiting (UE_thread_rxtx)\n");
733

734
  printf("Starting UE RXN_TXNP4 thread (%s)\n", threadname);
735
736

  while (!oai_exit) {
Wilson's avatar
Wilson committed
737
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_COND_WAIT0+(proc->proc_id), 1 );
738
    if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
knopp's avatar
knopp committed
739
      LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
740
      exit_fun("nothing to add");
knopp's avatar
knopp committed
741
      return &UE_thread_rxtx_retval;
742
    }
743

744
    while (proc->instance_cnt_rxtx < 0) {
Wilson's avatar
Wilson committed
745
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_WAIT_COND_RXTX0+(proc->proc_id), 1 );
746
      // most of the time, the thread is waiting here
747
      pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx );
748
    }
Wilson's avatar
Wilson committed
749
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_WAIT_COND_RXTX0+(proc->proc_id), 0 );
750

751
752
    if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) {
      LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" );
753
      exit_fun("nothing to add");
knopp's avatar
knopp committed
754
      return &UE_thread_rxtx_retval;
755
    }
Wilson's avatar
Wilson committed
756
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_COND_WAIT0+(proc->proc_id), 0 );
757

Wilson's avatar
Wilson committed
758
759
760
761
762
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_RXTX0+(proc->proc_id), 1 );
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_UE+(proc->proc_id), proc->subframe_rx );
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_UE+(proc->proc_id), proc->subframe_tx );
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE+(proc->proc_id), proc->frame_rx );
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE+(proc->proc_id), proc->frame_tx );
763

764
765
766
767
    lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx);
    if ((sf_type == SF_DL) ||
        (UE->frame_parms.frame_type == FDD) ||
        (sf_type == SF_S)) {
768
    
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
      if (UE->frame_parms.frame_type == TDD) {
      LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n",
          threadname,
          UE->frame_parms.tdd_config,
          (sf_type==SF_DL? "SF_DL" :
          (sf_type==SF_UL? "SF_UL" :
          (sf_type==SF_S ? "SF_S"  : "UNKNOWN_SF_TYPE"))));
      } else {
        LOG_D(PHY, "%s,%s,%s: calling UE_RX\n",
            threadname,
            (UE->frame_parms.frame_type==FDD? "FDD":
            (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")),
            (sf_type==SF_DL? "SF_DL" :
            (sf_type==SF_UL? "SF_UL" :
            (sf_type==SF_S ? "SF_S"  : "UNKNOWN_SF_TYPE"))));
      }
785
786
      phy_procedures_UE_RX( UE, proc, 0, 0, UE->mode, no_relay, NULL );
    }
787
    
788
    if (UE->mac_enabled==1) {
789

790
      ret = mac_xface->ue_scheduler(UE->Mod_id,
791
792
793
794
795
796
797
          proc->frame_rx,
          proc->subframe_rx,
          proc->frame_tx,
          proc->subframe_tx,
          subframe_select(&UE->frame_parms,proc->subframe_tx),
          0,
          0/*FIXME CC_id*/);
798
799
800
801
802
803
804
805
806
807
808
809
810
      
      if (ret == CONNECTION_LOST) {
	LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u RRC Connection lost, returning to PRACH\n",
	       UE->Mod_id, proc->frame_rx, proc->subframe_tx );
	UE->UE_mode[0] = PRACH;
      } else if (ret == PHY_RESYNCH) {
	LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u RRC Connection lost, trying to resynch\n",
	       UE->Mod_id, proc->frame_rx, proc->subframe_tx );
	UE->UE_mode[0] = RESYNCH;
      } else if (ret == PHY_HO_PRACH) {
	LOG_I( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u, return to PRACH and perform a contention-free access\n",
	       UE->Mod_id, proc->frame_rx, proc->subframe_tx );
	UE->UE_mode[0] = PRACH;
811
812
      }
    }
813
814

    if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
815
	(UE->frame_parms.frame_type == FDD) ) {
816
817

      if (UE->mode != loop_through_memory) {
Rohit Gupta's avatar
Rohit Gupta committed
818
	phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay);
819
820
821
      }
    }

822
823
824
825
826
827
828
829
    if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) &&
  (UE->frame_parms.frame_type == TDD)) {

      if (UE->mode != loop_through_memory) {
  phy_procedures_UE_S_TX(UE,0,0,no_relay);
      }
    }

Wilson's avatar
Wilson committed
830
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_RXTX0+(proc->proc_id), 0 );
831

832
    
Wilson's avatar
Wilson committed
833
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_CNT_DECREMENT0+(proc->proc_id), 1 );
834
    if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
knopp's avatar
knopp committed
835
      LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
836
      exit_fun("noting to add");
knopp's avatar
knopp committed
837
      return &UE_thread_rxtx_retval;
838
    }
839
840
841
842
843
    
    proc->instance_cnt_rxtx--;
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_RX, proc->instance_cnt_rxtx);
    
    if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) {
knopp's avatar
knopp committed
844
      LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" );
845
      exit_fun("noting to add");
knopp's avatar
knopp committed
846
      return &UE_thread_rxtx_retval;
847
    }
Wilson's avatar
Wilson committed
848
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_CNT_DECREMENT0+(proc->proc_id), 0 );
gauthier's avatar
gauthier committed
849
  }
850
  
gauthier's avatar
gauthier committed
851
  // thread finished
knopp's avatar
knopp committed
852
  return &UE_thread_rxtx_retval;
Florian Kaltenberger's avatar
   
Florian Kaltenberger committed
853
}
854

855
856
857



858

859
860
861
862
#define RX_OFF_MAX 10
#define RX_OFF_MIN 5
#define RX_OFF_MID ((RX_OFF_MAX+RX_OFF_MIN)/2)

863
864
865
/*!
 * \brief This is the main UE thread.
 * This thread controls the other three UE threads:
866
867
 * - UE_thread_rxn_txnp4 (even subframes)
 * - UE_thread_rxn_txnp4 (odd subframes)
868
869
870
871
 * - UE_thread_synch
 * \param arg unused
 * \returns a pointer to an int. The storage is not on the heap and must not be freed.
 */
872
873
874
875
876
877

void *UE_thread(void *arg) {

  static int UE_thread_retval;
  PHY_VARS_UE *UE = PHY_vars_UE_g[0][0];
  //  int tx_enabled = 0;
878
  uint32_t rxs=0,txs=0;
879
880
  int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32)));
  openair0_timestamp timestamp,timestamp1;
Rohit Gupta's avatar
Rohit Gupta committed
881
  void* rxp[2], *txp[2];
882
883
884
885
886

#ifdef NAS_UE
  MessageDef *message_p;
#endif

887
  int start_rx_stream = 0;
888
889
  int rx_off_diff = 0;
  int rx_correction_timer = 0;
Rohit Gupta's avatar
Rohit Gupta committed
890
  int i;
891

892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
#ifdef DEADLINE_SCHEDULER

  struct sched_attr attr;
  unsigned int flags = 0;

  attr.size = sizeof(attr);
  attr.sched_flags = 0;
  attr.sched_nice = 0;
  attr.sched_priority = 0;//sched_get_priority_max(SCHED_DEADLINE);

  // This creates a .5 ms  reservation
  attr.sched_policy = SCHED_DEADLINE;
  attr.sched_runtime  = 100000;
  attr.sched_deadline = 500000;
  attr.sched_period   = 500000;

  if (sched_setattr(0, &attr, flags) < 0 ) {
    perror("[SCHED] main eNB thread: sched_setattr failed\n");
    exit_fun("Nothing to add");
    return &UE_thread_retval;
  }
  LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %lu started on CPU %d\n",
        (unsigned long)gettid(), sched_getcpu());

#else
  struct sched_param sp;
  sp.sched_priority = sched_get_priority_max(SCHED_FIFO);
  pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp);
#endif

  // Lock memory from swapping. This is a process wide call (not constraint to this thread).
  mlockall(MCL_CURRENT | MCL_FUTURE);

  printf("waiting for sync (UE_thread)\n");
  pthread_mutex_lock(&sync_mutex);
  printf("Locked sync_mutex, waiting (UE_thread)\n");

  while (sync_var<0)
    pthread_cond_wait(&sync_cond, &sync_mutex);

  pthread_mutex_unlock(&sync_mutex);
  printf("unlocked sync_mutex, waiting (UE_thread)\n");

  printf("starting UE thread\n");

#ifdef NAS_UE
  message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE);
  itti_send_msg_to_task (TASK_NAS_UE, INSTANCE_DEFAULT, message_p);
#endif 

  while (!oai_exit) {
    
    if (UE->is_synchronized == 0) {
      
946
      if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) {
947
948
949
950
951
	LOG_E( PHY, "[SCHED][UE] verror locking mutex for UE initial synch thread\n" );
	exit_fun("nothing to add");
	return &UE_thread_retval;
      }
      
952
      int instance_cnt_synch = UE->proc.instance_cnt_synch;
953
      
954
      if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) {
955
956
957
958
959
960
961
962
	LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE initial synch thread\n" );
	exit_fun("nothing to add");
	return &UE_thread_retval;
      }
      
      if (instance_cnt_synch < 0) {  // we can invoke the synch
	// grab 10 ms of signal and wakeup synch thread
	for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
963
	  rxp[i] = (void*)&UE->common_vars.rxdata[i][0];
964
965
      
	if (UE->mode != loop_through_memory) {
knopp's avatar
knopp committed
966
967
968
969
970
	  rxs = UE->rfdevice.trx_read_func(&UE->rfdevice,
					   &timestamp,
					   rxp,
					   UE->frame_parms.samples_per_tti*10,
					   UE->frame_parms.nb_antennas_rx);
971
	  
knopp's avatar
knopp committed
972
973
	  
	  if (rxs!=UE->frame_parms.samples_per_tti*10) {
974
	    LOG_E(PHY, "problem in rx 1! expect #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti*10, rxs);
975
	    exit_fun("problem in rx 1");
knopp's avatar
knopp committed
976
977
	    return &UE_thread_retval;
	  }
978
	}
knopp's avatar
knopp committed
979

980
	instance_cnt_synch = ++UE->proc.instance_cnt_synch;
981
	if (instance_cnt_synch == 0) {
982
	  if (pthread_cond_signal(&UE->proc.cond_synch) != 0) {
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
	    LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE sync thread\n" );
	    exit_fun("nothing to add");
	    return &UE_thread_retval;
	  }
	} else {
	  LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" );
	  exit_fun("nothing to add");
	  return &UE_thread_retval;
	}
      } // 
      else {
	// grab 10 ms of signal into dummy buffer

	if (UE->mode != loop_through_memory) {
	  for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
	    rxp[i] = (void*)&dummy_rx[i][0];
999
	  for (int sf=0;sf<10;sf++) {
1000
	    //	    printf("Reading dummy sf %d\n",sf);
knopp's avatar
knopp committed
1001
1002
1003
1004
1005
	    rxs = UE->rfdevice.trx_read_func(&UE->rfdevice,
					     &timestamp,
					     rxp,
					     UE->frame_parms.samples_per_tti,
					     UE->frame_parms.nb_antennas_rx);
knopp's avatar
knopp committed
1006
1007

	    if (rxs!=UE->frame_parms.samples_per_tti){
1008
	      LOG_E(PHY, "problem in rx 2! expect #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti, rxs);
1009
	      exit_fun("problem in rx 2");
knopp's avatar
knopp committed
1010
1011
1012
	      return &UE_thread_retval;
	    }

1013
	  }
1014
1015
1016
	}
      }
      
1017
    } // UE->is_synchronized==0
1018
    else {
1019
1020
1021
      if (start_rx_stream==0) {
	start_rx_stream=1;
	if (UE->mode != loop_through_memory) {
1022
1023

	  if (UE->no_timing_correction==0) {
Rohit Gupta's avatar
Rohit Gupta committed
1024
	    LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
1025
1026
	    rxs = UE->rfdevice.trx_read_func(&UE->rfdevice,
					     &timestamp,
1027
					     (void**)UE->common_vars.rxdata,
1028
1029
1030
					     UE->rx_offset,
					     UE->frame_parms.nb_antennas_rx);
	    if (rxs != UE->rx_offset) {
1031
	      LOG_E(PHY, "problem in rx 3! expect #samples=%d but got only %d!\n", UE->rx_offset, rxs);
1032
	      exit_fun("problem in rx 3!");
1033
1034
	      return &UE_thread_retval;
	    }
1035
1036
	  }
	  UE->rx_offset=0;
1037
1038
1039
1040
	  UE->proc.proc_rxtx[0].frame_rx++;
	  UE->proc.proc_rxtx[1].frame_rx++;

	  // read in first symbol
knopp's avatar
knopp committed
1041
1042
	  rxs = UE->rfdevice.trx_read_func(&UE->rfdevice,
					   &timestamp,
1043
					   (void**)UE->common_vars.rxdata,
knopp's avatar
knopp committed
1044
1045
					   UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0,
					   UE->frame_parms.nb_antennas_rx);
1046
    if (rxs != (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0)) {
1047
      LOG_E(PHY, "problem in rx 4! expect #samples=%d but got only %d!\n", UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, rxs);
1048
1049
1050
      exit_fun("problem in rx 4!");
      return &UE_thread_retval;
    }
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
	  slot_fep(UE,
		   0,
		   0,
		   0,
		   0,
		   0);
	  if (rxs != UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0) {
	    exit_fun("problem in rx");
	    return &UE_thread_retval;
	  }
1061
1062
1063
	} //UE->mode != loop_through_memory
	else
	  rt_sleep_ns(1000000);
1064

1065
      }// start_rx_stream==0
1066
      else {
fnabet's avatar
fnabet committed
1067
1068
	//UE->proc.proc_rxtx[0].frame_rx++;
	//UE->proc.proc_rxtx[1].frame_rx++;
Rohit Gupta's avatar
Rohit Gupta committed
1069
	
1070
	for (int sf=0;sf<10;sf++) {
Rohit Gupta's avatar
Rohit Gupta committed
1071
	  for (i=0; i<UE->frame_parms.nb_antennas_rx; i++) 
1072
	    rxp[i] = (void*)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0+(sf*UE->frame_parms.samples_per_tti)];
1073
1074
1075
	  // grab signal for subframe
	  if (UE->mode != loop_through_memory) {
	    if (sf<9) {
1076
	      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
knopp's avatar
knopp committed
1077
1078
1079
1080
1081
	      rxs = UE->rfdevice.trx_read_func(&UE->rfdevice,
					       &timestamp,
					       rxp,
					       UE->frame_parms.samples_per_tti,
					       UE->frame_parms.nb_antennas_rx);
1082
1083
	      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
	      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS, rxs );
1084
	      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS_MISSING, UE->frame_parms.samples_per_tti - rxs);
1085
	      if (rxs != UE->frame_parms.samples_per_tti) {
1086
	        LOG_E(PHY, "problem in rx 5! expect #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti, rxs);
1087
1088
1089
	        exit_fun("problem in rx 5!");
	        return &UE_thread_retval;
	      }
Rohit Gupta's avatar
Rohit Gupta committed
1090