oaisim.c 61 KB
Newer Older
1 2 3 4 5
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
Cedric Roux's avatar
Cedric Roux committed
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

22
/*! \file oaisim.c
23 24 25 26 27 28 29 30 31
 * \brief oaisim top level
 * \author Navid Nikaein 
 * \date 2013-2015
 * \version 1.0
 * \company Eurecom
 * \email: openair_tech@eurecom.fr
 * \note
 * \warning
 */
32

33 34 35 36 37 38 39 40 41 42
#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>

43
#include "event_handler.h"
knopp's avatar
knopp committed
44
#include "SIMULATION/RF/rf.h"
45
#include "PHY/types.h"
knopp's avatar
knopp committed
46 47 48 49 50 51 52 53 54 55 56
#include "PHY/defs_eNB.h"
#include "PHY/defs_UE.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
#include "PHY/phy_vars.h"
#include "PHY/phy_vars_ue.h"
#include "SCHED/sched_common_vars.h"

#include "LAYER2/MAC/mac.h"
#include "LAYER2/MAC/mac_proto.h"
#include "LAYER2/MAC/mac_vars.h"
57
#include "pdcp.h"
knopp's avatar
knopp committed
58
#include "RRC/LTE/rrc_vars.h"
59
#include "RRC/NAS/nas_config.h"
60

61
#include "system.h"
62

knopp's avatar
knopp committed
63

64
#include "PHY/TOOLS/lte_phy_scope.h"
knopp's avatar
knopp committed
65

66 67

#ifdef SMBV
68
// Rohde&Schwarz SMBV100A vector signal generator
69
#include "PHY/TOOLS/smbv.h"
gauthier's avatar
gauthier committed
70
char smbv_fname[] = "smbv_config_file.smbv";
71 72
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
73 74 75
unsigned char smbv_frame_cnt = 0;
uint8_t config_smbv = 0;
char smbv_ip[16];
76 77
#endif

78
#include "flexran_agent.h"
79 80


81 82 83 84 85 86 87 88
#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"
89
#include "enb_app.h"
90 91 92 93 94 95 96

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

#include "UTIL/LOG/vcd_signal_dumper.h"
97
#include "UTIL/OTG/otg_kpi.h"
98
#include "assertions.h"
99 100

#if defined(ENABLE_ITTI)
101
# include "intertask_interface.h"
102
# include "create_tasks.h"
knopp's avatar
knopp committed
103
# include "intertask_interface_init.h"
104
#endif
105

106 107
#include "T.h"

108
/*
109 110 111 112 113
  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;
*/
114

gauthier's avatar
gauthier committed
115 116 117 118
#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
119

gauthier's avatar
gauthier committed
120 121
#define DECOR_DIST             100
#define SF_VAR                 10
122 123

//constant for OAISIM soft realtime calibration
124 125 126 127
//#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
128

fnabet's avatar
fnabet committed
129 130
uint8_t usim_test = 0;

gauthier's avatar
gauthier committed
131 132
frame_t frame = 0;
char stats_buffer[16384];
133 134
channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs];
channel_desc_t *UE2RU[NUMBER_OF_UE_MAX][NUMBER_OF_RU_MAX][MAX_NUM_CCs];
135
//Added for PHY abstraction
136
node_desc_t *enb_data[NUMBER_OF_RU_MAX];
gauthier's avatar
gauthier committed
137
node_desc_t *ue_data[NUMBER_OF_UE_MAX];
knopp's avatar
knopp committed
138 139 140

pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
141
int sync_var=-1;
knopp's avatar
knopp committed
142

143
pthread_mutex_t subframe_mutex;
144
int subframe_ru_mask=0,subframe_UE_mask=0;
knopp's avatar
knopp committed
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160

openair0_config_t openair0_cfg[MAX_CARDS];
uint32_t          downlink_frequency[MAX_NUM_CCs][4];
int32_t           uplink_frequency_offset[MAX_NUM_CCs][4];
openair0_rf_map rf_map[MAX_NUM_CCs];

#if defined(ENABLE_ITTI)
volatile int             start_eNB = 0;
volatile int             start_UE = 0;
#endif
volatile int                    oai_exit = 0;


//int32_t **rxdata;
//int32_t **txdata;

161 162
uint16_t sf_ahead=4;
uint8_t nfapi_mode = 0;
knopp's avatar
knopp committed
163

164
// Added for PHY abstraction
gauthier's avatar
gauthier committed
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
extern node_list* ue_node_list;
extern node_list* enb_node_list;
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;
extern uint8_t set_sinr;
extern uint8_t ue_connection_test;
extern uint8_t set_seed;
extern uint8_t target_dl_mcs;
extern uint8_t target_ul_mcs;
extern uint8_t abstraction_flag;
extern uint8_t ethernet_flag;
extern uint16_t Nid_cell;
182

knopp's avatar
knopp committed
183

184 185
double cpuf;
#include "threads_t.h"
186
threads_t threads= {-1,-1,-1,-1,-1,-1,-1};
knopp's avatar
knopp committed
187

188
//#ifdef XFORMS
189
int otg_enabled;
190 191
int xforms=0;
//#endif
192

193 194 195 196 197
time_stats_t oaisim_stats;
time_stats_t oaisim_stats_f;
time_stats_t dl_chan_stats;
time_stats_t ul_chan_stats;

Cedric Roux's avatar
Cedric Roux committed
198 199 200 201 202
int emulate_rf = 0;
int numerology = 0;
int codingw = 0;
int fepw = 0;

203
// this should reflect the channel models in openair1/SIMULATION/TOOLS/defs.h
204 205 206 207 208 209 210 211 212 213
mapping small_scale_names[] = { 
  { "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 }
214
};
215
#if !defined(ENABLE_ITTI)
gauthier's avatar
gauthier committed
216 217
static void *
sigh (void *arg);
218
#endif
gauthier's avatar
gauthier committed
219 220 221
void
oai_shutdown (void);

Rohit Gupta's avatar
Rohit Gupta committed
222 223
void reset_opp_meas_oaisim (void);

Cedric Roux's avatar
Cedric Roux committed
224 225
void wait_eNBs(void)
{
226 227 228
  return;
}

gauthier's avatar
gauthier committed
229
void
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
help (void)
{
  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");

  printf ("-h provides this help message!\n");
  printf ("-a Activates PHY abstraction mode\n");
  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");
  printf ("-b Set the number of local eNB\n");
  printf ("-B Set the mobility model for eNB, options are: STATIC, RWP, RWALK, \n");
  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");
  printf ("-C [0-6] Sets TDD configuration\n");
  printf ("-e Activates extended prefix mode\n");
  printf ("-E Random number generator seed\n");
  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");
  printf ("-H Enable handover operation (default disabled) \n");
  printf ("-I Enable CLI interface (to connect use telnet localhost 1352)\n");
  printf ("-k Set the Ricean factor (linear)\n");
  printf ("-K [log_file] Enable ITTI logging into log_file\n");
  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");
  printf ("-m Gives a fixed DL mcs for eNB scheduler\n");
  printf ("-M Set the machine ID for Ethernet-based emulation\n");
255
  printf ("-n Set the number of frames for the simulation. 0 for no limit\n");
256 257 258 259 260 261 262 263 264 265 266 267 268
  printf ("-O [enb_conf_file] eNB configuration file name\n");
  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");
  printf ("-q Enable Openair performance profiler \n");
  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");
  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");
  printf ("-t Gives a fixed UL mcs for eNB scheduler\n");
269
  printf ("-T activate the traffic generator. Valide options are m2m,scbr,mcbr,bcbr,auto_pilot,bicycle_race,open_arena,team_fortress,m2m_traffic,auto_pilot_l,auto_pilot_m,auto_pilot_h,auto_pilot_e,virtual_game_l,virtual_game_m,virtual_game_h,virtual_game_f,alarm_humidity,alarm_smoke,alarm_temperature,openarena_dl,openarena_ul,voip_g711,voip_g729,video_vbr_10mbps,video_vbr_4mbps,video_vbr_2mbp,video_vbr_768kbps,video_vbr_384kbps,video_vbr_192kpbs,background_users\n");
270 271 272 273
  printf ("-u Set the number of local UE\n");
  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");
  printf ("-w number of CBA groups, if not specified or zero, CBA is inactive\n");
274
#ifdef SMBV
275
  printf ("-W IP address to connect to Rohde&Schwarz SMBV100A and configure SMBV from config file. -W0 uses default IP 192.168.12.201\n");
276
#else
277
  printf ("-W [Rohde&Schwarz SMBV100A functions disabled. Recompile with SMBV=1]\n");
278
#endif
279 280
  printf ("-x deprecated. Set the transmission mode in config file!\n");
  printf ("-y Set the number of receive antennas at the UE (1 or 2)\n");
281 282 283
  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");
284 285
  printf ("--xforms Activate the grapical scope\n");

286 287 288 289
}

pthread_t log_thread;

gauthier's avatar
gauthier committed
290
void
291 292 293 294
log_thread_init (void)
{
  //create log_list
  //log_list_init(&log_list);
295 296
#ifndef LOG_NO_THREAD

297
  log_shutdown = 0;
298

299 300 301 302 303 304 305 306 307 308
  if ((pthread_mutex_init (&log_lock, NULL) != 0)
      || (pthread_cond_init (&log_notify, NULL) != 0)) {
    return;
  }

  if (pthread_create (&log_thread, NULL, log_thread_function, (void*) NULL)
      != 0) {
    log_thread_finalize ();
    return;
  }
309 310 311 312 313 314

#endif

}

//Call it after the last LOG call
gauthier's avatar
gauthier committed
315
int
316 317 318
log_thread_finalize (void)
{
  int err = 0;
319 320 321

#ifndef LOG_NO_THREAD

322 323 324
  if (pthread_mutex_lock (&log_lock) != 0) {
    return -1;
  }
gauthier's avatar
gauthier committed
325

326
  log_shutdown = 1;
gauthier's avatar
gauthier committed
327

328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
  /* Wake up LOG thread */
  if ((pthread_cond_broadcast (&log_notify) != 0)
      || (pthread_mutex_unlock (&log_lock) != 0)) {
    err = -1;
  }

  if (pthread_join (log_thread, NULL) != 0) {
    err = -1;
  }

  if (pthread_mutex_unlock (&log_lock) != 0) {
    err = -1;
  }

  if (!err) {
    //log_list_free(&log_list);
    pthread_mutex_lock (&log_lock);
    pthread_mutex_destroy (&log_lock);
    pthread_cond_destroy (&log_notify);
  }
gauthier's avatar
gauthier committed
348

Cedric Roux's avatar
Cedric Roux committed
349 350
#endif

351
  return err;
352 353
}

354
#if defined(ENABLE_ITTI)
355 356 357 358 359 360 361
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;
  } else {
    oai_emulation.info.cli_start_ue[module_idP - NB_eNB_INST] = start;
  }
362 363 364
}
#endif

365
#ifdef OPENAIR2
366 367
int omv_write(int pfd, node_list* enb_node_list, node_list* ue_node_list, Data_Flow_Unit omv_data)
{
Cedric Roux's avatar
Cedric Roux committed
368
  module_id_t i;
369 370 371 372 373 374 375 376 377 378 379 380
  omv_data.end = 0;

  //omv_data.total_num_nodes = NB_UE_INST + NB_eNB_INST;
  for (i = 0; i < NB_eNB_INST; i++) {
    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;
381
/*
382 383
      for (j = NB_RU; j < NB_UE_INST + NB_RU; j++) {
        if (is_UE_active (i, j - NB_RU) == 1) {
384 385 386
          omv_data.geo[i].Neighbor[omv_data.geo[i].Neighbors] = j;
          omv_data.geo[i].Neighbors++;
          LOG_D(
387
		OMG,
388
		"[RU %d][UE %d] is_UE_active(i,j) %d geo (x%d, y%d) num neighbors %d\n", i, j-NB_RU, is_UE_active(i,j-NB_RU), omv_data.geo[i].x, omv_data.geo[i].y, omv_data.geo[i].Neighbors);
gauthier's avatar
gauthier committed
389
        }
390
      }
391
*/
392
    }
393 394
  }

395
  for (i = NB_RU; i < NB_UE_INST + NB_RU; i++) {
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417
    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;
418
/*
419 420
      for (j = 0; j < NB_RU; j++) {
        if (is_UE_active (j, i - NB_RU) == 1) {
421 422 423
          omv_data.geo[i].Neighbor[omv_data.geo[i].Neighbors] = j;
          omv_data.geo[i].Neighbors++;
          LOG_D(
424
		OMG,
425
		"[UE %d][RU %d] is_UE_active  %d geo (x%d, y%d) num neighbors %d\n", i-NB_RU, j, is_UE_active(j,i-NB_RU), omv_data.geo[i].x, omv_data.geo[i].y, omv_data.geo[i].Neighbors);
gauthier's avatar
gauthier committed
426
        }
427
      }
428
*/
429
    }
430 431 432 433 434
  }

  LOG_E(OMG, "pfd %d \n", pfd);

  if (write (pfd, &omv_data, sizeof(struct Data_Flow_Unit)) == -1)
435
    perror ("write omv failed");
436 437

  return 1;
438 439
}

440 441 442 443 444
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)
445
    perror ("write omv failed");
446
}
447
#endif
448

449
#ifdef OPENAIR2
450 451
int pfd[2]; // fd for omv : fixme: this could be a local var
#endif
452

453 454 455
#ifdef OPENAIR2
static Data_Flow_Unit omv_data;
#endif //ALU
gauthier's avatar
gauthier committed
456
static module_id_t UE_inst = 0;
gauthier's avatar
gauthier committed
457
static module_id_t eNB_inst = 0;
458
static module_id_t ru_id;
459

460
Packet_OTG_List_t *otg_pdcp_buffer;
461

gauthier's avatar
gauthier committed
462
typedef enum l2l1_task_state_e {
463
  L2L1_WAITTING, L2L1_RUNNING, L2L1_TERMINATED,
gauthier's avatar
gauthier committed
464
} l2l1_task_state_t;
465

gauthier's avatar
gauthier committed
466
l2l1_task_state_t l2l1_state = L2L1_WAITTING;
467

468
extern openair0_timestamp current_ru_rx_timestamp[NUMBER_OF_RU_MAX][MAX_NUM_CCs];
469
extern openair0_timestamp current_UE_rx_timestamp[NUMBER_OF_UE_MAX][MAX_NUM_CCs];
470 471
extern openair0_timestamp last_eNB_rx_timestamp[NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
extern openair0_timestamp last_UE_rx_timestamp[NUMBER_OF_UE_MAX][MAX_NUM_CCs];
472

473
/*------------------------------------------------------------------------------*/
gauthier's avatar
gauthier committed
474
void *
475 476
l2l1_task (void *args_p)
{
gauthier's avatar
gauthier committed
477

478
  int CC_id;
479

480
  // Framing variables
481
  int32_t sf;
482

Cedric Roux's avatar
Cedric Roux committed
483
  //char fname[64], vname[64];
484

485
  //#ifdef XFORMS
486 487
  // 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
488
  FD_lte_phy_scope_ue *form_ue[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
489 490 491 492 493
  FD_lte_phy_scope_enb *form_enb[NUMBER_OF_UE_MAX];
  char title[255];
  char xname[32] = "oaisim";
  int xargc = 1;
  char *xargv[1];
494
  //#endif
495

Cedric Roux's avatar
Cedric Roux committed
496
#undef PRINT_STATS /* this undef is to avoid gcc warnings */
497
#define PRINT_STATS
498
#ifdef PRINT_STATS
Cedric Roux's avatar
Cedric Roux committed
499
  //int len;
500 501 502 503 504 505 506 507 508
  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];
509 510 511
#endif


512 513 514 515 516 517 518 519 520 521 522
  if (xforms==1) {
    xargv[0] = xname;
    fl_initialize (&xargc, xargv, NULL, 0, 0);
    eNB_inst = 0;
    for (UE_inst = 0; UE_inst < NB_UE_INST; UE_inst++) {
      for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
	// DL scope at UEs
	form_ue[CC_id][UE_inst] = create_lte_phy_scope_ue();
	sprintf (title, "LTE DL SCOPE eNB %d to UE %d CC_id %d", eNB_inst, UE_inst, CC_id);
	fl_show_form (form_ue[CC_id][UE_inst]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);

523
	if (PHY_vars_UE_g[UE_inst][CC_id]->use_ia_receiver == 1) {
524 525 526 527 528 529
	  fl_set_button(form_ue[CC_id][UE_inst]->button_0,1);
	  fl_set_object_label(form_ue[CC_id][UE_inst]->button_0, "IA Receiver ON");
	  fl_set_object_color(form_ue[CC_id][UE_inst]->button_0, FL_GREEN, FL_GREEN);
	}
	
      }
gauthier's avatar
gauthier committed
530
    }
531
  }
532

533 534

#ifdef PRINT_STATS
gauthier's avatar
gauthier committed
535

536 537 538 539 540 541 542 543 544 545 546 547
  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");
  }

  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");
  }

  if(abstraction_flag==0) {
    for (UE_inst=0; UE_inst<NB_UE_INST; UE_inst++) {
Cedric Roux's avatar
Cedric Roux committed
548 549
      /* TODO: transmission_mode is defined per CC, we set 0 for now */
      sprintf(UE_stats_th_filename,"UE_stats_th%d_tx%d.txt",UE_inst,oai_emulation.info.transmission_mode[0]);
550
      UE_stats_th[UE_inst] = fopen (UE_stats_th_filename, "w");
gauthier's avatar
gauthier committed
551
    }
552

Cedric Roux's avatar
Cedric Roux committed
553 554
    /* TODO: transmission_mode is defined per CC, we set 0 for now */
    sprintf(eNB_stats_th_filename,"eNB_stats_th_tx%d.txt",oai_emulation.info.transmission_mode[0]);
555 556 557
    eNB_avg_thr = fopen (eNB_stats_th_filename, "w");
  } else {
    for (UE_inst=0; UE_inst<NB_UE_INST; UE_inst++) {
Cedric Roux's avatar
Cedric Roux committed
558 559
      /* TODO: transmission_mode is defined per CC, we set 0 for now */
      sprintf(UE_stats_th_filename,"UE_stats_abs_th%d_tx%d.txt",UE_inst,oai_emulation.info.transmission_mode[0]);
560
      UE_stats_th[UE_inst] = fopen (UE_stats_th_filename, "w");
561
    }
562

Cedric Roux's avatar
Cedric Roux committed
563 564
    /* TODO: transmission_mode is defined per CC, we set 0 for now */
    sprintf(eNB_stats_th_filename,"eNB_stats_abs_th_tx%d.txt",oai_emulation.info.transmission_mode[0]);
565 566 567
    eNB_avg_thr = fopen (eNB_stats_th_filename, "w");
  }

568
#ifdef OPENAIR2
569 570 571
  eNB_l2_stats = fopen ("eNB_l2_stats.txt", "w");
  LOG_I(EMU,"eNB_l2_stats=%p\n", eNB_l2_stats);
#endif
572 573 574

#endif

575
#if defined(ENABLE_ITTI)
576 577 578 579 580 581 582
  MessageDef *message_p = NULL;
  const char *msg_name = NULL;
  int result;

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

583 584
  if ((oai_emulation.info.nb_enb_local > 0) && 
      (oai_emulation.info.node_function[0] < NGFI_RAU_IF4p5)) {
585 586 587
    /* Wait for the initialize message */
    do {
      if (message_p != NULL) {
gauthier's avatar
gauthier committed
588 589
        result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
        AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
590 591 592 593 594 595 596 597 598
      }

      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;
599
        start_eNB = 1;
600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
        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
624
#endif
knopp's avatar
knopp committed
625
  
626

627
  
628 629 630
  start_meas (&oaisim_stats);

  for (frame = 0;
631
       (l2l1_state != L2L1_TERMINATED) && 
632 633
	 ((oai_emulation.info.n_frames_flag == 0) ||
	  (frame < oai_emulation.info.n_frames));
634
       frame++) {
635

gauthier's avatar
gauthier committed
636 637
#if defined(ENABLE_ITTI)

638 639 640
    do {
      // Checks if a message has been sent to L2L1 task
      itti_poll_msg (TASK_L2L1, &message_p);
641

642 643 644
      if (message_p != NULL) {
        msg_name = ITTI_MSG_NAME (message_p);
        LOG_I(EMU, "TASK_L2L1 received %s\n", msg_name);
gauthier's avatar
gauthier committed
645

646 647 648 649 650 651 652 653 654 655 656 657
        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;
gauthier's avatar
gauthier committed
658

659 660 661 662 663 664
        case MESSAGE_TEST:
          break;

        default:
          LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
          break;
gauthier's avatar
gauthier committed
665 666
        }

667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693
        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);

#endif

    //Run the aperiodic user-defined events
    if (oai_emulation.info.oeh_enabled == 1)
      execute_events (frame);

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

    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)
gauthier's avatar
gauthier committed
694

knopp's avatar
knopp committed
695 696
    //update_omg (frame); // frequency is defined in the omg_global params configurable by the user
    //update_omg_ocm ();
697 698

#ifdef OPENAIR2
699 700 701 702 703 704

    // 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);
    }

705 706
#endif

707

gauthier's avatar
gauthier committed
708

709
    for (sf = 0; sf < 10; sf++) {
710
      LOG_D(EMU,"************************* Subframe %d\n",sf);
711
      start_meas (&oaisim_stats_f);
712

713
      wait_for_slot_isr ();
714

715
#if defined(ENABLE_ITTI)
716
      itti_update_lte_time(frame % MAX_FRAME_NUMBER, sf<<1);
717
#endif
718

719
      oai_emulation.info.time_ms = frame * 10 + sf;
720

721
#ifdef PROC
722

723
    if(Channel_Flag==1)
724
      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,RU2UE,UE2RU,enb_data,ue_data,abstraction_flag,frame_parms,sf<<1);
725

726
    if(Channel_Flag==0)
727
#endif
728
      { // SUBFRAME INNER PART
729
#if defined(ENABLE_ITTI)
730
        log_set_instance_type (LOG_INSTANCE_ENB);
731 732
#endif

733

734
	CC_id=0;
735 736
        int all_done=0;
        while (all_done==0) {
737

738
          pthread_mutex_lock(&subframe_mutex);
knopp's avatar
knopp committed
739
          int subframe_ru_mask_local  = (subframe_select(&RC.ru[0]->frame_parms,(sf+4)%10)!=SF_UL) ? subframe_ru_mask : ((1<<NB_RU)-1);
knopp's avatar
knopp committed
740
          int subframe_UE_mask_local  = (RC.ru[0]->frame_parms.frame_type == FDD || subframe_select(&RC.ru[0]->frame_parms,(sf+4)%10)!=SF_DL) ? subframe_UE_mask : ((1<<NB_UE_INST)-1);
741
          pthread_mutex_unlock(&subframe_mutex);
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
742
          LOG_D(EMU,"Frame %d, Subframe %d, NB_RU %d, NB_UE %d: Checking masks %x,%x\n",frame,sf,NB_RU,NB_UE_INST,subframe_ru_mask_local,subframe_UE_mask_local);
743
          if ((subframe_ru_mask_local == ((1<<NB_RU)-1)) &&
knopp's avatar
knopp committed
744 745
              (subframe_UE_mask_local == ((1<<NB_UE_INST)-1))) all_done=1;
          else usleep(1500);
746 747
        }

748

749 750
        //clear subframe masks for next round
        pthread_mutex_lock(&subframe_mutex);
751
        subframe_ru_mask=0;
752 753
        subframe_UE_mask=0;
        pthread_mutex_unlock(&subframe_mutex);
754

755
        // increment timestamps
756 757 758
	/*
        for (ru_id = oai_emulation.info.first_enb_local;
             (ru_id
759 760
              < (oai_emulation.info.first_enb_local
                 + oai_emulation.info.nb_enb_local));
761 762 763 764
             ru_id++) {
	*/
	for (ru_id=0;ru_id<NB_RU;ru_id++) {
	  current_ru_rx_timestamp[ru_id][CC_id] += RC.ru[ru_id]->frame_parms.samples_per_tti;
Cedric Roux's avatar
Cedric Roux committed
765
	  LOG_D(EMU,"RU %d/%d: TS %"PRIi64"\n",ru_id,CC_id,current_ru_rx_timestamp[ru_id][CC_id]);
766 767
        }
        for (UE_inst = 0; UE_inst<NB_UE_INST;UE_inst++) {
768
	  current_UE_rx_timestamp[UE_inst][CC_id] += PHY_vars_UE_g[UE_inst][CC_id]->frame_parms.samples_per_tti;
Cedric Roux's avatar
Cedric Roux committed
769
	  LOG_D(EMU,"UE %d/%d: TS %"PRIi64"\n",UE_inst,CC_id,current_UE_rx_timestamp[UE_inst][CC_id]);
770 771
        }

772 773 774 775 776 777
        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) {
778
        
779
	    /*
780 781 782 783 784 785 786 787 788
	    LOG_D(EMU,
		  "PHY procedures eNB %d for frame %d, subframe %d TDD %d/%d Nid_cell %d\n",
		  eNB_inst,
		  frame % MAX_FRAME_NUMBER,
		  sf,
		  PHY_vars_eNB_g[eNB_inst][0]->frame_parms.frame_type,
		  PHY_vars_eNB_g[eNB_inst][0]->frame_parms.tdd_config,
		  PHY_vars_eNB_g[eNB_inst][0]->frame_parms.Nid_cell);
            
789
	    */
790
#ifdef PRINT_STATS
791

792
            if((sf==9) && frame%10==0)
793
              if(eNB_avg_thr)
794 795
                fprintf(eNB_avg_thr,"%d %d\n",RC.eNB[eNB_inst][0]->proc.proc_rxtx[sf&1].frame_tx,
                        (RC.eNB[eNB_inst][0]->total_system_throughput)/((RC.eNB[eNB_inst][0]->proc.proc_rxtx[sf&1].frame_tx+1)*10));
796
	    /*
797
            if (eNB_stats[eNB_inst]) {
798
              len = dump_eNB_stats(RC.eNB[eNB_inst][0], stats_buffer, 0);
799 800 801 802
              rewind (eNB_stats[eNB_inst]);
              fwrite (stats_buffer, 1, len, eNB_stats[eNB_inst]);
              fflush(eNB_stats[eNB_inst]);
            }
803
#ifdef OPENAIR2
804 805 806 807 808 809 810
            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);
            }

811
#endif
knopp's avatar
knopp committed
812
*/
813
#endif
814
          }
815
        }// eNB_inst loop
gauthier's avatar
gauthier committed
816

817

818
#if defined(ENABLE_ITTI)
819
        log_set_instance_type (LOG_INSTANCE_UE);
820 821
#endif

822

823 824 825
	if ((sf == 0) && ((frame % MAX_FRAME_NUMBER) == 0) && (abstraction_flag == 0)
	    && (oai_emulation.info.n_frames == 1)) {
	  
Mongazon's avatar
Mongazon committed
826
	  LOG_M ("dlchan0.m",
827
			"dlch0",
828
			&(PHY_vars_UE_g[0][0]->common_vars.common_vars_rx_data_per_thread[0].dl_ch_estimates[0][0][0]),
829 830 831
			(6
			 * (PHY_vars_UE_g[0][0]->frame_parms.ofdm_symbol_size)),
			1, 1);
Mongazon's avatar
Mongazon committed
832
	  LOG_M ("dlchan1.m",
833
			"dlch1",
834
			&(PHY_vars_UE_g[0][0]->common_vars.common_vars_rx_data_per_thread[0].dl_ch_estimates[1][0][0]),
835 836 837
			(6
			 * (PHY_vars_UE_g[0][0]->frame_parms.ofdm_symbol_size)),
			1, 1);
Mongazon's avatar
Mongazon committed
838
	  LOG_M ("dlchan2.m",
839
			"dlch2",
840
			&(PHY_vars_UE_g[0][0]->common_vars.common_vars_rx_data_per_thread[0].dl_ch_estimates[2][0][0]),
841 842 843
			(6
			 * (PHY_vars_UE_g[0][0]->frame_parms.ofdm_symbol_size)),
			1, 1);
Mongazon's avatar
Mongazon committed
844
	  LOG_M ("pbch_rxF_comp0.m",
845 846 847
			"pbch_comp0",
			PHY_vars_UE_g[0][0]->pbch_vars[0]->rxdataF_comp[0],
			6 * 12 * 4, 1, 1);
Mongazon's avatar
Mongazon committed
848
	  LOG_M ("pbch_rxF_llr.m", "pbch_llr",
849
			PHY_vars_UE_g[0][0]->pbch_vars[0]->llr,
850
			(PHY_vars_UE_g[0][0]->frame_parms.Ncp == 0) ? 1920 : 1728, 1,
851 852 853 854 855
			4);
	}
    
	stop_meas (&oaisim_stats_f);
      } // SUBFRAME INNER PART
856 857


858
    }
knopp's avatar
knopp committed
859
    //update_ocm ();
860
    /*
861
    if ((frame >= 10) && (frame <= 11) && (abstraction_flag == 0)
862
#ifdef PROC
863
	&&(Channel_Flag==0)
864
#endif
865
	) {
866 867
      sprintf (fname, "UEtxsig%d.m", frame % MAX_FRAME_NUMBER);
      sprintf (vname, "txs%d", frame % MAX_FRAME_NUMBER);
Mongazon's avatar
Mongazon committed
868
      LOG_M (fname,
869 870 871 872 873
		    vname,
		    PHY_vars_UE_g[0][0]->common_vars.txdata[0],
		    PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti
		    * 10,
		    1, 1);
874 875
      sprintf (fname, "eNBtxsig%d.m", frame % MAX_FRAME_NUMBER);
      sprintf (vname, "txs%d", frame % MAX_FRAME_NUMBER);
Mongazon's avatar
Mongazon committed
876
      LOG_M (fname,
877 878 879 880 881
		    vname,
		    PHY_vars_eNB_g[0][0]->common_vars.txdata[0][0],
		    PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti
		    * 10,
		    1, 1);
882 883
      sprintf (fname, "eNBtxsigF%d.m", frame % MAX_FRAME_NUMBER);
      sprintf (vname, "txsF%d", frame % MAX_FRAME_NUMBER);
Mongazon's avatar
Mongazon committed
884
      LOG_M (fname,
885 886 887 888 889
		    vname,
		    PHY_vars_eNB_g[0][0]->common_vars.txdataF[0][0],
		    PHY_vars_eNB_g[0][0]->frame_parms.symbols_per_tti
		    * PHY_vars_eNB_g[0][0]->frame_parms.ofdm_symbol_size,
		    1, 1);
890 891
      sprintf (fname, "UErxsig%d.m", frame % MAX_FRAME_NUMBER);
      sprintf (vname, "rxs%d", frame % MAX_FRAME_NUMBER);
Mongazon's avatar
Mongazon committed
892
      LOG_M (fname,
893 894 895 896 897
		    vname,
		    PHY_vars_UE_g[0][0]->common_vars.rxdata[0],
		    PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti
		    * 10,
		    1, 1);
898 899
      sprintf (fname, "eNBrxsig%d.m", frame % MAX_FRAME_NUMBER);
      sprintf (vname, "rxs%d", frame % MAX_FRAME_NUMBER);
Mongazon's avatar
Mongazon committed
900
      LOG_M (fname,
901 902 903 904 905
		    vname,
		    PHY_vars_eNB_g[0][0]->common_vars.rxdata[0][0],
		    PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti
		    * 10,
		    1, 1);
906
    }
907
    */
908
    
909 910
    //#ifdef XFORMS
    if (xforms==1) {
911 912 913 914 915 916 917 918 919 920
      eNB_inst = 0;
      
      for (UE_inst = 0; UE_inst < NB_UE_INST; UE_inst++) {
	for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
	  phy_scope_UE(form_ue[CC_id][UE_inst],
		   PHY_vars_UE_g[UE_inst][CC_id],
		   eNB_inst,
		   UE_inst,
		   7);
	}
921 922 923 924
	if (RC.eNB && RC.eNB[eNB_inst] && RC.eNB[eNB_inst][0] )
	  phy_scope_eNB(form_enb[UE_inst],
			RC.eNB[eNB_inst][0],
			UE_inst);
925
	
926 927 928
      }
    }
    //#endif
929
    
930
#ifdef SMBV
931
    
932
    // Rohde&Schwarz SMBV100A vector signal generator
933
    if ((frame % MAX_FRAME_NUMBER == config_frames[0]) || (frame % MAX_FRAME_NUMBER == config_frames[1]) || (frame % MAX_FRAME_NUMBER == config_frames[2]) || (frame % MAX_FRAME_NUMBER == config_frames[3])) {
934
      smbv_frame_cnt++;
gauthier's avatar
gauthier committed
935
    }
936
    
937
#endif
938 939
    
  } // frame loop
gauthier's avatar
gauthier committed
940

941
  stop_meas (&oaisim_stats);
942
  oai_shutdown ();
943
  
944
#ifdef PRINT_STATS
945
  
946 947 948
  for (UE_inst=0; UE_inst<NB_UE_INST; UE_inst++) {
    if (UE_stats[UE_inst])
      fclose (UE_stats[UE_inst]);
949
    
950 951 952
    if(UE_stats_th[UE_inst])
      fclose (UE_stats_th[UE_inst]);
  }
953
  
954 955 956 957
  for (eNB_inst=0; eNB_inst<NB_eNB_INST; eNB_inst++) {
    if (eNB_stats[eNB_inst])
      fclose (eNB_stats[eNB_inst]);
  }
958
  
959
  if (eNB_avg_thr)
gauthier's avatar
gauthier committed
960
    fclose (eNB_avg_thr);
961
  
962
  if (eNB_l2_stats)
gauthier's avatar
gauthier committed
963
    fclose (eNB_l2_stats);
964
  
965
#endif
966
  
967 968 969
#if defined(ENABLE_ITTI)
  itti_terminate_tasks(TASK_L2L1);
#endif
970
  
971
  return NULL;
972
}
gauthier's avatar
gauthier committed
973

974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990
/*
 * The following two functions are meant to restart *the lte-softmodem* and are
 * here to make oaisim compile. A restart command from the controller will be
 * ignored in oaisim.
 */
int stop_L1L2(int enb_id)
{
  LOG_W(FLEXRAN_AGENT, "stop_L1L2() not supported in oaisim\n");
  return 0;
}

int restart_L1L2(int enb_id)
{
  LOG_W(FLEXRAN_AGENT, "restart_L1L2() not supported in oaisim\n");
  return 0;
}

991

Cedric Roux's avatar
Cedric Roux committed
992 993
void wait_RUs(void)
{
994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007
  int i;

  // wait for all RUs to be configured over fronthaul
  pthread_mutex_lock(&RC.ru_mutex);



  while (RC.ru_mask>0) {
    pthread_cond_wait(&RC.ru_cond,&RC.ru_mutex);
  }

  // copy frame parameters from RU to UEs
  for (i=0;i<NB_UE_INST;i++) {
    PHY_vars_UE_g[i][0]->frame_parms.N_RB_DL              = RC.ru[0]->frame_parms.N_RB_DL;
1008
    PHY_vars_UE_g[i][0]->frame_parms.N_RB_UL              = RC.ru[0]->frame_parms.N_RB_UL;
1009 1010
    PHY_vars_UE_g[i][0]->frame_parms.nb_antennas_tx       = 1;
    PHY_vars_UE_g[i][0]->frame_parms.nb_antennas_rx       = 1;
knopp's avatar
knopp committed
1011 1012
    // set initially to 2, it will be revised after initial synchronization
    PHY_vars_UE_g[i][0]->frame_parms.nb_antenna_ports_eNB = 2;
1013
    PHY_vars_UE_g[i][0]->frame_parms.tdd_config = 1;
1014 1015 1016
    PHY_vars_UE_g[i][0]->frame_parms.dl_CarrierFreq       = RC.ru[0]->frame_parms.dl_CarrierFreq;
    PHY_vars_UE_g[i][0]->frame_parms.ul_CarrierFreq       = RC.ru[0]->frame_parms.ul_CarrierFreq;
    PHY_vars_UE_g[i][0]->frame_parms.eutra_band           = RC.ru[0]->frame_parms.eutra_band;
knopp's avatar
knopp committed
1017 1018 1019 1020 1021 1022 1023 1024
    LOG_I(PHY,"Initializing UE %d frame parameters from RU information: N_RB_DL %d, p %d, dl_Carrierfreq %u, ul_CarrierFreq %u, eutra_band %d\n",
	  i,
	  PHY_vars_UE_g[i][0]->frame_parms.N_RB_DL,
	  PHY_vars_UE_g[i][0]->frame_parms.nb_antenna_ports_eNB,
	  PHY_vars_UE_g[i][0]->frame_parms.dl_CarrierFreq,
	  PHY_vars_UE_g[i][0]->frame_parms.ul_CarrierFreq,
	  PHY_vars_UE_g[i][0]->frame_parms.eutra_band);

1025
    current_UE_rx_timestamp[i][0] = RC.ru[0]->frame_parms.samples_per_tti + RC.ru[0]->frame_parms.ofdm_symbol_size + RC.ru[0]->frame_parms.nb_prefix_samples0;
1026 1027 1028

  }
  
knopp's avatar
knopp committed
1029 1030 1031
  


1032 1033 1034 1035 1036
  for (ru_id=0;ru_id<RC.nb_RU;ru_id++) current_ru_rx_timestamp[ru_id][0] = RC.ru[ru_id]->frame_parms.samples_per_tti;

  printf("RUs are ready, let's go\n");
}

1037
void init_UE(int,int,int,int);
1038 1039
void init_RU(const char*);

1040 1041 1042 1043 1044 1045 1046 1047 1048
void set_UE_defaults(int nb_ue) {

  for (int UE_id = 0;UE_id<nb_ue;UE_id++) {
    for (int CC_id = 0;CC_id<MAX_NUM_CCs;CC_id++) {
      for (uint8_t i=0; i<RX_NB_TH_MAX; i++) {
	PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[i][0]->dciFormat      = 0;
	PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[i][0]->agregationLevel      = 0xFF;
      }
      PHY_vars_UE_g[UE_id][CC_id]->current_dlsch_cqi[0] = 10;
1049
      PHY_vars_UE_g[UE_id][CC_id]->tx_power_max_dBm = 23;
1050 1051 1052 1053
    }
  }
}

knopp's avatar
knopp committed
1054

Cedric Roux's avatar
Cedric Roux committed
1055 1056 1057 1058 1059 1060 1061 1062 1063
static void print_current_directory(void)
{
  char dir[8192]; /* arbitrary size (should be big enough) */
  if (getcwd(dir, 8192) == NULL)
    printf("ERROR getting working directory\n");
  else
    printf("working directory: %s\n", dir);
}

Cedric Roux's avatar
Cedric Roux committed
1064 1065 1066
void init_devices(void);

int main (int argc, char **argv)
1067
{
1068

1069
  clock_t t;
1070

Cedric Roux's avatar
Cedric Roux committed
1071 1072
  print_current_directory();

1073 1074
  start_background_system();

1075
#ifdef SMBV
1076 1077
  // Rohde&Schwarz SMBV100A vector signal generator
  strcpy(smbv_ip,DEFAULT_SMBV_IP);
1078 1079 1080
#endif

#ifdef PROC
1081 1082
  int node_id;
  int port,Process_Flag=0,wgt,Channel_Flag=0,temp;
1083
#endif
1084

1085
  //default parameters
1086
  oai_emulation.info.n_frames = MAX_FRAME_NUMBER; //1024;          //10;
1087 1088
  oai_emulation.info.n_frames_flag = 0; //fixme
  snr_dB = 30;
knopp's avatar
knopp committed
1089
  NB_UE_INST = 1;
1090

1091 1092 1093
  //Default values if not changed by the user in get_simulation_options();
  pdcp_period = 1;
  omg_period = 1;
1094 1095 1096 1097
  //Clean ip rule table
  for(int i =0; i<NUMBER_OF_UE_MAX; i++){
      char command_line[100];
      sprintf(command_line, "while ip rule del table %d; do true; done",i+201);
Cedric Roux's avatar
Cedric Roux committed
1098 1099 1100 1101
      /* we don't care about return value from system(), but let's the
       * compiler be silent, so let's do "if (XX);"
       */
      if (system(command_line)) /* nothing */;