oaisim.c 62.8 KB
Newer Older
1
/*******************************************************************************
2 3
    OpenAirInterface 
    Copyright(c) 1999 - 2014 Eurecom
4

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


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

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

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

knopp's avatar
 
knopp committed
28
*******************************************************************************/
29

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

/*
knopp's avatar
 
knopp committed
114 115 116 117 118
  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;
*/
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

frame_t                frame = 0;
char                   stats_buffer[16384];
knopp's avatar
 
knopp committed
136 137
channel_desc_t        *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs];
channel_desc_t        *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
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

knopp's avatar
 
knopp committed
162
extern LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs];
163 164 165 166 167

#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[] = {
knopp's avatar
 
knopp 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)) {
knopp's avatar
 
knopp committed
261
    return;
262 263
  }

264
  if (pthread_create (&log_thread, NULL, log_thread_function, (void*) NULL) != 0) {
knopp's avatar
 
knopp 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) {
knopp's avatar
 
knopp 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)) {
knopp's avatar
 
knopp committed
286
    err = -1;
287
  }
288
  if (pthread_join (log_thread, NULL) != 0) {
knopp's avatar
 
knopp committed
289
    err = -1;
290
  }
291
  if (pthread_mutex_unlock (&log_lock) != 0) {
knopp's avatar
 
knopp committed
292
    err = -1;
293 294
  }

295
  if (!err) {
knopp's avatar
 
knopp 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
static void set_cli_start(module_id_t module_idP, uint8_t start) {
  if (module_idP < NB_eNB_INST) {
knopp's avatar
 
knopp committed
309
    oai_emulation.info.cli_start_enb[module_idP] = start;
310
  } else {
knopp's avatar
 
knopp 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++) {
knopp's avatar
 
knopp committed
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
    if (enb_node_list != NULL) {
      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;
      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);
	}
338
      }
knopp's avatar
 
knopp committed
339
    }
340
  }
341
  for (i = NB_eNB_INST; i < NB_UE_INST + NB_eNB_INST; i++) {
knopp's avatar
 
knopp committed
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
    if (ue_node_list != NULL) {
      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;
      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;
	}

      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);
	}
372
      }
knopp's avatar
 
knopp committed
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

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

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;
knopp's avatar
 
knopp committed
416
  int CC_id;
417

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

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

gauthier's avatar
gauthier committed
425
  lte_subframe_t        direction;
426

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

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

#ifdef PRINT_STATS
gauthier's avatar
gauthier committed
442 443 444 445 446 447 448 449 450 451
  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];
452 453
#endif

knopp's avatar
 
knopp committed
454 455 456 457 458 459 460 461 462 463
  for (CC_id = 0;CC_id<MAX_NUM_CCs;CC_id++)
    for (eNB_inst=0;eNB_inst<NB_eNB_INST;eNB_inst++) {
      for (sf=0;sf<10;sf++) {
	PHY_vars_eNB_g[eNB_inst][CC_id]->proc[sf].frame_tx = 0;
	PHY_vars_eNB_g[eNB_inst][CC_id]->proc[sf].frame_rx = 0;
	PHY_vars_eNB_g[eNB_inst][CC_id]->proc[sf].subframe_tx = (sf+1)%10;
	PHY_vars_eNB_g[eNB_inst][CC_id]->proc[sf].subframe_rx = (sf+9)%10;
      }
      PHY_vars_eNB_g[eNB_inst][CC_id]->proc[0].frame_rx = 1023;
      PHY_vars_eNB_g[eNB_inst][CC_id]->proc[9].frame_tx = 1;
knopp's avatar
 
knopp committed
464
    }
465 466 467
#ifdef XFORMS
  xargv[0] = xname;
  fl_initialize (&xargc, xargv, NULL, 0, 0);
468 469
  eNB_inst = 0;
  for (UE_inst = 0; UE_inst < NB_UE_INST; UE_inst++) {
knopp's avatar
 
knopp committed
470 471 472 473 474 475 476 477 478 479 480 481 482 483 484
    // DL scope at UEs
    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);

    // UL scope at eNB 0
    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);

    if (openair_daq_vars.use_ia_receiver == 1) {
      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);
    }
485 486 487 488 489

  }
#endif

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

  if(abstraction_flag==0) {
knopp's avatar
 
knopp committed
500 501 502 503 504 505
    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");
    }
    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");
506 507
  }
  else {
knopp's avatar
 
knopp committed
508 509 510 511 512 513
    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");
    }
    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");
514 515 516 517 518 519 520 521
  }
#ifdef OPENAIR2
  eNB_l2_stats = fopen ("eNB_l2_stats.txt", "w");
  LOG_I(EMU,"eNB_l2_stats=%p\n", eNB_l2_stats);
#endif 

#endif

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

527
  itti_mark_task_ready (TASK_L2L1);
528
  LOG_I(EMU, "TASK_L2L1 is READY\n");
529

530
  if (oai_emulation.info.nb_enb_local > 0) {
knopp's avatar
 
knopp committed
531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564
    /* 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);
      msg_name = ITTI_MSG_NAME (message_p);
      LOG_I(EMU, "TASK_L2L1 received %s in state L2L1_WAITTING\n", msg_name);

      switch (ITTI_MSG_ID(message_p)) {
      case INITIALIZE_MESSAGE:
	l2l1_state = L2L1_RUNNING;
	break;

      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;

      default:
	LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
	break;
      }
    } 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);
gauthier's avatar
gauthier committed
565 566
  }
#endif
567
  start_meas(&oaisim_stats);
gauthier's avatar
gauthier committed
568 569
  for (frame = 0; (l2l1_state != L2L1_TERMINATED) && (frame < oai_emulation.info.n_frames); frame++) {

570 571
    start_meas(&oaisim_stats_f);

gauthier's avatar
gauthier committed
572
#if defined(ENABLE_ITTI)
knopp's avatar
 
knopp committed
573 574 575 576 577 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 604 605
    do {
      // Checks if a message has been sent to L2L1 task
      itti_poll_msg (TASK_L2L1, &message_p);

      if (message_p != NULL) {
	msg_name = ITTI_MSG_NAME (message_p);
	LOG_I(EMU, "TASK_L2L1 received %s\n", msg_name);
	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);
606
#endif
607
      
knopp's avatar
 
knopp committed
608 609 610
    //Run the aperiodic user-defined events
    if (oai_emulation.info.oeh_enabled == 1)
      execute_events(frame);
611
           
knopp's avatar
 
knopp committed
612 613 614 615 616 617 618 619 620 621 622 623
    /*
    // 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;
    }
    */
    if (ue_connection_test == 1) {
      if ((frame % 20) == 0) {
	snr_dB += snr_direction;
	sinr_dB -= snr_direction;
624
      }
knopp's avatar
 
knopp committed
625 626
      if (snr_dB == -20) {
	snr_direction = snr_step;
gauthier's avatar
gauthier committed
627
      }
knopp's avatar
 
knopp committed
628 629 630 631 632
      else
	if (snr_dB == 20) {
	  snr_direction = -snr_step;
	}
    }
633

knopp's avatar
 
knopp committed
634 635 636 637 638 639 640 641 642
    oai_emulation.info.frame = frame;
    //oai_emulation.info.time_ms += 1;
    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)
    // 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);
    }

    update_omg (frame); // frequency is defined in the omg_global params configurable by the user
643

knopp's avatar
 
knopp committed
644
    update_omg_ocm ();
645 646

#ifdef OPENAIR2
knopp's avatar
 
knopp committed
647 648 649 650
    // 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);
    }
651
#endif
652
#ifdef DEBUG_OMG
knopp's avatar
 
knopp committed
653
    /*
gauthier's avatar
gauthier committed
654
      if ((((int) oai_emulation.info.time_s) % 100) == 0) {
knopp's avatar
 
knopp committed
655 656
      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);
657
      }
knopp's avatar
 
knopp committed
658 659
      }
    */
660 661
#endif

knopp's avatar
 
knopp committed
662
    update_ocm ();
663

knopp's avatar
 
knopp committed
664
    for (slot = 0; slot < 20; slot++) {
665
	
knopp's avatar
 
knopp committed
666
      wait_for_slot_isr ();
667

winckel's avatar
winckel committed
668
#if defined(ENABLE_ITTI)
knopp's avatar
 
knopp committed
669
      itti_update_lte_time(frame, slot);
winckel's avatar
winckel committed
670
#endif
671

knopp's avatar
 
knopp committed
672 673 674 675
      last_slot = (slot - 1) % 20;
      if (last_slot < 0)
	last_slot += 20;
      next_slot = (slot + 1) % 20;
676

knopp's avatar
 
knopp committed
677
      oai_emulation.info.time_ms = frame * 10 + (slot >> 1);
678

knopp's avatar
 
knopp committed
679
      direction = subframe_select (frame_parms[0], next_slot >> 1);
680

681
#ifdef PROC
knopp's avatar
 
knopp committed
682 683
      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);
684

knopp's avatar
 
knopp committed
685
      if(Channel_Flag==0)
686
#endif
knopp's avatar
 
knopp committed
687
	{
688
#if defined(ENABLE_ITTI)
knopp's avatar
 
knopp committed
689
	  log_set_instance_type (LOG_INSTANCE_ENB);
690 691
#endif

692 693
	  //	  if ((next_slot % 2) == 0)  
	  if ((slot&1) == 0) 
knopp's avatar
 
knopp committed
694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710
	    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) {
	      if ((slot&1) == 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,
		      PHY_vars_eNB_g[eNB_inst][0]->proc[slot >> 1].subframe_tx,
		      PHY_vars_eNB_g[eNB_inst][0]->proc[slot >> 1].subframe_rx,
		      PHY_vars_eNB_g[eNB_inst][0]->lte_frame_parms.frame_type,
		      PHY_vars_eNB_g[eNB_inst][0]->lte_frame_parms.tdd_config,
		      PHY_vars_eNB_g[eNB_inst][0]->lte_frame_parms.Nid_cell);
		  
711
#ifdef OPENAIR2
knopp's avatar
 
knopp committed
712 713
	      //Appliation: traffic gen
	      update_otg_eNB (eNB_inst, oai_emulation.info.time_ms);
714

knopp's avatar
 
knopp committed
715 716
	      //IP/OTG to PDCP and PDCP to IP operation
	      pdcp_run (frame, 1, 0, eNB_inst); //PHY_vars_eNB_g[eNB_id]->Mod_id
717
#endif
718

knopp's avatar
 
knopp committed
719 720 721
	      // PHY_vars_eNB_g[eNB_id]->frame = frame;
	      if ((slot&1) == 0) 
		phy_procedures_eNB_lte (slot>>1,PHY_vars_eNB_g[eNB_inst], abstraction_flag, no_relay, NULL);
722 723

#ifdef PRINT_STATS
knopp's avatar
 
knopp committed
724 725 726 727 728 729 730 731 732 733
	      if(last_slot==9 && frame%10==0)
		if(eNB_avg_thr) 
		  fprintf(eNB_avg_thr,"%d %d\n",PHY_vars_eNB_g[eNB_inst]->proc[slot>>1].frame_tx,
			  (PHY_vars_eNB_g[eNB_inst]->total_system_throughput)/((PHY_vars_eNB_g[eNB_inst]->proc[slot>>1].frame_tx+1)*10));
	      if (eNB_stats[eNB_inst]) {
		len = dump_eNB_stats(PHY_vars_eNB_g[eNB_inst][0], stats_buffer, 0);
		rewind (eNB_stats[eNB_inst]);
		fwrite (stats_buffer, 1, len, eNB_stats[eNB_inst]);
		fflush(eNB_stats[eNB_inst]);
	      }
734
#ifdef OPENAIR2
knopp's avatar
 
knopp committed
735 736 737 738 739 740
	      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);
	      }
741
#endif
742
#endif
knopp's avatar
 
knopp committed
743 744
	    }
	  }
knopp's avatar
 
knopp committed
745
	    	    
knopp's avatar
 
knopp committed
746 747
	  // Call ETHERNET emulation here
	  //emu_transport (frame, last_slot, next_slot, direction, oai_emulation.info.frame_type, ethernet_flag);
748

749
#if defined(ENABLE_ITTI)
knopp's avatar
 
knopp committed
750
	  log_set_instance_type (LOG_INSTANCE_UE);
751 752
#endif

knopp's avatar
 
knopp committed
753
	  if ((next_slot % 2) == 0)
754
	  // if ((slot&1) == 0) 
knopp's avatar
 
knopp committed
755 756 757 758
	    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) {
759
#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
gauthier's avatar
gauthier committed
760

761
#else
knopp's avatar
 
knopp committed
762
	      if (frame >= (UE_inst * 20))  // activate UE only after 20*UE_id frames so that different UEs turn on separately
763
#endif
knopp's avatar
 
knopp committed
764 765 766 767 768 769 770 771 772 773
		{
		  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][0]->UE_mode[0] != NOT_SYNCHED) {
		    if (frame > 0) {
knopp's avatar
 
knopp committed
774 775 776 777 778 779 780
		      PHY_vars_UE_g[UE_inst][0]->frame_rx = frame;
		      PHY_vars_UE_g[UE_inst][0]->slot_rx = last_slot;
		      PHY_vars_UE_g[UE_inst][0]->slot_tx = next_slot;
		      if (next_slot > 1)
			PHY_vars_UE_g[UE_inst][0]->frame_tx = frame;
		      else
			PHY_vars_UE_g[UE_inst][0]->frame_tx = frame+1;
781
#ifdef OPENAIR2
knopp's avatar
 
knopp committed
782 783
		      //Application
		      update_otg_UE (UE_inst, oai_emulation.info.time_ms);
gauthier's avatar
gauthier committed
784

knopp's avatar
 
knopp committed
785 786
		      //Access layer
		      pdcp_run (frame, 0, UE_inst, 0);
787
#endif
knopp's avatar
 
knopp committed
788
		      for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
knopp's avatar
 
knopp committed
789
			phy_procedures_UE_lte (PHY_vars_UE_g[UE_inst][CC_id], 0, abstraction_flag, normal_txrx,
knopp's avatar
 
knopp committed
790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819
					       no_relay, NULL);
		      }
		      ue_data[UE_inst]->tx_power_dBm = PHY_vars_UE_g[UE_inst][0]->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][0]->UE_mode[0]);
		      exit (-1);
		    }
		    if ((frame > 0) && (last_slot == (LTE_SLOTS_PER_FRAME - 2))) {
		      initial_sync (PHY_vars_UE_g[UE_inst][0], normal_txrx);

		      /*
			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);
		      */
		    }
		  }
820
#ifdef PRINT_STATS
knopp's avatar
 
knopp committed
821 822 823 824 825 826 827 828 829 830 831
		  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][0]->bitrate[0]/1000);
		    }
		  }
		  if (UE_stats[UE_inst]) {
		    len = dump_ue_stats (PHY_vars_UE_g[UE_inst][0], 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]);
		  }
832
#endif
knopp's avatar
 
knopp committed
833 834 835 836
		}
	    }
	  }	       
    
gauthier's avatar
gauthier committed
837
#ifdef Rel10
knopp's avatar
 
knopp committed
838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859
	  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) {
		if (PHY_vars_UE_g[UE_inst][0]->UE_mode[0] != NOT_SYNCHED) {
		  LOG_D(EMU,"[RN %d] PHY procedures UE %d for frame %d, slot %d (subframe TX %d, RX %d)\n",
			RN_id, UE_inst, frame, slot, next_slot >> 1,last_slot>>1);
knopp's avatar
 
knopp committed
860 861 862 863 864 865
		  PHY_vars_UE_g[UE_inst][0]->frame_rx = frame;
		  PHY_vars_UE_g[UE_inst][0]->slot_rx =  last_slot;
		  PHY_vars_UE_g[UE_inst][0]->slot_tx =  next_slot;
		  if (next_slot>1) PHY_vars_UE_g[UE_inst][0]->frame_tx = frame;
		  else PHY_vars_UE_g[UE_inst][0]->frame_tx = frame+1;
		  phy_procedures_UE_lte (PHY_vars_UE_g[UE_inst][0], 0, abstraction_flag,normal_txrx,
knopp's avatar
 
knopp committed
866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882
					 r_type, PHY_vars_RN_g[RN_id]);
		}
		else if (last_slot == (LTE_SLOTS_PER_FRAME-2)) {
		  initial_sync(PHY_vars_UE_g[UE_inst][0],normal_txrx);
		}
	      }
	      // RN == eNB
	      LOG_D(EMU,"[RN %d] PHY procedures eNB %d for frame %d, slot %d (subframe TX %d, RX %d)\n",
		    RN_id, eNB_inst, frame, slot, next_slot >> 1,last_slot>>1);
	      phy_procedures_eNB_lte(slot>>1, PHY_vars_eNB_g[eNB_inst][0], abstraction_flag,
				     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);
	    }
	  }
883
#endif
knopp's avatar
 
knopp committed
884
	  emu_transport (frame, last_slot, next_slot, direction, oai_emulation.info.frame_type[0], ethernet_flag);
knopp's avatar
 
knopp committed
885
	  if ((direction == SF_DL) || (frame_parms[0]->frame_type == FDD)) {
knopp's avatar
 
knopp committed
886 887 888 889 890 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 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985
	    // consider only sec id 0
	    /*  for (eNB_id=0;eNB_id<NB_eNB_INST;eNB_id++) {
		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);
		}
		}*/
	    start_meas(&dl_chan_stats);
	    for (UE_inst = 0; UE_inst < NB_UE_INST; UE_inst++) 
	      for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
#warning figure out what to do with UE frame_parms during initial_sync
		do_DL_sig (r_re0, r_im0, r_re, r_im, s_re, s_im, eNB2UE, enb_data, ue_data, next_slot, abstraction_flag,&PHY_vars_eNB_g[0][CC_id]->lte_frame_parms,UE_inst,CC_id);
	      }
	    stop_meas(&dl_chan_stats);
	  }
	  if ((direction == SF_UL) || (frame_parms[0]->frame_type == 0)) { //if ((subframe<2) || (subframe>4))
	    start_meas(&ul_chan_stats);
	    for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
#warning figure out what to do with UE frame_parms during initial_sync
	      do_UL_sig (r_re0, r_im0, r_re, r_im, s_re, s_im, UE2eNB, enb_data, ue_data, next_slot, abstraction_flag,&PHY_vars_eNB_g[0][CC_id]->lte_frame_parms, frame,CC_id); 
	    }
	    stop_meas(&ul_chan_stats);
	    /*
	      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]);
	    */
	  }
	  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++) {
		  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);
		  }
		  }*/ 
	      start_meas(&dl_chan_stats);
	      for (UE_inst = 0; UE_inst < NB_UE_INST; UE_inst++) 
		for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
#warning	check dimensions of r_reN,r_imN for multiple CCs
		  do_DL_sig (r_re0, r_im0, r_re, r_im, s_re, s_im, eNB2UE, enb_data, ue_data, next_slot, abstraction_flag,&PHY_vars_eNB_g[0][CC_id]->lte_frame_parms, UE_inst,CC_id);
		}
	      stop_meas(&dl_chan_stats);
	      /*
		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);
	      */
	    }
	    else { // UL part
	      start_meas(&ul_chan_stats);
	      for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
#warning	check dimensions of r_reN,r_imN for multiple CCs
		do_UL_sig (r_re0, r_im0, r_re, r_im, s_re, s_im, UE2eNB, enb_data, ue_data, next_slot, abstraction_flag,&PHY_vars_eNB_g[0][CC_id]->lte_frame_parms, frame,CC_id);
	      }
	      stop_meas(&ul_chan_stats);

	      /*        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]);
			}
	      */
	    }
	  }
	  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][0]->lte_ue_common_vars.dl_ch_estimates[0][0][0]),
			  (6 * (PHY_vars_UE_g[0][0]->lte_frame_parms.ofdm_symbol_size)), 1, 1);
	    write_output ("dlchan1.m", "dlch1", &(PHY_vars_UE_g[0][0]->lte_ue_common_vars.dl_ch_estimates[1][0][0]),
			  (6 * (PHY_vars_UE_g[0][0]->lte_frame_parms.ofdm_symbol_size)), 1, 1);
	    write_output ("dlchan2.m", "dlch2", &(PHY_vars_UE_g[0][0]->lte_ue_common_vars.dl_ch_estimates[2][0][0]),
			  (6 * (PHY_vars_UE_g[0][0]->lte_frame_parms.ofdm_symbol_size)), 1, 1);
	    write_output ("pbch_rxF_comp0.m", "pbch_comp0", PHY_vars_UE_g[0][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][0]->lte_ue_pbch_vars[0]->llr,
			  (frame_parms[0]->Ncp == 0) ? 1920 : 1728, 1, 4);
	  }
	  /*
	    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);
	    }
	  */
	} // if Channel_Flag==0
    
    }//end of slot

986
    if ((frame >= 10) && (frame <= 11) && (abstraction_flag == 0)
987
#ifdef PROC
knopp's avatar
 
knopp committed
988
	&&(Channel_Flag==0)
989
#endif
knopp's avatar
 
knopp committed
990
	) {
991 992 993 994
      sprintf (fname, "UEtxsig%d.m", frame);
      sprintf (vname, "txs%d", frame);
      write_output (fname, vname, PHY_vars_UE_g[0][0]->lte_ue_common_vars.txdata[0], 
		    PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti*10,1,1);
knopp's avatar
 
knopp committed
995 996
      sprintf (fname, "eNBtxsig%d.m", frame);
      sprintf (vname, "txs%d", frame);
997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
      write_output (fname, vname, PHY_vars_eNB_g[0][0]->lte_eNB_common_vars.txdata[0][0], 
		    PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti*10,1,1);
      sprintf (fname, "eNBtxsigF%d.m", frame);
      sprintf (vname, "txsF%d", frame);
      write_output (fname, vname, PHY_vars_eNB_g[0][0]->lte_eNB_common_vars.txdataF[0][0],
		    PHY_vars_eNB_g[0][0]->lte_frame_parms.symbols_per_tti * PHY_vars_eNB_g[0][0]->lte_frame_parms.ofdm_symbol_size,1,1);
      sprintf (fname, "UErxsig%d.m", frame);
      sprintf (vname, "rxs%d", frame);
      write_output (fname, vname, PHY_vars_UE_g[0][0]->lte_ue_common_vars.rxdata[0], 
		    PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti*10,1,1);
      sprintf (fname, "eNBrxsig%d.m", frame);
      sprintf (vname, "rxs%d", frame);
      write_output (fname, vname, PHY_vars_eNB_g[0][0]->lte_eNB_common_vars.rxdata[0][0], 
		    PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti*10,1,1);
knopp's avatar
 
knopp committed
1011 1012
    }
    
1013
#ifdef XFORMS
knopp's avatar
 
knopp committed
1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026
    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][0],
		   eNB_inst,
		   UE_inst,
		   7);
      
      phy_scope_eNB(form_enb[UE_inst],
		    PHY_vars_eNB_g[eNB_inst][0],
		    UE_inst);
      
    }
1027
#endif
knopp's avatar
 
knopp committed
1028
    
1029
#ifdef SMBV
knopp's avatar
 
knopp committed
1030 1031 1032
    if ((frame == config_frames[0]) || (frame == config_frames[1]) || (frame == config_frames[2]) || (frame == config_frames[3])) {
      smbv_frame_cnt++;
    }
1033
#endif
knopp's avatar
 
knopp committed
1034 1035 1036 1037
  }
  stop_meas(&oaisim_stats_f);
    //end of frame
      
1038 1039
  stop_meas(&oaisim_stats);

1040 1041 1042 1043
#if defined(ENABLE_ITTI)
  itti_terminate_tasks(TASK_L2L1);
#endif

1044
#ifdef PRINT_STATS
1045
  for (UE_inst=0;UE_inst<NB_UE_INST;UE_inst++) {
knopp's avatar
 
knopp committed
1046 1047 1048 1049
    if (UE_stats[UE_inst])
      fclose (UE_stats[UE_inst]);
    if(UE_stats_th[UE_inst])
      fclose (UE_stats_th[UE_inst]);
1050
  }
1051
  for (eNB_inst=0;eNB_inst<NB_eNB_INST;eNB_inst++) {
knopp's avatar
 
knopp committed
1052 1053
    if (eNB_stats[eNB_inst])
      fclose (eNB_stats[eNB_inst]);
1054 1055
  }
  if (eNB_avg_thr)
gauthier's avatar
gauthier committed
1056
    fclose (eNB_avg_thr);
1057
  if (eNB_l2_stats)
gauthier's avatar
gauthier committed
1058
    fclose (eNB_l2_stats);
knopp's avatar
 
knopp committed
1059
  
1060
#endif
knopp's avatar
 
knopp committed
1061
  
1062 1063
  return NULL;
}
knopp's avatar
 
knopp committed
1064 1065 1066
  
  /*------------------------------------------------------------------------------*/
  int main(int argc, char **argv) {
1067

knopp's avatar
 
knopp committed
1068 1069 1070
    int32_t i;
    // pointers signal buffers (s = transmit, r,r0 = receive)
    clock_t t;
1071

knopp's avatar
 
knopp committed
1072 1073 1074 1075 1076
    //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
1077 1078

#ifdef SMBV
knopp's avatar
 
knopp committed
1079
    strcpy(smbv_ip,DEFAULT_SMBV_IP);
1080 1081
#endif

knopp's avatar
 
knopp committed
1082 1083 1084
    // time calibration for soft realtime mode  
    char pbch_file_path[512];
    FILE *pbch_file_fd;
1085 1086

#ifdef PROC
knopp's avatar
 
knopp committed
1087 1088
    int node_id;
    int port,Process_Flag=0,wgt,Channel_Flag=0,temp;
1089
#endif
knopp's avatar
 
knopp committed
1090 1091 1092 1093 1094 1095 1096 1097
    //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