oaisim.c 64.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*******************************************************************************

  Eurecom OpenAirInterface
  Copyright(c) 1999 - 2014 Eurecom

  This program is free software; you can redistribute it and/or modify it
  under the terms and conditions of the GNU General Public License,
  version 2, as published by the Free Software Foundation.

  This program is distributed in the hope 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.

  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

  The full GNU General Public License is included in this distribution in
  the file called "COPYING".

  Contact Information
  Openair Admin: openair_admin@eurecom.fr
  Openair Tech : openair_tech@eurecom.fr
  Forums       : http://forums.eurecom.fsr/openairinterface
  Address      : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France

*******************************************************************************/

30
31
32
33
34
35
36
37
38
39
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <cblas.h>
#include <execinfo.h>

40
#include "event_handler.h"
41
42
43
44
45
46
47
#include "SIMULATION/RF/defs.h"
#include "PHY/types.h"
#include "PHY/defs.h"
#include "PHY/LTE_TRANSPORT/proto.h"
#include "PHY/vars.h"
#include "MAC_INTERFACE/vars.h"

Cedric Roux's avatar
Cedric Roux committed
48
49
#include "SIMULATION/ETH_TRANSPORT/proto.h"

50
51
//#ifdef OPENAIR2
#include "LAYER2/MAC/defs.h"
52
#include "LAYER2/MAC/proto.h"
53
#include "LAYER2/MAC/vars.h"
54
#include "pdcp.h"
55
56
57
58
59
#ifndef CELLULAR
#include "RRC/LITE/vars.h"
#endif
#include "PHY_INTERFACE/vars.h"
//#endif
60
#include "RRC/NAS/nas_config.h"
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

#include "ARCH/CBMIMO1/DEVICE_DRIVER/vars.h"

#ifdef IFFT_FPGA
//#include "PHY/LTE_REFSIG/mod_table.h"
#endif //IFFT_FPGA
#include "SCHED/defs.h"
#include "SCHED/vars.h"

#ifdef XFORMS
#include "PHY/TOOLS/lte_phy_scope.h"
#endif

#ifdef SMBV
#include "PHY/TOOLS/smbv.h"
gauthier's avatar
gauthier committed
76
char           smbv_fname[] = "smbv_config_file.smbv";
77
78
unsigned short smbv_nframes = 4; // how many frames to configure 1,..,4
unsigned short config_frames[4] = {2,9,11,13};
gauthier's avatar
gauthier committed
79
unsigned char  smbv_frame_cnt = 0;
gauthier's avatar
gauthier committed
80
uint8_t             config_smbv = 0;
gauthier's avatar
gauthier committed
81
char           smbv_ip[16];
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#endif

#include "oaisim_functions.h"

#include "oaisim.h"
#include "oaisim_config.h"
#include "UTIL/OCG/OCG_extern.h"
#include "cor_SF_sim.h"
#include "UTIL/OMG/omg_constants.h"
#include "UTIL/FIFO/pad_list.h"

//#ifdef PROC
#include "../PROC/interface.h"
#include "../PROC/channel_sim_proc.h"
#include "../PROC/Tsync.h"
#include "../PROC/Process.h"
//#endif

#include "UTIL/LOG/vcd_signal_dumper.h"
101
#include "UTIL/OTG/otg_kpi.h"
102
#include "assertions.h"
103
104

#if defined(ENABLE_ITTI)
105
# include "intertask_interface.h"
106
# include "create_tasks.h"
107
#endif
108

gauthier's avatar
gauthier committed
109
110
111
#define RF                    1
#define MCS_COUNT             24 /*added for PHY abstraction */
#define N_TRIALS              1
112
113

/*
114
115
116
117
 DCI0_5MHz_TDD0_t          UL_alloc_pdu;
 DCI1A_5MHz_TDD_1_6_t      CCCH_alloc_pdu;
 DCI2_5MHz_2A_L10PRB_TDD_t DLSCH_alloc_pdu1;
 DCI2_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu2;
118
119
 */

gauthier's avatar
gauthier committed
120
121
122
123
#define UL_RB_ALLOC            computeRIV(lte_frame_parms->N_RB_UL,0,24)
#define CCCH_RB_ALLOC          computeRIV(lte_frame_parms->N_RB_UL,0,3)
#define RA_RB_ALLOC            computeRIV(lte_frame_parms->N_RB_UL,0,3)
#define DLSCH_RB_ALLOC         0x1fff
124

gauthier's avatar
gauthier committed
125
126
#define DECOR_DIST             100
#define SF_VAR                 10
127
128

//constant for OAISIM soft realtime calibration
129
130
131
132
//#define SF_DEVIATION_OFFSET_NS 100000        /*= 0.1ms : should be as a number of UE */
//#define SLEEP_STEP_US          100           /*  = 0.01ms could be adaptive, should be as a number of UE */
//#define K                      2             /* averaging coefficient */
//#define TARGET_SF_TIME_NS      1000000       /* 1ms = 1000000 ns */
gauthier's avatar
gauthier committed
133
134
135
136
137

frame_t                frame = 0;
char                   stats_buffer[16384];
channel_desc_t        *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX];
channel_desc_t        *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX];
138
//Added for PHY abstraction
gauthier's avatar
gauthier committed
139
140
node_desc_t           *enb_data[NUMBER_OF_eNB_MAX];
node_desc_t           *ue_data[NUMBER_OF_UE_MAX];
141
// Added for PHY abstraction
142
143
extern node_list*       ue_node_list;
extern node_list*       enb_node_list;
gauthier's avatar
gauthier committed
144
145
146
147
148
149
150
extern int             pdcp_period, omg_period;

extern double        **s_re, **s_im, **r_re, **r_im, **r_re0, **r_im0;
int                    map1, map2;
extern double        **ShaF;
double                 snr_dB, sinr_dB, snr_direction; //,sinr_direction;
extern double          snr_step;
gauthier's avatar
gauthier committed
151
152
153
154
155
156
157
158
159
160
extern uint8_t              set_sinr;
extern uint8_t              ue_connection_test;
extern uint8_t              set_seed;
uint8_t                     cooperation_flag; // for cooperative communication
extern uint8_t              target_dl_mcs;
extern uint8_t              target_ul_mcs;
uint8_t                     rate_adaptation_flag;
extern uint8_t              abstraction_flag;
extern uint8_t              ethernet_flag;
extern uint16_t             Nid_cell;
161

162
163
164
165
166
167
extern LTE_DL_FRAME_PARMS *frame_parms;

#ifdef XFORMS
int otg_enabled;
#endif

168
169
170
171
172
time_stats_t oaisim_stats;
time_stats_t oaisim_stats_f;
time_stats_t dl_chan_stats;
time_stats_t ul_chan_stats;

173
// this should reflect the channel models in openair1/SIMULATION/TOOLS/defs.h
174
mapping small_scale_names[] = {
gauthier's avatar
gauthier committed
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
    {"custom", custom},
    {"SCM_A", SCM_A},
    {"SCM_B", SCM_B},
    {"SCM_C", SCM_C},
    {"SCM_D", SCM_D},
    {"EPA", EPA},
    {"EVA", EVA},
    {"ETU", ETU},
    {"MBSFN", MBSFN},
    {"Rayleigh8", Rayleigh8},
    {"Rayleigh1", Rayleigh1},
    {"Rayleigh1_800", Rayleigh1_800},
    {"Rayleigh1_corr", Rayleigh1_corr},
    {"Rayleigh1_anticorr", Rayleigh1_anticorr},
    {"Rice8", Rice8},
    {"Rice1", Rice1},
    {"Rice1_corr", Rice1_corr},
    {"Rice1_anticorr", Rice1_anticorr},
    {"AWGN", AWGN},
    {NULL, -1}
195
};
196
197
198
199
#if !defined(ENABLE_ITTI)
static void *sigh(void *arg);
#endif
void oai_shutdown(void);
200

201
void help(void) {
202
  printf ("Usage: oaisim -h -a -F -C tdd_config -K [log_file] -V [vcd_file] -R N_RB_DL -e -x transmission_mode -m target_dl_mcs -r(ate_adaptation) -n n_frames -s snr_dB -k ricean_factor -t max_delay -f forgetting factor -A channel_model -z cooperation_flag -u nb_local_ue -U UE mobility -b nb_local_enb -B eNB_mobility -M ethernet_flag -p nb_master -g multicast_group -l log_level -c ocg_enable -T traffic model -D multicast network device\n");
203
204
205

  printf ("-h provides this help message!\n");
  printf ("-a Activates PHY abstraction mode\n");
206
  printf ("-A set the multipath channel simulation,  options are: SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr,Rayleigh1_anticorr, Rice8,, Rice1, AWGN \n");
207
208
  printf ("-b Set the number of local eNB\n");
  printf ("-B Set the mobility model for eNB, options are: STATIC, RWP, RWALK, \n");
209
  printf ("-c [1,2,3,4] Activate the config generator (OCG) to process the scenario descriptor, or give the scenario manually: -c template_1.xml \n");
210
211
  printf ("-C [0-6] Sets TDD configuration\n");
  printf ("-e Activates extended prefix mode\n");
212
  printf ("-E Random number generator seed\n");
213
214
215
216
  printf ("-f Set the forgetting factor for time-variation\n");
  printf ("-F Activates FDD transmission (TDD is default)\n");
  printf ("-g Set multicast group ID (0,1,2,3) - valid if M is set\n");
  printf ("-G Enable background traffic \n");
217
  printf ("-H Enable handover operation (default disabled) \n");
218
219
  printf ("-I Enable CLI interface (to connect use telnet localhost 1352)\n");
  printf ("-k Set the Ricean factor (linear)\n");
220
  printf ("-K [log_file] Enable ITTI logging into log_file\n");
221
222
  printf ("-l Set the global log level (8:trace, 7:debug, 6:info, 4:warn, 3:error) \n");
  printf ("-L [0-1] 0 to disable new link adaptation, 1 to enable new link adapatation\n");
223
  printf ("-m Gives a fixed DL mcs for eNB scheduler\n");
224
225
  printf ("-M Set the machine ID for Ethernet-based emulation\n");
  printf ("-n Set the number of frames for the simulation\n");
226
  printf ("-O [enb_conf_file] eNB configuration file name\n");
227
228
229
230
231
  printf ("-p Set the total number of machine in emulation - valid if M is set\n");
  printf ("-P [trace type] Enable protocol analyzer. Possible values for OPT:\n");
  printf ("    - wireshark: Enable tracing of layers above PHY using an UDP socket\n");
  printf ("    - pcap:      Enable tracing of layers above PHY to a pcap file\n");
  printf ("    - tshark:    Not implemented yet\n");
232
  printf ("-q Enable Openair performance profiler \n");
233
  printf ("-Q Activate and set the MBMS service: 0 : not used (default eMBMS disabled), 1: eMBMS and RRC Connection enabled, 2: eMBMS relaying and RRC Connection enabled, 3: eMBMS enabled, RRC Connection disabled, 4: eMBMS relaying enabled, RRC Connection disabled\n");
234
235
236
237
  printf ("-R [6,15,25,50,75,100] Sets N_RB_DL\n");
  printf ("-r Activates rate adaptation (DL for now)\n");
  printf ("-s snr_dB set a fixed (average) SNR, this deactivates the openair channel model generator (OCM)\n");
  printf ("-S snir_dB set a fixed (average) SNIR, this deactivates the openair channel model generator (OCM)\n");
238
  printf ("-t Gives a fixed UL mcs for eNB scheduler\n");
239
  printf ("-T activate the traffic generator: cbr, scbr, mcbr, bcbr, mscbr\n");
240
  printf ("-u Set the number of local UE\n");
241
242
  printf ("-U Set the mobility model for UE, options are: STATIC, RWP, RWALK\n");
  printf ("-V [vcd_file] Enable VCD dump into vcd_file\n");
243
  printf ("-w number of CBA groups, if not specified or zero, CBA is inactive\n");
244
  printf ("-W IP address to connect to SMBV and configure SMBV from config file. Requires compilation with SMBV=1, -W0 uses default IP 192.168.12.201\n");
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
  printf ("-x Set the transmission mode (1,2,5,6 supported for now)\n");
  printf ("-Y Set the global log verbosity (none, low, medium, high, full) \n");
  printf ("-z Set the cooperation flag (0 for no cooperation, 1 for delay diversity and 2 for distributed alamouti\n");
  printf ("-Z Reserved\n");
}

pthread_t log_thread;

void log_thread_init() {
  //create log_list
  //log_list_init(&log_list);
#ifndef LOG_NO_THREAD

  log_shutdown = 0;

260
  if ((pthread_mutex_init (&log_lock, NULL) != 0) || (pthread_cond_init (&log_notify, NULL) != 0)) {
gauthier's avatar
gauthier committed
261
      return;
262
263
  }

264
  if (pthread_create (&log_thread, NULL, log_thread_function, (void*) NULL) != 0) {
gauthier's avatar
gauthier committed
265
266
      log_thread_finalize ();
      return;
267
268
269
270
271
272
273
274
275
276
277
  }
#endif

}

//Call it after the last LOG call
int log_thread_finalize() {
  int err = 0;

#ifndef LOG_NO_THREAD

278
  if (pthread_mutex_lock (&log_lock) != 0) {
gauthier's avatar
gauthier committed
279
      return -1;
280
281
282
283
284
  }

  log_shutdown = 1;

  /* Wake up LOG thread */
285
  if ((pthread_cond_broadcast (&log_notify) != 0) || (pthread_mutex_unlock (&log_lock) != 0)) {
gauthier's avatar
gauthier committed
286
      err = -1;
287
  }
288
  if (pthread_join (log_thread, NULL) != 0) {
gauthier's avatar
gauthier committed
289
      err = -1;
290
  }
291
  if (pthread_mutex_unlock (&log_lock) != 0) {
gauthier's avatar
gauthier committed
292
      err = -1;
293
294
  }

295
  if (!err) {
gauthier's avatar
gauthier committed
296
297
298
299
      //log_list_free(&log_list);
      pthread_mutex_lock (&log_lock);
      pthread_mutex_destroy (&log_lock);
      pthread_cond_destroy (&log_notify);
300
  }
Cedric Roux's avatar
Cedric Roux committed
301
302
#endif

303
304
305
  return err;
}

306
#if defined(ENABLE_ITTI)
gauthier's avatar
gauthier committed
307
308
309
static void set_cli_start(module_id_t module_idP, uint8_t start) {
  if (module_idP < NB_eNB_INST) {
      oai_emulation.info.cli_start_enb[module_idP] = start;
310
  } else {
gauthier's avatar
gauthier committed
311
      oai_emulation.info.cli_start_ue[module_idP - NB_eNB_INST] = start;
312
313
314
315
  }
}
#endif

316
#ifdef OPENAIR2
317
int omv_write(int pfd, node_list* enb_node_list, node_list* ue_node_list, Data_Flow_Unit omv_data) {
gauthier's avatar
gauthier committed
318
  module_id_t i, j;
319
  omv_data.end = 0;
320
  //omv_data.total_num_nodes = NB_UE_INST + NB_eNB_INST;
321
  for (i = 0; i < NB_eNB_INST; i++) {
gauthier's avatar
gauthier committed
322
      if (enb_node_list != NULL) {
323
324
          omv_data.geo[i].x = (enb_node_list->node->x_pos < 0.0) ? 0.0 : enb_node_list->node->x_pos;
          omv_data.geo[i].y = (enb_node_list->node->y_pos < 0.0) ? 0.0 : enb_node_list->node->y_pos;
gauthier's avatar
gauthier committed
325
326
327
328
329
330
331
332
333
334
335
336
337
338
          omv_data.geo[i].z = 1.0;
          omv_data.geo[i].mobility_type = oai_emulation.info.omg_model_enb;
          omv_data.geo[i].node_type = 0; //eNB
          enb_node_list = enb_node_list->next;
          omv_data.geo[i].Neighbors = 0;
          for (j = NB_eNB_INST; j < NB_UE_INST + NB_eNB_INST; j++) {
              if (is_UE_active (i, j - NB_eNB_INST) == 1) {
                  omv_data.geo[i].Neighbor[omv_data.geo[i].Neighbors] = j;
                  omv_data.geo[i].Neighbors++;
                  LOG_D(
                      OMG,
                      "[eNB %d][UE %d] is_UE_active(i,j) %d geo (x%d, y%d) num neighbors %d\n", i, j-NB_eNB_INST, is_UE_active(i,j-NB_eNB_INST), omv_data.geo[i].x, omv_data.geo[i].y, omv_data.geo[i].Neighbors);
              }
          }
339
      }
340
  }
341
  for (i = NB_eNB_INST; i < NB_UE_INST + NB_eNB_INST; i++) {
gauthier's avatar
gauthier committed
342
      if (ue_node_list != NULL) {
343
344
          omv_data.geo[i].x = (ue_node_list->node->x_pos < 0.0) ? 0.0 : ue_node_list->node->x_pos;
          omv_data.geo[i].y = (ue_node_list->node->y_pos < 0.0) ? 0.0 : ue_node_list->node->y_pos;
gauthier's avatar
gauthier committed
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
          omv_data.geo[i].z = 1.0;
          omv_data.geo[i].mobility_type = oai_emulation.info.omg_model_ue;
          omv_data.geo[i].node_type = 1; //UE
          //trial
          omv_data.geo[i].state = 1;
          omv_data.geo[i].rnti = 88;
          omv_data.geo[i].connected_eNB = 0;
          omv_data.geo[i].RSRP = 66;
          omv_data.geo[i].RSRQ = 55;
          omv_data.geo[i].Pathloss = 44;
          omv_data.geo[i].RSSI[0] = 33;
          omv_data.geo[i].RSSI[1] = 22;
          if ((sizeof(omv_data.geo[0].RSSI) / sizeof(omv_data.geo[0].RSSI[0])) > 2)
            {
              omv_data.geo[i].RSSI[2] = 11;
            }
361

gauthier's avatar
gauthier committed
362
363
364
365
366
367
368
369
370
371
372
          ue_node_list = ue_node_list->next;
          omv_data.geo[i].Neighbors = 0;
          for (j = 0; j < NB_eNB_INST; j++) {
              if (is_UE_active (j, i - NB_eNB_INST) == 1) {
                  omv_data.geo[i].Neighbor[omv_data.geo[i].Neighbors] = j;
                  omv_data.geo[i].Neighbors++;
                  LOG_D(
                      OMG,
                      "[UE %d][eNB %d] is_UE_active  %d geo (x%d, y%d) num neighbors %d\n", i-NB_eNB_INST, j, is_UE_active(j,i-NB_eNB_INST), omv_data.geo[i].x, omv_data.geo[i].y, omv_data.geo[i].Neighbors);
              }
          }
373
374
      }
  }
375
376
377
  LOG_E(OMG, "pfd %d \n", pfd);
  if (write (pfd, &omv_data, sizeof(struct Data_Flow_Unit)) == -1)
    perror ("write omv failed");
378
379
380
  return 1;
}

381
382
383
384
void omv_end(int pfd, Data_Flow_Unit omv_data) {
  omv_data.end = 1;
  if (write (pfd, &omv_data, sizeof(struct Data_Flow_Unit)) == -1)
    perror ("write omv failed");
385
386
387
}
#endif 

388
#ifdef OPENAIR2
389
390
int pfd[2]; // fd for omv : fixme: this could be a local var
#endif
391

392
393
394
#ifdef OPENAIR2
static Data_Flow_Unit omv_data;
#endif //ALU
gauthier's avatar
gauthier committed
395
396
static module_id_t UE_inst  = 0;
static module_id_t eNB_inst = 0;
397
#ifdef Rel10
398
static module_id_t RN_id    = 0;
399
#endif
400

gauthier's avatar
gauthier committed
401
Packet_OTG_List_t *otg_pdcp_buffer;
402
403
404

typedef enum l2l1_task_state_e
{
gauthier's avatar
gauthier committed
405
406
407
  L2L1_WAITTING,
  L2L1_RUNNING,
  L2L1_TERMINATED,
408
409
} l2l1_task_state_t;

410
411
l2l1_task_state_t     l2l1_state = L2L1_WAITTING;

412
/*------------------------------------------------------------------------------*/
413
void *l2l1_task(void *args_p) {
414
  
gauthier's avatar
gauthier committed
415
  clock_t               t;
416

417
  // Framing variables
gauthier's avatar
gauthier committed
418
  int32_t                   slot, last_slot, next_slot;
419

420
#ifdef Rel10
gauthier's avatar
gauthier committed
421
  relaying_type_t       r_type = no_relay; // no relaying
422
#endif
423

gauthier's avatar
gauthier committed
424
  lte_subframe_t        direction;
425

gauthier's avatar
gauthier committed
426
  char                  fname[64], vname[64];
knopp's avatar
   
knopp committed
427
  int sf;
428
429
430
431

#ifdef XFORMS
  // 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 
gauthier's avatar
gauthier committed
432
  FD_lte_phy_scope_ue  *form_ue[NUMBER_OF_UE_MAX];
433
  FD_lte_phy_scope_enb *form_enb[NUMBER_OF_UE_MAX];
gauthier's avatar
gauthier committed
434
435
436
437
  char                  title[255];
  char                  xname[32]                  = "oaisim";
  int                   xargc                      = 1;
  char                 *xargv[1];
438
439
440
#endif

#ifdef PRINT_STATS
gauthier's avatar
gauthier committed
441
442
443
444
445
446
447
448
449
450
  int                   len;
  FILE                 *UE_stats[NUMBER_OF_UE_MAX];
  FILE                 *UE_stats_th[NUMBER_OF_UE_MAX];
  FILE                 *eNB_stats[NUMBER_OF_eNB_MAX];
  FILE                 *eNB_avg_thr;
  FILE                 *eNB_l2_stats;
  char                  UE_stats_filename[255];
  char                  eNB_stats_filename[255];
  char                  UE_stats_th_filename[255];
  char                  eNB_stats_th_filename[255];
451
452
#endif

knopp's avatar
   
knopp committed
453
454
455
456
  for (eNB_inst=0;eNB_inst<NB_eNB_INST;eNB_inst++) {
    for (sf=0;sf<10;sf++) {
      PHY_vars_eNB_g[eNB_inst]->proc[sf].frame_tx = 0;
      PHY_vars_eNB_g[eNB_inst]->proc[sf].frame_rx = 0;
knopp's avatar
   
knopp committed
457
458
      PHY_vars_eNB_g[eNB_inst]->proc[sf].subframe_tx = (sf+1)%10;
      PHY_vars_eNB_g[eNB_inst]->proc[sf].subframe_rx = (sf+9)%10;
knopp's avatar
   
knopp committed
459
460
461
462
    }
    PHY_vars_eNB_g[eNB_inst]->proc[0].frame_rx = 1023;
    PHY_vars_eNB_g[eNB_inst]->proc[9].frame_tx = 1;
  }
463
464
465
#ifdef XFORMS
  xargv[0] = xname;
  fl_initialize (&xargc, xargv, NULL, 0, 0);
466
467
  eNB_inst = 0;
  for (UE_inst = 0; UE_inst < NB_UE_INST; UE_inst++) {
gauthier's avatar
gauthier committed
468
      // DL scope at UEs
469
470
471
      form_ue[UE_inst] = create_lte_phy_scope_ue();
      sprintf (title, "LTE DL SCOPE eNB %d to UE %d", eNB_inst, UE_inst);
      fl_show_form (form_ue[UE_inst]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
gauthier's avatar
gauthier committed
472
473

      // UL scope at eNB 0
474
475
476
      form_enb[UE_inst] = create_lte_phy_scope_enb();
      sprintf (title, "LTE UL SCOPE UE %d to eNB %d", UE_inst, eNB_inst);
      fl_show_form (form_enb[UE_inst]->lte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
gauthier's avatar
gauthier committed
477
478

      if (openair_daq_vars.use_ia_receiver == 1) {
479
480
481
          fl_set_button(form_ue[UE_inst]->button_0,1);
          fl_set_object_label(form_ue[UE_inst]->button_0, "IA Receiver ON");
          fl_set_object_color(form_ue[UE_inst]->button_0, FL_GREEN, FL_GREEN);
gauthier's avatar
gauthier committed
482
      }
483
484
485
486
487

  }
#endif

#ifdef PRINT_STATS
488
489
490
  for (UE_inst=0;UE_inst<NB_UE_INST;UE_inst++) {
      sprintf(UE_stats_filename,"UE_stats%d.txt",UE_inst);
      UE_stats[UE_inst] = fopen (UE_stats_filename, "w");
491
  }
492
493
494
  for (eNB_inst=0;eNB_inst<NB_eNB_INST;eNB_inst++) {
      sprintf(eNB_stats_filename,"eNB_stats%d.txt",eNB_inst);
      eNB_stats[eNB_inst] = fopen (eNB_stats_filename, "w");
495
496
497
  }

  if(abstraction_flag==0) {
498
499
500
      for (UE_inst=0;UE_inst<NB_UE_INST;UE_inst++) {
          sprintf(UE_stats_th_filename,"UE_stats_th%d_tx%d.txt",UE_inst,oai_emulation.info.transmission_mode);
          UE_stats_th[UE_inst] = fopen (UE_stats_th_filename, "w");
gauthier's avatar
gauthier committed
501
502
503
      }
      sprintf(eNB_stats_th_filename,"eNB_stats_th_tx%d.txt",oai_emulation.info.transmission_mode);
      eNB_avg_thr = fopen (eNB_stats_th_filename, "w");
504
505
  }
  else {
506
507
508
      for (UE_inst=0;UE_inst<NB_UE_INST;UE_inst++) {
          sprintf(UE_stats_th_filename,"UE_stats_abs_th%d_tx%d.txt",UE_inst,oai_emulation.info.transmission_mode);
          UE_stats_th[UE_inst] = fopen (UE_stats_th_filename, "w");
gauthier's avatar
gauthier committed
509
510
511
      }
      sprintf(eNB_stats_th_filename,"eNB_stats_abs_th_tx%d.txt",oai_emulation.info.transmission_mode);
      eNB_avg_thr = fopen (eNB_stats_th_filename, "w");
512
513
514
515
516
517
518
519
  }
#ifdef OPENAIR2
  eNB_l2_stats = fopen ("eNB_l2_stats.txt", "w");
  LOG_I(EMU,"eNB_l2_stats=%p\n", eNB_l2_stats);
#endif 

#endif

520
#if defined(ENABLE_ITTI)
521
  MessageDef   *message_p = NULL;
gauthier's avatar
   
gauthier committed
522
  const char   *msg_name  = NULL;
523
  int           result;
524

525
  itti_mark_task_ready (TASK_L2L1);
526
  LOG_I(EMU, "TASK_L2L1 is READY\n");
527

528
  if (oai_emulation.info.nb_enb_local > 0) {
gauthier's avatar
gauthier committed
529
530
531
532
533
534
535
      /* Wait for the initialize message */
      do {
          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);
          }
          itti_receive_msg (TASK_L2L1, &message_p);
gauthier's avatar
   
gauthier committed
536
537
          msg_name = ITTI_MSG_NAME (message_p);
          LOG_I(EMU, "TASK_L2L1 received %s in state L2L1_WAITTING\n", msg_name);
538

gauthier's avatar
gauthier committed
539
540
541
542
          switch (ITTI_MSG_ID(message_p)) {
          case INITIALIZE_MESSAGE:
            l2l1_state = L2L1_RUNNING;
            break;
543

544
545
546
547
548
549
550
551
          case ACTIVATE_MESSAGE:
            set_cli_start(ITTI_MSG_INSTANCE (message_p), 1);
            break;

          case DEACTIVATE_MESSAGE:
            set_cli_start(ITTI_MSG_INSTANCE (message_p), 0);
            break;

552
          case TERMINATE_MESSAGE:
553
            l2l1_state = L2L1_TERMINATED;
554
555
556
            break;

          default:
Cedric Roux's avatar
Cedric Roux committed
557
            LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
558
            break;
gauthier's avatar
gauthier committed
559
560
561
562
563
564
          }
      } while (l2l1_state == L2L1_WAITTING);
      result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
      AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
  }
#endif
565
  start_meas(&oaisim_stats);
gauthier's avatar
gauthier committed
566
567
  for (frame = 0; (l2l1_state != L2L1_TERMINATED) && (frame < oai_emulation.info.n_frames); frame++) {

568
569
    start_meas(&oaisim_stats_f);

gauthier's avatar
gauthier committed
570
571
572
573
574
575
#if defined(ENABLE_ITTI)
      do {
          // Checks if a message has been sent to L2L1 task
          itti_poll_msg (TASK_L2L1, &message_p);

          if (message_p != NULL) {
gauthier's avatar
   
gauthier committed
576
577
              msg_name = ITTI_MSG_NAME (message_p);
              LOG_I(EMU, "TASK_L2L1 received %s\n", msg_name);
gauthier's avatar
gauthier committed
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
              switch (ITTI_MSG_ID(message_p)) {
              case ACTIVATE_MESSAGE:
                set_cli_start(ITTI_MSG_INSTANCE (message_p), 1);
                break;

              case DEACTIVATE_MESSAGE:
                set_cli_start(ITTI_MSG_INSTANCE (message_p), 0);
                break;

              case TERMINATE_MESSAGE:
                l2l1_state = L2L1_TERMINATED;
                break;

              case MESSAGE_TEST:
                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(message_p != NULL);
604
#endif
605
606
607
608
609
      
      //Run the aperiodic user-defined events
      if (oai_emulation.info.oeh_enabled == 1)
	execute_events(frame);
           
gauthier's avatar
gauthier committed
610
      /*
611
612
613
614
615
616
     // Handling the cooperation Flag
     if (cooperation_flag == 2)
     {
     if ((PHY_vars_eNB_g[0]->eNB_UE_stats[0].mode == PUSCH) && (PHY_vars_eNB_g[0]->eNB_UE_stats[1].mode == PUSCH))
     PHY_vars_eNB_g[0]->cooperation_flag = 2;
     }
gauthier's avatar
gauthier committed
617
618
619
620
621
622
623
624
625
626
627
628
629
       */
      if (ue_connection_test == 1) {
          if ((frame % 20) == 0) {
              snr_dB += snr_direction;
              sinr_dB -= snr_direction;
          }
          if (snr_dB == -20) {
              snr_direction = snr_step;
          }
          else
            if (snr_dB == 20) {
                snr_direction = -snr_step;
            }
630
631
      }

gauthier's avatar
gauthier committed
632
633
      oai_emulation.info.frame = frame;
      //oai_emulation.info.time_ms += 1;
634
      oai_emulation.info.time_s += 0.01; // emu time in s, each frame lasts for 10 ms // JNote: TODO check the coherency of the time and frame (I corrected it to 10 (instead of 0.01)
gauthier's avatar
gauthier committed
635
636
637
638
      // if n_frames not set by the user or is greater than max num frame then set adjust the frame counter
      if ((oai_emulation.info.n_frames_flag == 0) || (oai_emulation.info.n_frames >= 0xffff)) {
          frame %= (oai_emulation.info.n_frames - 1);
      }
639

gauthier's avatar
gauthier committed
640
      update_omg (frame); // frequency is defined in the omg_global params configurable by the user
641

gauthier's avatar
gauthier committed
642
      update_omg_ocm ();
643
644

#ifdef OPENAIR2
gauthier's avatar
gauthier committed
645
646
647
648
      // check if pipe is still open
      if ((oai_emulation.info.omv_enabled == 1)) {
          omv_write (pfd[1], enb_node_list, ue_node_list, omv_data);
      }
649
#endif
650
#ifdef DEBUG_OMG
651
/*
gauthier's avatar
gauthier committed
652
      if ((((int) oai_emulation.info.time_s) % 100) == 0) {
653
654
          for (UE_inst = oai_emulation.info.first_ue_local; UE_inst < (oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local); UE_inst++) {
              get_node_position (UE, UE_inst);
gauthier's avatar
gauthier committed
655
          }
656
      }
657
*/
658
659
#endif

gauthier's avatar
gauthier committed
660
      update_ocm ();
661

gauthier's avatar
gauthier committed
662
      for (slot = 0; slot < 20; slot++) {
663
	
gauthier's avatar
gauthier committed
664
          wait_for_slot_isr ();
665

winckel's avatar
winckel committed
666
#if defined(ENABLE_ITTI)
gauthier's avatar
gauthier committed
667
          itti_update_lte_time(frame, slot);
winckel's avatar
winckel committed
668
#endif
669

gauthier's avatar
gauthier committed
670
671
672
673
          last_slot = (slot - 1) % 20;
          if (last_slot < 0)
            last_slot += 20;
          next_slot = (slot + 1) % 20;
674

gauthier's avatar
gauthier committed
675
          oai_emulation.info.time_ms = frame * 10 + (slot >> 1);
676

gauthier's avatar
gauthier committed
677
          direction = subframe_select (frame_parms, next_slot >> 1);
678

679
#ifdef PROC
gauthier's avatar
gauthier committed
680
681
          if(Channel_Flag==1)
            Channel_Func(s_re2,s_im2,r_re2,r_im2,r_re02,r_im02,r_re0_d,r_im0_d,r_re0_u,r_im0_u,eNB2UE,UE2eNB,enb_data,ue_data,abstraction_flag,frame_parms,slot);
682

gauthier's avatar
gauthier committed
683
          if(Channel_Flag==0)
684
#endif
gauthier's avatar
gauthier committed
685
            {
686
#if defined(ENABLE_ITTI)
gauthier's avatar
gauthier committed
687
              log_set_instance_type (LOG_INSTANCE_ENB);
688
689
#endif

gauthier's avatar
gauthier committed
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
              if ((next_slot % 2) == 0)
                clear_eNB_transport_info (oai_emulation.info.nb_enb_local);

              for (eNB_inst = oai_emulation.info.first_enb_local; (eNB_inst < (oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local)); eNB_inst++) {
                  if (oai_emulation.info.cli_start_enb[eNB_inst] != 0) {
                      LOG_D(
                          EMU,
                          "PHY procedures eNB %d for frame %d, slot %d (subframe TX %d, RX %d) TDD %d/%d Nid_cell %d\n",
                          eNB_inst,
                          frame,
                          slot,
                          next_slot >> 1,
                          last_slot>>1,
                          PHY_vars_eNB_g[eNB_inst]->lte_frame_parms.frame_type,
                          PHY_vars_eNB_g[eNB_inst]->lte_frame_parms.tdd_config,
                          PHY_vars_eNB_g[eNB_inst]->lte_frame_parms.Nid_cell);
706

707
#ifdef OPENAIR2
gauthier's avatar
gauthier committed
708
709
                      //Appliation: traffic gen
                      update_otg_eNB (eNB_inst, oai_emulation.info.time_ms);
710

gauthier's avatar
gauthier committed
711
712
                      //IP/OTG to PDCP and PDCP to IP operation
                      pdcp_run (frame, 1, 0, eNB_inst); //PHY_vars_eNB_g[eNB_id]->Mod_id
713
#endif
714

gauthier's avatar
gauthier committed
715
                      // PHY_vars_eNB_g[eNB_id]->frame = frame;
knopp's avatar
   
knopp committed
716
717
                      if ((slot&1) == 0) 
			phy_procedures_eNB_lte (slot>>1,PHY_vars_eNB_g[eNB_inst], abstraction_flag, no_relay, NULL);
718
719

#ifdef PRINT_STATS
gauthier's avatar
gauthier committed
720
721
722
723
724
725
726
727
728
                      if(last_slot==9 && frame%10==0)
                        if(eNB_avg_thr)
                          fprintf(eNB_avg_thr,"%d %d\n",PHY_vars_eNB_g[eNB_inst]->frame,(PHY_vars_eNB_g[eNB_inst]->total_system_throughput)/((PHY_vars_eNB_g[eNB_inst]->frame+1)*10));
                      if (eNB_stats[eNB_inst]) {
                          len = dump_eNB_stats(PHY_vars_eNB_g[eNB_inst], stats_buffer, 0);
                          rewind (eNB_stats[eNB_inst]);
                          fwrite (stats_buffer, 1, len, eNB_stats[eNB_inst]);
                          fflush(eNB_stats[eNB_inst]);
                      }
729
#ifdef OPENAIR2
gauthier's avatar
gauthier committed
730
731
732
733
734
735
                      if (eNB_l2_stats) {
                          len = dump_eNB_l2_stats (stats_buffer, 0);
                          rewind (eNB_l2_stats);
                          fwrite (stats_buffer, 1, len, eNB_l2_stats);
                          fflush(eNB_l2_stats);
                      }
736
#endif
737
#endif
gauthier's avatar
gauthier committed
738
739
740
741
                  }
              }
              // Call ETHERNET emulation here
              //emu_transport (frame, last_slot, next_slot, direction, oai_emulation.info.frame_type, ethernet_flag);
742

743
#if defined(ENABLE_ITTI)
gauthier's avatar
gauthier committed
744
              log_set_instance_type (LOG_INSTANCE_UE);
745
746
#endif

gauthier's avatar
gauthier committed
747
748
749
750
751
              if ((next_slot % 2) == 0)
                clear_UE_transport_info (oai_emulation.info.nb_ue_local);
              for (UE_inst = oai_emulation.info.first_ue_local;
                  (UE_inst < (oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local)); UE_inst++) {
                  if (oai_emulation.info.cli_start_ue[UE_inst] != 0) {
752
#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
gauthier's avatar
gauthier committed
753

754
#else
gauthier's avatar
gauthier committed
755
                      if (frame >= (UE_inst * 20))  // activate UE only after 20*UE_id frames so that different UEs turn on separately
756
#endif
gauthier's avatar
gauthier committed
757
758
759
760
761
762
763
764
765
766
767
768
                        {
                          LOG_D(EMU, "PHY procedures UE %d for frame %d, slot %d (subframe TX %d, RX %d)\n",
                              UE_inst,
                              frame,
                              slot,
                              next_slot >> 1,
                              last_slot>>1);

                          if (PHY_vars_UE_g[UE_inst]->UE_mode[0] != NOT_SYNCHED) {
                              if (frame > 0) {
                                  PHY_vars_UE_g[UE_inst]->frame = frame;

769
#ifdef OPENAIR2
gauthier's avatar
gauthier committed
770
771
772
773
774
                                  //Application
                                  update_otg_UE (UE_inst, oai_emulation.info.time_ms);

                                  //Access layer
                                  pdcp_run (frame, 0, UE_inst, 0);
775
#endif
gauthier's avatar
gauthier committed
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792

                                  phy_procedures_UE_lte (last_slot, next_slot, PHY_vars_UE_g[UE_inst], 0, abstraction_flag, normal_txrx,
                                      no_relay, NULL);
                                  ue_data[UE_inst]->tx_power_dBm = PHY_vars_UE_g[UE_inst]->tx_power_dBm;
                              }
                          }
                          else {
                              if (abstraction_flag == 1) {
                                  LOG_E(
                                      EMU,
                                      "sync not supported in abstraction mode (UE%d,mode%d)\n", UE_inst, PHY_vars_UE_g[UE_inst]->UE_mode[0]);
                                  exit (-1);
                              }
                              if ((frame > 0) && (last_slot == (LTE_SLOTS_PER_FRAME - 2))) {
                                  initial_sync (PHY_vars_UE_g[UE_inst], normal_txrx);

                                  /*
793
794
795
796
797
798
799
800
801
802
803
                   write_output("dlchan00.m","dlch00",&(PHY_vars_UE_g[0]->lte_ue_common_vars.dl_ch_estimates[0][0][0]),(6*(PHY_vars_UE_g[0]->lte_frame_parms.ofdm_symbol_size)),1,1);
                   if (PHY_vars_UE_g[0]->lte_frame_parms.nb_antennas_rx>1)
                   write_output("dlchan01.m","dlch01",&(PHY_vars_UE_g[0]->lte_ue_common_vars.dl_ch_estimates[0][1][0]),(6*(PHY_vars_UE_g[0]->lte_frame_parms.ofdm_symbol_size)),1,1);
                   write_output("dlchan10.m","dlch10",&(PHY_vars_UE_g[0]->lte_ue_common_vars.dl_ch_estimates[0][2][0]),(6*(PHY_vars_UE_g[0]->lte_frame_parms.ofdm_symbol_size)),1,1);
                   if (PHY_vars_UE_g[0]->lte_frame_parms.nb_antennas_rx>1)
                   write_output("dlchan11.m","dlch11",&(PHY_vars_UE_g[0]->lte_ue_common_vars.dl_ch_estimates[0][3][0]),(6*(PHY_vars_UE_g[0]->lte_frame_parms.ofdm_symbol_size)),1,1);
                   write_output("rxsig.m","rxs",PHY_vars_UE_g[0]->lte_ue_common_vars.rxdata[0],PHY_vars_UE_g[0]->lte_frame_parms.samples_per_tti*10,1,1);
                   write_output("rxsigF.m","rxsF",PHY_vars_UE_g[0]->lte_ue_common_vars.rxdataF[0],2*PHY_vars_UE_g[0]->lte_frame_parms.symbols_per_tti*PHY_vars_UE_g[0]->lte_frame_parms.ofdm_symbol_size,2,1);
                   write_output("pbch_rxF_ext0.m","pbch_ext0",PHY_vars_UE_g[0]->lte_ue_pbch_vars[0]->rxdataF_ext[0],6*12*4,1,1);
                   write_output("pbch_rxF_comp0.m","pbch_comp0",PHY_vars_UE_g[0]->lte_ue_pbch_vars[0]->rxdataF_comp[0],6*12*4,1,1);
                   write_output("pbch_rxF_llr.m","pbch_llr",PHY_vars_UE_g[0]->lte_ue_pbch_vars[0]->llr,(frame_parms->Ncp==0) ? 1920 : 1728,1,4);
gauthier's avatar
gauthier committed
804
805
806
                                   */
                              }
                          }
807
#ifdef PRINT_STATS
gauthier's avatar
gauthier committed
808
809
810
811
812
813
814
815
816
817
818
                          if(last_slot==2 && frame%10==0) {
                              if (UE_stats_th[UE_inst]) {
                                  fprintf(UE_stats_th[UE_inst],"%d %d\n",frame, PHY_vars_UE_g[UE_inst]->bitrate[0]/1000);
                              }
                          }
                          if (UE_stats[UE_inst]) {
                              len = dump_ue_stats (PHY_vars_UE_g[UE_inst], stats_buffer, 0, normal_txrx, 0);
                              rewind (UE_stats[UE_inst]);
                              fwrite (stats_buffer, 1, len, UE_stats[UE_inst]);
                              fflush(UE_stats[UE_inst]);
                          }
819
#endif
gauthier's avatar
gauthier committed
820
821
                        }
                  }
822
              }
gauthier's avatar
gauthier committed
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
#ifdef Rel10
              for (RN_id=oai_emulation.info.first_rn_local;
                  RN_id<oai_emulation.info.first_rn_local+oai_emulation.info.nb_rn_local;
                  RN_id++) {
                  // UE id and eNB id of the RN
                  UE_inst= oai_emulation.info.first_ue_local+oai_emulation.info.nb_ue_local + RN_id;// NB_UE_INST + RN_id
                  eNB_inst= oai_emulation.info.first_enb_local+oai_emulation.info.nb_enb_local + RN_id;// NB_eNB_INST + RN_id
                  // currently only works in FDD
                  if (oai_emulation.info.eMBMS_active_state == 4) {
                      r_type = multicast_relay;
                      //LOG_I(EMU,"Activating the multicast relaying\n");
                  }
                  else {
                      LOG_E(EMU,"Not supported eMBMS option when relaying is enabled %d\n", r_type);
                      exit(-1);
                  }
                  PHY_vars_RN_g[RN_id]->frame = frame;
                  if ( oai_emulation.info.frame_type == 0) {
                      // RN == UE
                      if (frame>0) {
843
                          if (PHY_vars_UE_g[UE_inst]->UE_mode[0] != NOT_SYNCHED) {
gauthier's avatar
gauthier committed
844
                              LOG_D(EMU,"[RN %d] PHY procedures UE %d for frame %d, slot %d (subframe TX %d, RX %d)\n",
845
846
847
                                  RN_id, UE_inst, frame, slot, next_slot >> 1,last_slot>>1);
                              PHY_vars_UE_g[UE_inst]->frame = frame;
                              phy_procedures_UE_lte (last_slot, next_slot, PHY_vars_UE_g[UE_inst], 0, abstraction_flag,normal_txrx,
gauthier's avatar
gauthier committed
848
849
850
                                  r_type, PHY_vars_RN_g[RN_id]);
                          }
                          else if (last_slot == (LTE_SLOTS_PER_FRAME-2)) {
851
                              initial_sync(PHY_vars_UE_g[UE_inst],normal_txrx);
gauthier's avatar
gauthier committed
852
853
854
855
                          }
                      }
                      // RN == eNB
                      LOG_D(EMU,"[RN %d] PHY procedures eNB %d for frame %d, slot %d (subframe TX %d, RX %d)\n",
856
                          RN_id, eNB_inst, frame, slot, next_slot >> 1,last_slot>>1);
knopp's avatar
   
knopp committed
857
                      phy_procedures_eNB_lte(slot>>1, PHY_vars_eNB_g[eNB_inst], abstraction_flag,
gauthier's avatar
gauthier committed
858
859
860
861
862
863
                          r_type, PHY_vars_RN_g[RN_id]);
                  }
                  else {
                      LOG_E(EMU,"TDD is not supported for multicast relaying %d\n", r_type);
                      exit(-1);
                  }
864
              }
865
#endif
gauthier's avatar
gauthier committed
866
867
868
869
              emu_transport (frame, last_slot, next_slot, direction, oai_emulation.info.frame_type, ethernet_flag);
              if ((direction == SF_DL) || (frame_parms->frame_type == 0)) {
                  // consider only sec id 0
                  /*  for (eNB_id=0;eNB_id<NB_eNB_INST;eNB_id++) {
870
871
872
873
874
875
876
           if (abstraction_flag == 0) {
           do_OFDM_mod(PHY_vars_eNB_g[eNB_id]->lte_eNB_common_vars.txdataF[0],
           PHY_vars_eNB_g[eNB_id]->lte_eNB_common_vars.txdata[0],
           frame,next_slot,
           frame_parms);
           }
           }*/
877
878
879
                  start_meas(&dl_chan_stats);
		  for (UE_inst = 0; UE_inst < NB_UE_INST; UE_inst++) {
                      do_DL_sig (r_re0, r_im0, r_re, r_im, s_re, s_im, eNB2UE, enb_data, ue_data, next_slot, abstraction_flag,frame_parms, UE_inst);
gauthier's avatar
gauthier committed
880
                  }
881
		  stop_meas(&dl_chan_stats);
gauthier's avatar
gauthier committed
882
883
              }
              if ((direction == SF_UL) || (frame_parms->frame_type == 0)) { //if ((subframe<2) || (subframe>4))
884
885
886
                   start_meas(&ul_chan_stats);
		   do_UL_sig (r_re0, r_im0, r_re, r_im, s_re, s_im, UE2eNB, enb_data, ue_data, next_slot, abstraction_flag,frame_parms, frame); 
		   stop_meas(&ul_chan_stats);
gauthier's avatar
gauthier committed
887
                  /*
888
889
890
891
892
893
894
           int ccc;
           fprintf(SINRpost,"SINRdb For eNB New Subframe : \n ");
           for(ccc = 0 ; ccc<301; ccc++)
           {
           fprintf(SINRpost,"_ %f ", SINRpost_eff[ccc]);
           }
           fprintf(SINRpost,"SINRdb For eNB : %f \n ", SINRpost_eff[ccc]);
gauthier's avatar
gauthier committed
895
896
897
898
899
                   */
              }
              if ((direction == SF_S)) { //it must be a special subframe
                  if (next_slot % 2 == 0) { //DL part
                      /*  for (eNB_id=0;eNB_id<NB_eNB_INST;eNB_id++) {
900
901
902
903
904
905
             if (abstraction_flag == 0) {
             do_OFDM_mod(PHY_vars_eNB_g[eNB_id]->lte_eNB_common_vars.txdataF[0],
             PHY_vars_eNB_g[eNB_id]->lte_eNB_common_vars.txdata[0],
             frame,next_slot,
             frame_parms);
             }
906
907
908
909
910
911
             }*/ 
		    start_meas(&dl_chan_stats);
		    for (UE_inst = 0; UE_inst < NB_UE_INST; UE_inst++) {
		      do_DL_sig (r_re0, r_im0, r_re, r_im, s_re, s_im, eNB2UE, enb_data, ue_data, next_slot, abstraction_flag,frame_parms, UE_inst);
		    }
		    stop_meas(&dl_chan_stats);
gauthier's avatar
gauthier committed
912
                      /*
913
914
915
916
             for (aarx=0;aarx<UE2eNB[1][0]->nb_rx;aarx++)
             for (aatx=0;aatx<UE2eNB[1][0]->nb_tx;aatx++)
             for (k=0;k<UE2eNB[1][0]->channel_length;k++)
             printf("SB(%d,%d,%d)->(%f,%f)\n",k,aarx,aatx,UE2eNB[1][0]->ch[aarx+(aatx*UE2eNB[1][0]->nb_rx)][k].r,UE2eNB[1][0]->ch[aarx+(aatx*UE2eNB[1][0]->nb_rx)][k].i);
gauthier's avatar
gauthier committed
917
918
919
                       */
                  }
                  else { // UL part
920
921
922
		    start_meas(&ul_chan_stats);
                      do_UL_sig (r_re0, r_im0, r_re, r_im, s_re, s_im, UE2eNB, enb_data, ue_data, next_slot, abstraction_flag,frame_parms, frame);
		      stop_meas(&ul_chan_stats);
923

gauthier's avatar
gauthier committed
924
                      /*        int ccc;
925
926
927
928
929
930
931
             fprintf(SINRpost,"SINRdb For eNB New Subframe : \n ");
             for(ccc = 0 ; ccc<301; ccc++)
             {
             fprintf(SINRpost,"_ %f ", SINRpost_eff[ccc]);
             }
             fprintf(SINRpost,"SINRdb For eNB : %f \n ", SINRpost_eff[ccc]);
             }
gauthier's avatar
gauthier committed
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
                       */}
              }
              if ((last_slot == 1) && (frame == 0) && (abstraction_flag == 0) && (oai_emulation.info.n_frames == 1)) {

                  write_output ("dlchan0.m", "dlch0", &(PHY_vars_UE_g[0]->lte_ue_common_vars.dl_ch_estimates[0][0][0]),
                      (6 * (PHY_vars_UE_g[0]->lte_frame_parms.ofdm_symbol_size)), 1, 1);
                  write_output ("dlchan1.m", "dlch1", &(PHY_vars_UE_g[0]->lte_ue_common_vars.dl_ch_estimates[1][0][0]),
                      (6 * (PHY_vars_UE_g[0]->lte_frame_parms.ofdm_symbol_size)), 1, 1);
                  write_output ("dlchan2.m", "dlch2", &(PHY_vars_UE_g[0]->lte_ue_common_vars.dl_ch_estimates[2][0][0]),
                      (6 * (PHY_vars_UE_g[0]->lte_frame_parms.ofdm_symbol_size)), 1, 1);
                  write_output ("pbch_rxF_comp0.m", "pbch_comp0", PHY_vars_UE_g[0]->lte_ue_pbch_vars[0]->rxdataF_comp[0],
                      6 * 12 * 4, 1, 1);
                  write_output ("pbch_rxF_llr.m", "pbch_llr", PHY_vars_UE_g[0]->lte_ue_pbch_vars[0]->llr,
                      (frame_parms->Ncp == 0) ? 1920 : 1728, 1, 4);
              }
              /*
948
949
950
951
         if ((last_slot==1) && (frame==1)) {
         write_output("dlsch_rxF_comp0.m","dlsch0_rxF_comp0",PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp[0],300*(-(PHY_vars_UE->lte_frame_parms.Ncp*2)+14),1,1);
         write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1);
         }
gauthier's avatar
gauthier committed
952
               */
953
      } // if Channel_Flag==0
gauthier's avatar
gauthier committed
954
955
956
957

      } //end of slot

      if ((frame >= 1) && (frame <= 9) && (abstraction_flag == 0)
958
#ifdef PROC
gauthier's avatar
gauthier committed
959
          &&(Channel_Flag==0)
960
#endif
gauthier's avatar
gauthier committed
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
      ) {
          write_output ("UEtxsig0.m", "txs0", PHY_vars_UE_g[0]->lte_ue_common_vars.txdata[0], FRAME_LENGTH_COMPLEX_SAMPLES,
              1, 1);
          sprintf (fname, "eNBtxsig%d.m", frame);
          sprintf (vname, "txs%d", frame);
          write_output (fname, vname, PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][0], FRAME_LENGTH_COMPLEX_SAMPLES, 1,
              1);
          write_output (
              "eNBtxsigF0.m", "txsF0", PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdataF[0][0],
              PHY_vars_eNB_g[0]->lte_frame_parms.symbols_per_tti * PHY_vars_eNB_g[0]->lte_frame_parms.ofdm_symbol_size, 1,
              1);

          write_output ("UErxsig0.m", "rxs0", PHY_vars_UE_g[0]->lte_ue_common_vars.rxdata[0], FRAME_LENGTH_COMPLEX_SAMPLES,
              1, 1);
          write_output ("eNBrxsig0.m", "rxs0", PHY_vars_eNB_g[0]->lte_eNB_common_vars.rxdata[0][0],
              FRAME_LENGTH_COMPLEX_SAMPLES, 1, 1);
      }
978
979

#ifdef XFORMS
980
981
982
983
984
985
      eNB_inst = 0;
      for (UE_inst = 0; UE_inst < NB_UE_INST; UE_inst++) {
          phy_scope_UE(form_ue[UE_inst],
              PHY_vars_UE_g[UE_inst],
              eNB_inst,
              UE_inst,
gauthier's avatar
gauthier committed
986
987
              7);

988
989
990
          phy_scope_eNB(form_enb[UE_inst],
              PHY_vars_eNB_g[eNB_inst],
              UE_inst);
991

gauthier's avatar
gauthier committed
992
      }
993
#endif
994
995

#ifdef SMBV
gauthier's avatar
gauthier committed
996
997
998
      if ((frame == config_frames[0]) || (frame == config_frames[1]) || (frame == config_frames[2]) || (frame == config_frames[3])) {
          smbv_frame_cnt++;
      }
999
#endif
1000
      stop_meas(&oaisim_stats_f);
1001
1002
  } //end of frame

1003
1004
  stop_meas(&oaisim_stats);

1005
1006
1007
1008
#if defined(ENABLE_ITTI)
  itti_terminate_tasks(TASK_L2L1);
#endif

1009
#ifdef PRINT_STATS
1010
1011
1012
1013
1014
  for (UE_inst=0;UE_inst<NB_UE_INST;UE_inst++) {
      if (UE_stats[UE_inst])
        fclose (UE_stats[UE_inst]);
      if(UE_stats_th[UE_inst])
        fclose (UE_stats_th[UE_inst]);
1015
  }
1016
1017
1018
  for (eNB_inst=0;eNB_inst<NB_eNB_INST;eNB_inst++) {
      if (eNB_stats[eNB_inst])
        fclose (eNB_stats[eNB_inst]);
1019
1020
  }
  if (eNB_avg_thr)
gauthier's avatar
gauthier committed
1021
    fclose (eNB_avg_thr);
1022
  if (eNB_l2_stats)
gauthier's avatar
gauthier committed
1023
    fclose (eNB_l2_stats);
1024
1025
1026

#endif

1027
1028
1029
  return NULL;
}

1030
/*------------------------------------------------------------------------------*/
1031
1032
int main(int argc, char **argv) {

gauthier's avatar
gauthier committed
1033
  int32_t i;
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
  // pointers signal buffers (s = transmit, r,r0 = receive)
  clock_t t;

  //FILE *SINRpost;
  //char SINRpost_fname[512];
  // sprintf(SINRpost_fname,"postprocSINR.m");
  //SINRpost = fopen(SINRpost_fname,"w");
  // variables/flags which are set by user on command-line

#ifdef SMBV
  strcpy(smbv_ip,DEFAULT_SMBV_IP);
#endif

  // time calibration for soft realtime mode  
1048
1049
  char pbch_file_path[512];
  FILE *pbch_file_fd;
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073

#ifdef PROC
  int node_id;
  int port,Process_Flag=0,wgt,Channel_Flag=0,temp;
#endif
  //double **s_re2[MAX_eNB+MAX_UE], **s_im2[MAX_eNB+MAX_UE], **r_re2[MAX_eNB+MAX_UE], **r_im2[MAX_eNB+MAX_UE], **r_re02, **r_im02;
  //double **r_re0_d[MAX_UE][MAX_eNB], **r_im0_d[MAX_UE][MAX_eNB], **r_re0_u[MAX_eNB][MAX_UE],**r_im0_u[MAX_eNB][MAX_UE];
  //default parameters
  rate_adaptation_flag = 0;
  oai_emulation.info.n_frames = 0xffff; //1024;          //10;
  oai_emulation.info.n_frames_flag = 0; //fixme
  snr_dB = 30;
  cooperation_flag = 0; // default value 0 for no cooperation, 1 for Delay diversity, 2 for Distributed Alamouti

  //Default values if not changed by the user in get_simulation_options();
  pdcp_period = 1;
  omg_period = 1;
  // start thread for log gen
  log_thread_init ();

  init_oai_emulation (); // to initialize everything !!!

  // get command-line options
  get_simulation_options (argc, argv); //Command-line options
gauthier's avatar
gauthier committed
1074

1075
  // Initialize VCD LOG module
1076
  vcd_signal_dumper_init (oai_emulation.info.vcd_file);
1077

1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
#if !defined(ENABLE_ITTI)
  pthread_t tid;
  int err;
  sigset_t sigblock;
  sigemptyset(&sigblock);
  sigaddset(&sigblock, SIGHUP);
  sigaddset(&sigblock, SIGINT);
  sigaddset(&sigblock, SIGTERM);
  sigaddset(&sigblock, SIGQUIT);
  //sigaddset(&sigblock, SIGKILL);
 
  if ((err= pthread_sigmask(SIG_BLOCK, &sigblock, NULL)) != 0){
    printf("SIG_BLOCK error\n");
    return -1;
  }
  if (pthread_create(&tid, NULL, sigh, NULL)) {
    printf("Pthread for tracing Signals is not created!\n");
    return -1;
  } else {
    printf("Pthread for tracing Signals is created!\n");
  }
#endif 
1100
1101
1102
1103
  // configure oaisim with OCG
  oaisim_config (); // config OMG and OCG, OPT, OTG, OLG

  if (ue_connection_test == 1) {
gauthier's avatar
gauthier committed
1104
1105
1106
      snr_direction = -snr_step;
      snr_dB = 20;
      sinr_dB = -20;
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
  }

#ifdef OPENAIR2
  init_omv ();
#endif
  //Before this call, NB_UE_INST and NB_eNB_INST are not set correctly
  check_and_adjust_params ();

  set_seed = oai_emulation.emulation_config.seed.value;

  init_otg_pdcp_buffer ();

  init_seed (set_seed);

  init_openair1 ();

  init_openair2 ();

  init_ocm ();

#ifdef SMBV
  smbv_init_config(smbv_fname, smbv_nframes);
  smbv_write_config_from_frame_parms(smbv_fname, &PHY_vars_eNB_g[0]->lte_frame_parms);
#endif
1131
  // add events to future event list: Currently not used
1132
	//oai_emulation.info.oeh_enabled = 1;
1133
1134
1135
  if (oai_emulation.info.oeh_enabled == 1)
    schedule_events();

1136
1137
1138
1139
  // oai performance profiler is enabled 
  if (oai_emulation.info.opp_enabled == 1)
    reset_opp_meas();
  
1140
1141
1142
1143
1144
  init_time ();

  init_slot_isr ();

  t = clock ();
gauthier's avatar
gauthier committed
1145

nikaeinn's avatar
nikaeinn committed
1146
  LOG_N(EMU, ">>>>>>>>>>>>>>>>>>>>>>>>>>> OAIEMU initialization done <<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");
1147
1148
1149

#if defined(ENABLE_ITTI)
  // Handle signals until all tasks are terminated
1150
  if (create_tasks(oai_emulation.info.nb_enb_local, oai_emulation.info.nb_ue_local) >= 0) {
gauthier's avatar
gauthier committed
1151
      itti_wait_tasks_end();
1152
  } else {
gauthier's avatar
gauthier committed
1153
      exit(-1); // need a softer mode
1154
  }
1155
#else