oaisim_functions.c 61.8 KB
Newer Older
1
/*******************************************************************************
2
    OpenAirInterface
3
    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
    You should have received a copy of the GNU General Public License
17 18
    along with OpenAirInterface.The full GNU General Public License is
    included in this distribution in the file called "COPYING". If not,
19
    see <http://www.gnu.org/licenses/>.
20

21 22 23
   Contact Information
   OpenAirInterface Admin: openair_admin@eurecom.fr
   OpenAirInterface Tech : openair_tech@eurecom.fr
24
   OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
25

ghaddab's avatar
ghaddab committed
26
   Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
27

28
 *******************************************************************************/
29 30 31 32 33 34 35 36 37 38
/*! \file oaisim_functions.c
* \brief function primitives of oaisim
* \author Navid Nikaein 
* \date 2013-2015
* \version 1.0
* \company Eurecom
* \email: openair_tech@eurecom.fr
* \note
* \warning
*/
39 40


41 42 43 44
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
45
#include <execinfo.h>
46
#include <time.h>
Lionel Gauthier's avatar
Lionel Gauthier committed
47
#include <mcheck.h>
48
#include <sys/timerfd.h>
49

50
#include "assertions.h"
51 52 53 54
#include "oaisim_functions.h"

#include "PHY/extern.h"
#include "LAYER2/MAC/extern.h"
55 56
#ifdef OPENAIR2
#include "LAYER2/MAC/proto.h"
57
#endif
58 59 60
#include "LAYER2/PDCP_v10.1.0/pdcp.h"
#include "LAYER2/PDCP_v10.1.0/pdcp_primitives.h"
#include "RRC/LITE/extern.h"
Cedric Roux's avatar
Cedric Roux committed
61
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
62
#include "PHY_INTERFACE/extern.h"
63
//#include "ARCH/CBMIMO1/DEVICE_DRIVER/extern.h"
64
#include "SCHED/extern.h"
Cedric Roux's avatar
Cedric Roux committed
65
#include "SIMULATION/ETH_TRANSPORT/proto.h"
66 67 68
#include "UTIL/OCG/OCG_extern.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
69
#include "UTIL/OTG/otg_config.h"
winckel's avatar
winckel committed
70
#include "UTIL/OTG/otg_tx.h"
71
#if ENABLE_RAL
72 73
#include "lteRALenb.h"
#include "lteRALue.h"
74
#endif
75

Cedric Roux's avatar
Cedric Roux committed
76
#include "cor_SF_sim.h"
77
#include "enb_config.h"
Cedric Roux's avatar
Cedric Roux committed
78

79 80 81 82
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

83 84 85 86
#if defined(ENABLE_USE_MME)
# include "s1ap_eNB.h"
#endif

87
#ifdef SMBV
88
extern uint8_t config_smbv;
89 90 91 92 93 94 95 96 97
extern char smbv_ip[16];
#endif

//constant for OAISIM soft realtime calibration
#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

98 99 100 101
int           otg_times             = 0;
int           if_times              = 0;
int           for_times             = 0;

102
uint16_t           Nid_cell              = 0; //needed by init_lte_vars
103
int           nb_antennas_rx_ue        = 1; // //
104
uint8_t            target_dl_mcs         = 16; // max mcs used by MAC scheduler
105
uint8_t            rate_adaptation_flag  = 0;
106
uint8_t        set_snr         = 0;
107
uint8_t            set_sinr              = 0;
108
double             snr_dB=0, sinr_dB=0;
109 110 111 112
uint8_t            set_seed              = 0;
uint8_t            cooperation_flag;          // for cooperative communication
uint8_t            abstraction_flag      = 0;
uint8_t            ethernet_flag         = 0;
113
double        snr_step              = 1.0;
114
uint8_t            ue_connection_test    = 0;
115
double        forgetting_factor     = 0.0;
116 117 118
uint8_t            beta_ACK              = 0;
uint8_t            beta_RI               = 0;
uint8_t            beta_CQI              = 2;
119
uint8_t            target_ul_mcs         = 16;
Raymond Knopp's avatar
 
Raymond Knopp committed
120
LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs];
121 122
int           map1,map2;
double      **ShaF                  = NULL;
123
// pointers signal buffers (s = transmit, r,r0 = receive)
124
double      **s_re, **s_im, **r_re, **r_im, **r_re0, **r_im0;
125 126
node_list*     ue_node_list          = NULL;
node_list*     enb_node_list         = NULL;
127
int           omg_period            = 10000;
128
int           pdcp_period           = 0;
129
int           cba_backoff           = 30;
130 131
// time calibration for soft realtime mode
struct timespec time_spec;
132 133 134 135 136
unsigned long   time_last           = 0;
unsigned long   time_now            = 0;
int             td                  = 0;
int             td_avg              = 0;
int             sleep_time_us       = 0;
137

Florian Kaltenberger's avatar
Florian Kaltenberger committed
138 139
int phy_test = 0;

140 141 142 143
#ifdef OPENAIR2
// omv related info
//pid_t omv_pid;
char full_name[200];
144
extern int pfd[2]; // fd for omv : fixme: this could be a local var
145 146 147 148 149 150 151 152 153 154 155 156 157
char fdstr[10];
char frames[10];
char num_enb[10];
char num_ue[10];
//area_x, area_y and area_z for omv
char x_area[20];
char y_area[20];
char z_area[20];
char nb_antenna[20];
char frame_type[10];
char tdd_config[10];
#endif

158
Packet_OTG_List_t *otg_pdcp_buffer = NULL;
159 160 161

extern node_desc_t *enb_data[NUMBER_OF_eNB_MAX];
extern node_desc_t *ue_data[NUMBER_OF_UE_MAX];
Raymond Knopp's avatar
 
Raymond Knopp committed
162 163
extern channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs];
extern channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
164 165

extern mapping small_scale_names[];
Lionel Gauthier's avatar
Lionel Gauthier committed
166 167 168 169
#if defined(Rel10)
extern pdcp_mbms_t pdcp_mbms_array_ue[NUMBER_OF_UE_MAX][maxServiceCount][maxSessionPerPMCH];
extern pdcp_mbms_t pdcp_mbms_array_eNB[NUMBER_OF_eNB_MAX][maxServiceCount][maxSessionPerPMCH];
#endif
170

171 172
extern time_stats_t dl_chan_stats;
extern time_stats_t ul_chan_stats;
173

174 175
extern int xforms;

176

177 178 179 180 181 182
extern uint32_t          downlink_frequency[MAX_NUM_CCs][4];
extern int32_t           uplink_frequency_offset[MAX_NUM_CCs][4];

void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst);
void stop_eNB(int nb_inst);

183 184
const Enb_properties_array_t *enb_properties;

185

186 187
void get_simulation_options(int argc, char *argv[])
{
winckel's avatar
winckel committed
188
  int                           option;
189
  char  *conf_config_file_name = NULL;
winckel's avatar
winckel committed
190

winckel's avatar
winckel committed
191
  enum long_option_e {
192
    LONG_OPTION_START = 0x100, /* Start after regular single char options */
winckel's avatar
winckel committed
193

194
    LONG_OPTION_ENB_CONF,
winckel's avatar
winckel committed
195

196 197
    LONG_OPTION_PDNC_PERIOD,
    LONG_OPTION_OMG_PERIOD,
198
    LONG_OPTION_OEH_ENABLED,
winckel's avatar
winckel committed
199

200 201 202 203
    LONG_OPTION_ENB_RAL_LISTENING_PORT,
    LONG_OPTION_ENB_RAL_IP_ADDRESS,
    LONG_OPTION_ENB_RAL_LINK_ID,
    LONG_OPTION_ENB_RAL_LINK_ADDRESS,
winckel's avatar
winckel committed
204

205 206 207
    LONG_OPTION_ENB_MIHF_REMOTE_PORT,
    LONG_OPTION_ENB_MIHF_IP_ADDRESS,
    LONG_OPTION_ENB_MIHF_ID,
winckel's avatar
winckel committed
208

209 210 211 212
    LONG_OPTION_UE_RAL_LISTENING_PORT,
    LONG_OPTION_UE_RAL_IP_ADDRESS,
    LONG_OPTION_UE_RAL_LINK_ID,
    LONG_OPTION_UE_RAL_LINK_ADDRESS,
winckel's avatar
winckel committed
213

214 215 216
    LONG_OPTION_UE_MIHF_REMOTE_PORT,
    LONG_OPTION_UE_MIHF_IP_ADDRESS,
    LONG_OPTION_UE_MIHF_ID,
Lionel Gauthier's avatar
Lionel Gauthier committed
217 218

    LONG_OPTION_MALLOC_TRACE_ENABLED,
219 220

    LONG_OPTION_CBA_BACKOFF_TIMER,
221

Florian Kaltenberger's avatar
Florian Kaltenberger committed
222
    LONG_OPTION_PHYTEST,
223
    LONG_OPTION_XFORMS,
Cedric Roux's avatar
Cedric Roux committed
224 225 226 227

#if T_TRACER
    LONG_OPTION_T_PORT,
    LONG_OPTION_T_NOWAIT,
228
    LONG_OPTION_T_DONT_FORK,
Cedric Roux's avatar
Cedric Roux committed
229
#endif
winckel's avatar
winckel committed
230
  };
winckel's avatar
winckel committed
231

winckel's avatar
winckel committed
232
  static struct option long_options[] = {
233
    {"enb-conf",               required_argument, 0, LONG_OPTION_ENB_CONF},
winckel's avatar
winckel committed
234

235 236 237
    {"pdcp-period",            required_argument, 0, LONG_OPTION_PDNC_PERIOD},
    {"omg-period",             required_argument, 0, LONG_OPTION_OMG_PERIOD},
    {"oeh-enabled",            no_argument, 0, LONG_OPTION_OEH_ENABLED},
winckel's avatar
winckel committed
238

239 240 241 242
    {"enb-ral-listening-port", required_argument, 0, LONG_OPTION_ENB_RAL_LISTENING_PORT},
    {"enb-ral-ip-address",     required_argument, 0, LONG_OPTION_ENB_RAL_IP_ADDRESS},
    {"enb-ral-link-id",        required_argument, 0, LONG_OPTION_ENB_RAL_LINK_ID},
    {"enb-ral-link-address",   required_argument, 0, LONG_OPTION_ENB_RAL_LINK_ADDRESS},
winckel's avatar
winckel committed
243

244 245 246
    {"enb-mihf-remote-port",   required_argument, 0, LONG_OPTION_ENB_MIHF_REMOTE_PORT},
    {"enb-mihf-ip-address",    required_argument, 0, LONG_OPTION_ENB_MIHF_IP_ADDRESS},
    {"enb-mihf-id",            required_argument, 0, LONG_OPTION_ENB_MIHF_ID},
winckel's avatar
winckel committed
247

248 249 250 251
    {"ue-ral-listening-port",  required_argument, 0, LONG_OPTION_UE_RAL_LISTENING_PORT},
    {"ue-ral-ip-address",      required_argument, 0, LONG_OPTION_UE_RAL_IP_ADDRESS},
    {"ue-ral-link-id",         required_argument, 0, LONG_OPTION_UE_RAL_LINK_ID},
    {"ue-ral-link-address",    required_argument, 0, LONG_OPTION_UE_RAL_LINK_ADDRESS},
winckel's avatar
winckel committed
252

253 254 255
    {"ue-mihf-remote-port",    required_argument, 0, LONG_OPTION_UE_MIHF_REMOTE_PORT},
    {"ue-mihf-ip-address",     required_argument, 0, LONG_OPTION_UE_MIHF_IP_ADDRESS},
    {"ue-mihf-id",             required_argument, 0, LONG_OPTION_UE_MIHF_ID},
256

257
    {"malloc-trace-enabled",   no_argument,       0, LONG_OPTION_MALLOC_TRACE_ENABLED},
258

259
    {"cba-backoff",            required_argument, 0, LONG_OPTION_CBA_BACKOFF_TIMER},
260

Florian Kaltenberger's avatar
Florian Kaltenberger committed
261
    {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST},
262
    {"xforms",                 no_argument,       0, LONG_OPTION_XFORMS},
Florian Kaltenberger's avatar
Florian Kaltenberger committed
263

Cedric Roux's avatar
Cedric Roux committed
264 265 266
#if T_TRACER
    {"T_port",                 required_argument, 0, LONG_OPTION_T_PORT},
    {"T_nowait",               no_argument,       0, LONG_OPTION_T_NOWAIT},
267
    {"T_dont_fork",            no_argument,       0, LONG_OPTION_T_DONT_FORK},
Cedric Roux's avatar
Cedric Roux committed
268 269
#endif

270
    {NULL, 0, NULL, 0}
winckel's avatar
winckel committed
271
  };
winckel's avatar
winckel committed
272

273
  while ((option = getopt_long (argc, argv, "aA:b:B:c:C:D:d:eE:f:FGg:hHi:IJ:j:k:K:l:L:m:M:n:N:oO:p:P:qQ:rR:s:S:t:T:u:U:vV:w:W:x:X:y:Y:z:Z:", long_options, NULL)) != -1) {
274
    switch (option) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
275 276 277 278
    case LONG_OPTION_PHYTEST:
      phy_test = 1;
      break;

279 280 281 282 283 284
    case LONG_OPTION_ENB_CONF:
      if (optarg) {
        free(conf_config_file_name); // prevent memory leak if option is used multiple times
        conf_config_file_name = strdup(optarg);
        printf("eNB configuration file is %s\n", conf_config_file_name);
      }
winckel's avatar
winckel committed
285

286
      break;
winckel's avatar
winckel committed
287

288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
    case LONG_OPTION_PDNC_PERIOD:
      if (optarg) {
        pdcp_period = atoi(optarg);
        printf("PDCP period is %d\n", pdcp_period);
      }

      break;

    case LONG_OPTION_OMG_PERIOD:
      if (optarg) {
        omg_period = atoi(optarg);
        printf("OMG period is %d\n", omg_period);
      }

      break;

    case LONG_OPTION_OEH_ENABLED:
      oai_emulation.info.oeh_enabled = 1;
      break;

    case LONG_OPTION_MALLOC_TRACE_ENABLED:
      mtrace();
      break;

    case LONG_OPTION_CBA_BACKOFF_TIMER:
      oai_emulation.info.cba_backoff=atoi(optarg);
      cba_backoff=atoi(optarg);
      printf("setting CBA backoff to %d\n", cba_backoff);
      break;
Lionel Gauthier's avatar
Lionel Gauthier committed
317

318
#if ENABLE_RAL
winckel's avatar
winckel committed
319

320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 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 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430
    case LONG_OPTION_ENB_RAL_LISTENING_PORT:
      if (optarg) {
        g_conf_enb_ral_listening_port = strdup(optarg);
        printf("eNB RAL listening port is %s\n", g_conf_enb_ral_listening_port);
      }

      break;

    case LONG_OPTION_ENB_RAL_IP_ADDRESS:
      if (optarg) {
        g_conf_enb_ral_ip_address = strdup(optarg);
        printf("eNB RAL IP address is %s\n", g_conf_enb_ral_ip_address);
      }

      break;

    case LONG_OPTION_ENB_RAL_LINK_ADDRESS:
      if (optarg) {
        g_conf_enb_ral_link_address = strdup(optarg);
        printf("eNB RAL link address is %s\n", g_conf_enb_ral_link_address);
      }

      break;

    case LONG_OPTION_ENB_RAL_LINK_ID:
      if (optarg) {
        g_conf_enb_ral_link_id = strdup(optarg);
        printf("eNB RAL link id is %s\n", g_conf_enb_ral_link_id);
      }

      break;

    case LONG_OPTION_ENB_MIHF_REMOTE_PORT:
      if (optarg) {
        g_conf_enb_mihf_remote_port = strdup(optarg);
        printf("eNB MIH-F remote port is %s\n", g_conf_enb_mihf_remote_port);
      }

      break;

    case LONG_OPTION_ENB_MIHF_IP_ADDRESS:
      if (optarg) {
        g_conf_enb_mihf_ip_address = strdup(optarg);
        printf("eNB MIH-F IP address is %s\n", g_conf_enb_mihf_ip_address);
      }

      break;

    case LONG_OPTION_ENB_MIHF_ID:
      if (optarg) {
        g_conf_enb_mihf_id = strdup(optarg);
        printf("eNB MIH-F id is %s\n", g_conf_enb_mihf_id);
      }

      break;

    case LONG_OPTION_UE_RAL_LISTENING_PORT:
      if (optarg) {
        g_conf_ue_ral_listening_port = strdup(optarg);
        printf("UE RAL listening port is %s\n", g_conf_ue_ral_listening_port);
      }

      break;

    case LONG_OPTION_UE_RAL_IP_ADDRESS:
      if (optarg) {
        g_conf_ue_ral_ip_address = strdup(optarg);
        printf("UE RAL IP address is %s\n", g_conf_ue_ral_ip_address);
      }

      break;

    case LONG_OPTION_UE_RAL_LINK_ID:
      if (optarg) {
        g_conf_ue_ral_link_id = strdup(optarg);
        printf("UE RAL link id is %s\n", g_conf_ue_ral_link_id);
      }

      break;

    case LONG_OPTION_UE_RAL_LINK_ADDRESS:
      if (optarg) {
        g_conf_ue_ral_link_address = strdup(optarg);
        printf("UE RAL link address is %s\n", g_conf_ue_ral_link_address);
      }

      break;

    case LONG_OPTION_UE_MIHF_REMOTE_PORT:
      if (optarg) {
        g_conf_ue_mihf_remote_port = strdup(optarg);
        printf("UE MIH-F remote port is %s\n", g_conf_ue_mihf_remote_port);
      }

      break;

    case LONG_OPTION_UE_MIHF_IP_ADDRESS:
      if (optarg) {
        g_conf_ue_mihf_ip_address = strdup(optarg);
        printf("UE MIH-F IP address is %s\n", g_conf_ue_mihf_ip_address);
      }

      break;

    case LONG_OPTION_UE_MIHF_ID:
      if (optarg) {
        g_conf_ue_mihf_id = strdup(optarg);
        printf("UE MIH-F id is %s\n", g_conf_ue_mihf_id);
      }

      break;
431
#endif
432

433 434 435 436
    case LONG_OPTION_XFORMS:
      xforms=1;
      break;

Cedric Roux's avatar
Cedric Roux committed
437 438 439 440 441 442 443 444 445 446 447 448 449
#if T_TRACER
    case LONG_OPTION_T_PORT: {
      extern int T_port;
      if (optarg == NULL) abort();  /* should not happen */
      T_port = atoi(optarg);
      break;
    }

    case LONG_OPTION_T_NOWAIT: {
      extern int T_wait;
      T_wait = 0;
      break;
    }
450 451 452 453 454 455

    case LONG_OPTION_T_DONT_FORK: {
      extern int T_dont_fork;
      T_dont_fork = 1;
      break;
    }
Cedric Roux's avatar
Cedric Roux committed
456 457
#endif

458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536
    case 'a':
      abstraction_flag = 1;
      break;

    case 'A':

      //oai_emulation.info.ocm_enabled=1;
      if (optarg == NULL)
        oai_emulation.environment_system_config.fading.small_scale.selected_option="AWGN";
      else
        oai_emulation.environment_system_config.fading.small_scale.selected_option= optarg;

      //awgn_flag = 1;
      break;

    case 'b':
      oai_emulation.info.nb_enb_local = atoi (optarg);
      break;

    case 'B':
      oai_emulation.topology_config.mobility.eNB_mobility.eNB_mobility_type.selected_option = optarg;
      //oai_emulation.info.omg_model_enb = atoi (optarg);
      break;

    case 'c':
      //strcpy(oai_emulation.info.local_server, optarg);
      strncpy(oai_emulation.info.local_server, optarg, sizeof(oai_emulation.info.local_server));
      oai_emulation.info.local_server[sizeof(oai_emulation.info.local_server) - 1] = 0; // terminate string
      oai_emulation.info.ocg_enabled=1;
      break;

    case 'C':
      oai_emulation.info.tdd_config[0] = atoi (optarg);
      AssertFatal (oai_emulation.info.tdd_config[0] <= TDD_Config__subframeAssignment_sa6, "Illegal tdd_config %d (should be 0-%d)!",
                   oai_emulation.info.tdd_config[0], TDD_Config__subframeAssignment_sa6);
      break;

    case 'D':
      oai_emulation.info.multicast_ifname = strdup(optarg);
      break;

    case 'e':
      oai_emulation.info.extended_prefix_flag[0] = 1;
      break;

    case 'E':
      set_seed = 1;
      oai_emulation.info.seed = atoi (optarg);
      break;

    case 'f':
      forgetting_factor = atof (optarg);
      break;

    case 'F':                   // set FDD
      printf("Setting Frame to FDD\n");
      oai_emulation.info.frame_type[0] = 0;
      oai_emulation.info.frame_type_name[0] = "FDD";
      break;

    case 'g':
      oai_emulation.info.multicast_group = atoi (optarg);
      break;

    case 'G' :
      oai_emulation.info.otg_bg_traffic_enabled = 1;
      break;

    case 'h':
      help ();
      exit (1);
      break;

    case 'H':
      oai_emulation.info.handover_active=1;
      printf("Activate the handover procedure at RRC\n");
      break;

    case 'i':
winckel's avatar
winckel committed
537
#ifdef PROC
538 539 540
      Process_Flag=1;
      node_id = wgt+atoi(optarg);
      port+=atoi(optarg);
winckel's avatar
winckel committed
541
#endif
542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 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
      break;

    case 'I':
      oai_emulation.info.cli_enabled = 1;
      break;

    case 'j' :
      // number of relay nodes: currently only applicable to eMBMS
      oai_emulation.info.nb_rn_local = atoi (optarg);
      break;

    case 'J':
      ue_connection_test=1;
      oai_emulation.info.ocm_enabled=0;
      snr_step = atof(optarg);
      break;

    case 'k':
      //ricean_factor = atof (optarg);
      printf("[SIM] Option k is no longer supported on the command line. Please specify your channel model in the xml template\n");
      exit(-1);
      break;

    case 'K':
      oai_emulation.info.itti_dump_file = optarg;
      break;

    case 'l':
      oai_emulation.info.g_log_level = atoi(optarg);
      break;

    case 'L':                   // set FDD
      flag_LA = atoi(optarg);
      break;

    case 'm':
      target_dl_mcs = atoi (optarg);
      printf("Max target downlink MCS used by MAC scheduler is set to %d\n", target_dl_mcs);
      break;

    case 'M':
      abstraction_flag = 1;
      ethernet_flag = 1;
      oai_emulation.info.ethernet_id = atoi (optarg);
      oai_emulation.info.master_id = oai_emulation.info.ethernet_id;
      oai_emulation.info.ethernet_flag = 1;
      break;

    case 'n':
      oai_emulation.info.n_frames = atoi (optarg);
      oai_emulation.emulation_config.emulation_time_ms= oai_emulation.info.n_frames * 10; // 10 ms frame
      //n_frames = (n_frames >1024) ? 1024: n_frames; // adjust the n_frames if higher that 1024
      oai_emulation.info.n_frames_flag = 1;
      break;

    case 'N':
      Nid_cell = atoi (optarg);

      if (Nid_cell > 503) {
        printf("Illegal Nid_cell %d (should be 0 ... 503)\n", Nid_cell);
winckel's avatar
winckel committed
602
        exit(-1);
603
      }
604

605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715
      break;

    case 'O':
      if (optarg) {
        free(conf_config_file_name); // prevent memory leak if option is used multiple times
        conf_config_file_name = strdup(optarg);
      }

      break;

    case 'o':
      oai_emulation.info.slot_isr = 1;
      break;

    case 'p':
      oai_emulation.info.nb_master = atoi (optarg);
      break;

    case 'P':
      oai_emulation.info.opt_enabled = 1;
      opt_enabled = 1;

      if (strcmp(optarg, "wireshark") == 0) {
        opt_type = OPT_WIRESHARK;
        printf("Enabling OPT for wireshark\n");
      } else if (strcmp(optarg, "pcap") == 0) {
        opt_type = OPT_PCAP;
        printf("Enabling OPT for pcap\n");
      } else {
        printf("Unrecognized option for OPT module. -> Disabling it\n");
        printf("Possible values are either wireshark or pcap\n");
        opt_type = OPT_NONE;
        oai_emulation.info.opt_enabled = 0;
        opt_enabled = 0;
      }

      oai_emulation.info.opt_mode = opt_type;
      break;

    case 'q':
      // openair performane profiler
      oai_emulation.info.opp_enabled = 1; // this var is used for OCG
      opp_enabled = 1; // this is the global var used by oaisim
      break;

    case 'Q':
      //eMBMS_active=1;
      // 0 : not used (default), 1: eMBMS and RRC enabled, 2: eMBMS relaying and RRC enabled, 3: eMBMS enabled, RRC disabled, 4: eMBMS relaying enabled, RRC disabled
      oai_emulation.info.eMBMS_active_state = atoi (optarg);
      break;

    case 'r':
      rate_adaptation_flag = 1;
      break;

    case 'R':
      oai_emulation.info.N_RB_DL[0] = atoi (optarg);

      if ((oai_emulation.info.N_RB_DL[0] != 6) && (oai_emulation.info.N_RB_DL[0] != 15) && (oai_emulation.info.N_RB_DL[0] != 25)
          && (oai_emulation.info.N_RB_DL[0] != 50) && (oai_emulation.info.N_RB_DL[0] != 75) && (oai_emulation.info.N_RB_DL[0] != 100)) {
        printf("Illegal N_RB_DL %d (should be one of 6,15,25,50,75,100)\n", oai_emulation.info.N_RB_DL[0]);
        exit (-1);
      }

      break;

    case 's':
      snr_dB = atoi (optarg);
      //      set_snr = 1;
      oai_emulation.info.ocm_enabled=0;
      break;

    case 'S':
      sinr_dB = atoi (optarg);
      set_sinr = 1;
      oai_emulation.info.ocm_enabled=0;
      break;

    case 't':
      target_ul_mcs = atoi (optarg);
      printf("Max target uplink MCS used by MAC scheduler is set to %d\n", target_ul_mcs);
      break;

    case 'T':
      oai_emulation.info.otg_enabled = 1;
      oai_emulation.info.otg_traffic = optarg;
      break;

    case 'u':
      oai_emulation.info.nb_ue_local = atoi (optarg);
      break;

    case 'U':
      oai_emulation.topology_config.mobility.UE_mobility.UE_mobility_type.selected_option = optarg;
      break;

    case 'v':
      oai_emulation.info.omv_enabled = 1;
      break;

    case 'V':
      ouput_vcd = 1;
      oai_emulation.info.vcd_enabled = 1;
      oai_emulation.info.vcd_file = optarg;
      break;

    case 'w':
      oai_emulation.info.cba_group_active = atoi (optarg);
      break;

    case 'W':
716
#ifdef SMBV
717 718 719 720 721
      config_smbv = 1;

      if(atoi(optarg)!=0)
        strcpy(smbv_ip,optarg);

722
#endif
723
      break;
winckel's avatar
winckel committed
724

725
    case 'x':
726
      /*
727 728 729 730 731 732 733
      oai_emulation.info.transmission_mode[0] = atoi (optarg);

      if ((oai_emulation.info.transmission_mode[0] != 1) &&  (oai_emulation.info.transmission_mode[0] != 2) && (oai_emulation.info.transmission_mode[0] != 3)
          && (oai_emulation.info.transmission_mode[0] != 5) && (oai_emulation.info.transmission_mode[0] != 6)) {
        printf("Unsupported transmission mode %d\n",oai_emulation.info.transmission_mode[0]);
        exit(-1);
      }
734 735 736
      */
      printf("Option -x deprecated. Please set transmission mode in eNB config file\n");
      exit(-1);
winckel's avatar
winckel committed
737

738 739 740
      break;

    case 'X':
winckel's avatar
winckel committed
741
#ifdef PROC
742 743 744 745 746 747 748 749 750 751 752 753 754 755 756
      temp=atoi(optarg);

      if(temp==0) {
        port=CHANNEL_PORT;
        Channel_Flag=1;
        Process_Flag=0;
        wgt=0;
      } else if(temp==1) {
        port=eNB_PORT;
        wgt=0;
      } else {
        port=UE_PORT;
        wgt=MAX_eNB;
      }

winckel's avatar
winckel committed
757
#endif
758
      break;
winckel's avatar
winckel committed
759

760
    case 'y':
761
      nb_antennas_rx_ue=atoi(optarg);
winckel's avatar
winckel committed
762

763
      if (nb_antennas_rx_ue>4) {
764 765 766
        printf("Cannot have more than 4 antennas\n");
        exit(-1);
      }
winckel's avatar
winckel committed
767

768
      break;
winckel's avatar
winckel committed
769

770 771 772
    case 'Y':
      oai_emulation.info.g_log_verbosity_option = strdup(optarg);
      break;
winckel's avatar
winckel committed
773

774 775 776 777 778 779 780 781 782 783 784 785 786
    case 'z':
      cooperation_flag = atoi (optarg);
      break;

    case 'Z':
      /* Sebastien ROUX: Reserved for future use (currently used in ltenow branch) */
      break;

    default:
      help ();
      exit (-1);
      break;
    }
winckel's avatar
winckel committed
787
  }
788

789 790 791
  if ((oai_emulation.info.nb_enb_local > 0) && (conf_config_file_name != NULL)) {
    /* Read eNB configuration file */
    enb_properties = enb_config_init(conf_config_file_name);
792

793 794 795
    AssertFatal (oai_emulation.info.nb_enb_local <= enb_properties->number,
                 "Number of eNB is greater than eNB defined in configuration file %s (%d/%d)!",
                 conf_config_file_name, oai_emulation.info.nb_enb_local, enb_properties->number);
Raymond Knopp's avatar
Raymond Knopp committed
796
    
797
    /* Update some simulation parameters */
798 799 800
    oai_emulation.info.frame_type[0]           = enb_properties->properties[0]->frame_type[0];
    oai_emulation.info.tdd_config[0]           = enb_properties->properties[0]->tdd_config[0];
    oai_emulation.info.tdd_config_S[0]         = enb_properties->properties[0]->tdd_config_s[0];
801
    oai_emulation.info.extended_prefix_flag[0] = enb_properties->properties[0]->prefix_type[0];
Raymond Knopp's avatar
Raymond Knopp committed
802

803 804 805 806
    oai_emulation.info.node_function[0]        = enb_properties->properties[0]->cc_node_function[0];
    oai_emulation.info.node_timing[0]          = enb_properties->properties[0]->cc_node_timing[0];
    downlink_frequency[0][0]                   = enb_properties->properties[0]->downlink_frequency[0];
    uplink_frequency_offset[0][0]              = enb_properties->properties[0]->uplink_frequency_offset[0];
807
  }
808

809 810
  free(conf_config_file_name);
  conf_config_file_name = 0;
811 812
}

813 814
void check_and_adjust_params(void)
{
815

816
  int32_t ret;
817 818
  int i,j;

819
  if (oai_emulation.info.nb_ue_local  + oai_emulation.info.nb_rn_local > NUMBER_OF_UE_MAX) {
820 821
    LOG_E(EMU,"Enter fewer than %d UEs/RNs for the moment or change the NUMBER_OF_UE_MAX\n", NUMBER_OF_UE_MAX);
    exit(EXIT_FAILURE);
822 823
  }

824
  if (oai_emulation.info.nb_enb_local + oai_emulation.info.nb_rn_local > NUMBER_OF_eNB_MAX) {
825 826
    LOG_E(EMU,"Enter fewer than %d eNBs/RNs for the moment or change the NUMBER_OF_UE_MAX\n", NUMBER_OF_eNB_MAX);
    exit(EXIT_FAILURE);
827
  }
828

829
  if (oai_emulation.info.nb_rn_local > NUMBER_OF_RN_MAX) {
830 831
    LOG_E(EMU,"Enter fewer than %d RNs for the moment or change the NUMBER_OF_RN_MAX\n", NUMBER_OF_RN_MAX);
    exit(EXIT_FAILURE);
832
  }
833

834 835 836 837 838 839 840 841 842 843 844
  // fix ethernet and abstraction with RRC_CELLULAR Flag
#ifdef RRC_CELLULAR
  abstraction_flag = 1;
  ethernet_flag = 1;
#endif

  if (set_sinr == 0)
    sinr_dB = snr_dB - 20;

  // setup netdevice interface (netlink socket)
  LOG_I(EMU,"[INIT] Starting NAS netlink interface\n");
Cedric Roux's avatar
Cedric Roux committed
845
  ret = netlink_init();
846

847
  if (ret < 0)
848
    LOG_W(EMU,"[INIT] Netlink not available, careful ...\n");
849 850

  if (ethernet_flag == 1) {
851 852
    oai_emulation.info.master[oai_emulation.info.master_id].nb_ue = oai_emulation.info.nb_ue_local + oai_emulation.info.nb_rn_local;
    oai_emulation.info.master[oai_emulation.info.master_id].nb_enb = oai_emulation.info.nb_enb_local + oai_emulation.info.nb_rn_local;
853

854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876
    if (oai_emulation.info.nb_rn_local>0)
      LOG_N(EMU,"Ethernet emulation is not yet tested with the relay nodes\n");

    if (!oai_emulation.info.master_id)
      oai_emulation.info.is_primary_master = 1;

    j = 1;

    for (i = 0; i < oai_emulation.info.nb_master; i++) {
      if (i != oai_emulation.info.master_id)
        oai_emulation.info.master_list = oai_emulation.info.master_list + j;

      LOG_I (EMU, "Index of master id i=%d  MASTER_LIST %d\n", i, oai_emulation.info.master_list);
      j *= 2;
    }

    LOG_I (EMU, " Total number of master %d my master id %d\n", oai_emulation.info.nb_master, oai_emulation.info.master_id);
    init_bypass ();

    while (emu_tx_status != SYNCED_TRANSPORT) {
      LOG_I (EMU, " Waiting for EMU Transport to be synced\n");
      emu_transport_sync ();    //emulation_tx_rx();
    }
877 878
  } // ethernet flag

879
  //
880 881
  NB_UE_INST = oai_emulation.info.nb_ue_local + oai_emulation.info.nb_ue_remote;
  NB_eNB_INST = oai_emulation.info.nb_enb_local + oai_emulation.info.nb_enb_remote;
882 883
  NB_RN_INST = oai_emulation.info.nb_rn_local + oai_emulation.info.nb_rn_remote;

884
#if defined(PDCP_USE_NETLINK_QUEUES) && defined(OPENAIR2)
885 886 887
  pdcp_netlink_init();
#endif

888
  if (NB_RN_INST > 0 ) {
889 890
    LOG_N(EMU,"Total number of RN %d (local %d, remote %d) mobility (the same as eNB) %s  \n", NB_RN_INST,oai_emulation.info.nb_rn_local,oai_emulation.info.nb_rn_remote,
          oai_emulation.topology_config.mobility.eNB_mobility.eNB_mobility_type.selected_option);
891

892
    LOG_N(EMU,"Adjust the number of eNB inst (%d->%d) and UE inst (%d->%d)\n ",
893 894
          NB_eNB_INST, NB_eNB_INST+NB_RN_INST,
          NB_UE_INST, NB_UE_INST+NB_RN_INST);
895 896
    NB_eNB_INST+=NB_RN_INST;
    NB_UE_INST+=NB_RN_INST;
897
  }
898

899
  LOG_I(EMU,"Total number of UE %d (first local %d , num local %d, remote %d, relay %d) mobility %s \n",
900 901 902
        NB_UE_INST,oai_emulation.info.first_ue_local, oai_emulation.info.nb_ue_local,oai_emulation.info.nb_ue_remote,
        NB_RN_INST,
        oai_emulation.topology_config.mobility.UE_mobility.UE_mobility_type.selected_option);
903 904

  LOG_I(EMU,"Total number of eNB %d (local %d, remote %d, relay %d) mobility %s \n",
905 906 907
        NB_eNB_INST,oai_emulation.info.nb_enb_local,oai_emulation.info.nb_enb_remote,
        NB_RN_INST,
        oai_emulation.topology_config.mobility.eNB_mobility.eNB_mobility_type.selected_option);
908

909 910
}

911
#ifdef OPENAIR2
912 913
void init_omv(void)
{
914 915
  if (oai_emulation.info.omv_enabled == 1) {

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
    if(pipe(pfd) == -1)
      perror("pipe error \n");

    snprintf( full_name, sizeof(full_name), "%s/UTIL/OMV/OMV",getenv("OPENAIR2_DIR") );
    LOG_I(EMU,"Stating the OMV path %s pfd[0] %d pfd[1] %d \n", full_name, pfd[0],pfd[1]);

    switch(fork()) {
    case -1 :
      perror("fork failed \n");
      break;

    case 0 : // child is going to be the omv, it is the reader
      if(close(pfd[1]) == -1 ) // we close the write desc.
        perror("close on write\n" );

      sprintf(fdstr, "%d", pfd[0] );
      sprintf(num_enb, "%d", NB_eNB_INST);
      sprintf(num_ue, "%d", NB_UE_INST);
      sprintf(x_area, "%f", oai_emulation.topology_config.area.x_m );
      sprintf(y_area, "%f", oai_emulation.topology_config.area.y_m );
      sprintf(z_area, "%f", 200.0 );
      sprintf(frames, "%d", oai_emulation.info.n_frames);
      sprintf(nb_antenna, "%d", 4);
      sprintf(frame_type, "%s", (oai_emulation.info.frame_type[0] == 0) ? "FDD" : "TDD");
      sprintf(tdd_config, "%d", oai_emulation.info.tdd_config[0]);
      // execl is used to launch the visualisor
      execl(full_name,"OMV", fdstr, frames, num_enb, num_ue, x_area, y_area, z_area, nb_antenna, frame_type, tdd_config,NULL );
      perror( "error in execl the OMV" );
    }

    //parent
    if(close( pfd[0] ) == -1 ) // we close the write desc.
      perror("close on read\n" );
949 950
  }
}
951
#endif
952

953 954
void init_seed(uint8_t set_seed)
{
955 956 957

  if(set_seed) {

958 959
    randominit (oai_emulation.info.seed);
    set_taus_seed (oai_emulation.info.seed);
960 961

  } else {
962 963
    randominit (0);
    set_taus_seed (0);
964 965 966
  }
}

967 968 969 970 971
openair0_timestamp current_eNB_rx_timestamp[NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
openair0_timestamp current_UE_rx_timestamp[NUMBER_OF_UE_MAX][MAX_NUM_CCs];
openair0_timestamp last_eNB_rx_timestamp[NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
openair0_timestamp last_UE_rx_timestamp[NUMBER_OF_UE_MAX][MAX_NUM_CCs];

972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004
int eNB_trx_start(openair0_device *device) {
  return(0);
}

void eNB_trx_end(openair0_device *device) {
  return;
}

int eNB_trx_stop(openair0_device *device) {
  return(0);
}
int UE_trx_start(openair0_device *device) {
  return(0);
}
int UE_trx_end(openair0_device *device) {
  return(0);
}
int UE_trx_stop(openair0_device *device) {
  return(0);
}
int eNB_trx_set_freq(openair0_device *device, openair0_config_t *openair0_cfg, int dummy) {
  return(0);
}
int eNB_trx_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) {
  return(0);
}
int UE_trx_set_freq(openair0_device *device, openair0_config_t *openair0_cfg, int dummy) {
  return(0);
}
int UE_trx_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) {
  return(0);
}

1005 1006
extern pthread_mutex_t subframe_mutex;
extern int subframe_eNB_mask,subframe_UE_mask;
1007

1008
int eNB_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) {
1009 1010 1011 1012

  int eNB_id = device->Mod_id;
  int CC_id  = device->CC_id;

1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041
  int subframe;
  int sample_count=0;

  *ptimestamp = last_eNB_rx_timestamp[eNB_id][CC_id];

  LOG_D(PHY,"eNB_trx_read nsamps %d TS(%llu,%llu) => subframe %d\n",nsamps,
        (unsigned long long)current_eNB_rx_timestamp[eNB_id][CC_id],
        (unsigned long long)last_eNB_rx_timestamp[eNB_id][CC_id],
	(*ptimestamp/PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti)%10);
  // if we're at a subframe boundary generate UL signals for this eNB

  while (sample_count<nsamps) {
    while (current_eNB_rx_timestamp[eNB_id][CC_id]<
	   (nsamps+last_eNB_rx_timestamp[eNB_id][CC_id])) {
      LOG_D(EMU,"eNB: current TS %llu, last TS %llu, sleeping\n",current_eNB_rx_timestamp[eNB_id][CC_id],last_eNB_rx_timestamp[eNB_id][CC_id]);
      usleep(500);
    }

    // tell top-level we are busy
    pthread_mutex_lock(&subframe_mutex);
    subframe_eNB_mask|=(1<<eNB_id);
    pthread_mutex_unlock(&subframe_mutex); 
    
    subframe = (last_eNB_rx_timestamp[eNB_id][CC_id]/PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti)%10;
    LOG_D(PHY,"eNB_trx_read generating UL subframe %d (Ts %llu, current TS %llu)\n",
	  subframe,(unsigned long long)*ptimestamp,
	  (unsigned long long)current_eNB_rx_timestamp[eNB_id][CC_id]);
    
    do_UL_sig(UE2eNB,
1042 1043 1044
	      enb_data,
	      ue_data,
	      subframe,
1045
	      0,  // abstraction_flag
1046
	      &PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms,
1047 1048
	      0,  // frame is only used for abstraction
	      eNB_id,
1049
	      CC_id);
1050 1051 1052
  
    last_eNB_rx_timestamp[eNB_id][CC_id] += PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti;
    sample_count += PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti;
1053
  }
1054 1055
  

1056 1057

  return(nsamps);
1058 1059
}

1060
int UE_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) {
1061 1062 1063

  int UE_id = device->Mod_id;
  int CC_id  = device->CC_id;
1064 1065 1066 1067 1068 1069
  int subframe;
  int sample_count=0;
  int read_size;

  *ptimestamp = last_UE_rx_timestamp[UE_id][CC_id];

1070
  LOG_D(EMU,"UE_trx_read nsamps %d TS(%llu,%llu) antenna %d\n",nsamps,
1071
        (unsigned long long)current_UE_rx_timestamp[UE_id][CC_id],
1072 1073
        (unsigned long long)last_UE_rx_timestamp[UE_id][CC_id],
	cc);
1074 1075 1076 1077 1078 1079 1080 1081 1082 1083

  if (nsamps < PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti)
    read_size = nsamps;
  else
    read_size = PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti;

  while (sample_count<nsamps) {
    while (current_UE_rx_timestamp[UE_id][CC_id] < 
	   (last_UE_rx_timestamp[UE_id][CC_id]+read_size)) {
      LOG_D(EMU,"UE_trx_read : current TS %d, last TS %d, sleeping\n",current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]);
1084

1085 1086
      usleep(500);
    }
1087

1088 1089 1090 1091 1092 1093
    LOG_D(EMU,"UE_trx_read : current TS %d, last TS %d, sleeping\n",current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]);
      
    // tell top-level we are busy 
    pthread_mutex_lock(&subframe_mutex);
    subframe_UE_mask|=(1<<UE_id);
    pthread_mutex_unlock(&subframe_mutex);
1094

1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110

    // otherwise we have one subframe here so generate the received signal
    subframe = (last_UE_rx_timestamp[UE_id][CC_id]/PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti)%10;
    if ((last_UE_rx_timestamp[UE_id][CC_id]%PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti) > 0)
      subframe++;

    last_UE_rx_timestamp[UE_id][CC_id] += read_size;
    sample_count += read_size;
 
    if (subframe > 9) 
      return(nsamps);

    LOG_D(PHY,"UE_trx_read generating DL subframe %d (Ts %llu, current TS %llu)\n",
	  subframe,(unsigned long long)*ptimestamp,
	  (unsigned long long)current_UE_rx_timestamp[UE_id][CC_id]);    
    do_DL_sig(eNB2UE,
1111 1112 1113
	      enb_data,
	      ue_data,
	      subframe,
1114 1115 1116
	      0, //abstraction_flag,
	      &PHY_vars_UE_g[UE_id][CC_id]->frame_parms,
	      UE_id,
1117
	      CC_id);
1118 1119


1120
  }
1121 1122


1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133
  return(nsamps);
}

int eNB_trx_write(openair0_device *device,openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {

  return(nsamps);
}

int UE_trx_write(openair0_device *device,openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {

  return(nsamps);
1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151
}

void init_devices(void){

  module_id_t UE_id, eNB_id;
  uint8_t CC_id;

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    for (eNB_id=0;eNB_id<NB_eNB_INST;eNB_id++) {
      PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.Mod_id             = eNB_id;
      PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.CC_id              = CC_id;
      PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_start_func     = eNB_trx_start;
      PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_read_func      = eNB_trx_read;
      PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_write_func     = eNB_trx_write;
      PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_end_func       = eNB_trx_end;
      PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_stop_func      = eNB_trx_stop;
      PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_set_freq_func  = eNB_trx_set_freq;
      PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_set_gains_func = eNB_trx_set_gains;
1152 1153
      current_eNB_rx_timestamp[eNB_id][CC_id] = PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti;
      last_eNB_rx_timestamp[eNB_id][CC_id] = 0;
1154
    }
1155
    for (UE_id=0;UE_id<NB_UE_INST;UE_id++) {
1156 1157 1158 1159 1160 1161 1162 1163 1164
      PHY_vars_UE_g[UE_id][CC_id]->rfdevice.Mod_id               = UE_id;
      PHY_vars_UE_g[UE_id][CC_id]->rfdevice.CC_id                = CC_id;
      PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_start_func       = UE_trx_start;
      PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_read_func        = UE_trx_read;
      PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_write_func       = UE_trx_write;
      PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_end_func         = UE_trx_end;
      PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_stop_func        = UE_trx_stop;
      PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_set_freq_func    = UE_trx_set_freq;
      PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_set_gains_func   = UE_trx_set_gains;
1165 1166 1167
      current_UE_rx_timestamp[UE_id][CC_id] = PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti;
      last_UE_rx_timestamp[UE_id][CC_id] = 0;

1168 1169 1170 1171
    }
  }
}

1172 1173
void init_openair1(void)
{
Lionel Gauthier's avatar
Lionel Gauthier committed
1174
  module_id_t UE_id, eNB_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1175
  uint8_t CC_id;
1176
#if ENABLE_RAL
1177 1178
  int list_index;
#endif
1179

1180
  // change the nb_connected_eNB
1181
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1182 1183 1184 1185 1186 1187 1188 1189 1190 1191
    init_lte_vars (&frame_parms[CC_id], 
		   oai_emulation.info.frame_type[CC_id], 
		   oai_emulation.info.tdd_config[CC_id], 
		   oai_emulation.info.tdd_config_S[CC_id],
		   oai_emulation.info.extended_prefix_flag[CC_id],
                   oai_emulation.info.N_RB_DL[CC_id], 
		   Nid_cell, 
		   cooperation_flag, 
		   enb_properties->properties[0]->nb_antenna_ports[CC_id], 
		   abstraction_flag,
1192
		   enb_properties->properties[0]->nb_antennas_rx[CC_id],
1193 1194
		   enb_properties->properties[0]->nb_antennas_tx[CC_id],
		   nb_antennas_rx_ue,
1195
		   oai_emulation.info.eMBMS_active_state);
Raymond Knopp's avatar
 
Raymond Knopp committed
1196
  }
1197

1198 1199 1200 1201 1202 1203
  for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) {
    for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
        PHY_vars_eNB_g[eNB_id][CC_id]->pusch_config_dedicated[UE_id].betaOffset_ACK_Index = beta_ACK;
        PHY_vars_eNB_g[eNB_id][CC_id]->pusch_config_dedicated[UE_id].betaOffset_RI_Index  = beta_RI;
        PHY_vars_eNB_g[eNB_id][CC_id]->pusch_config_dedicated[UE_id].betaOffset_CQI_Index = beta_CQI;
1204
        PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.pdsch_config_common.p_b = (frame_parms[CC_id]->nb_antennas_tx_eNB>1) ? 1 : 0; // rho_A = rho_B
1205 1206 1207 1208

        PHY_vars_UE_g[UE_id][CC_id]->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index = beta_ACK;
        PHY_vars_UE_g[UE_id][CC_id]->pusch_config_dedicated[eNB_id].betaOffset_RI_Index  = beta_RI;
        PHY_vars_UE_g[UE_id][CC_id]->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index = beta_CQI;
1209
        PHY_vars_UE_g[UE_id][CC_id]->frame_parms.pdsch_config_common.p_b = (frame_parms[CC_id]->nb_antennas_tx_eNB>1) ? 1 : 0; // rho_A = rho_B
1210
      }
1211
    }
1212 1213
  }

1214 1215
  printf ("AFTER init: MAX_NUM_CCs %d, Nid_cell %d frame_type %d,tdd_config %d\n",
          MAX_NUM_CCs,
1216 1217 1218
          PHY_vars_eNB_g[0][0]->frame_parms.Nid_cell,
          PHY_vars_eNB_g[0][0]->frame_parms.frame_type,
          PHY_vars_eNB_g[0][0]->frame_parms.tdd_config);
1219 1220 1221

  number_of_cards = 1;

1222 1223 1224
//  openair_daq_vars.rx_rf_mode = 1;
//  openair_daq_vars.tdd = 1;
//  openair_daq_vars.rx_gain_mode = DAQ_AGC_ON;
1225

1226
//  openair_daq_vars.dlsch_transmission_mode = oai_emulation.info.transmission_mode[0];
Cedric Roux's avatar
Cedric Roux committed
1227
//#warning "NN->FK: OAI EMU channel abstraction does not work for MCS higher than"
1228 1229 1230 1231 1232
//  openair_daq_vars.target_ue_dl_mcs = cmin(target_dl_mcs,16);
//  openair_daq_vars.target_ue_ul_mcs = target_ul_mcs;
//  openair_daq_vars.ue_dl_rb_alloc=0x1fff;
//  openair_daq_vars.ue_ul_nb_rb=6;
//  openair_daq_vars.dlsch_rate_adaptation = rate_adaptation_flag;
1233

1234
  //N_TA_offset
1235 1236
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
1237 1238 1239 1240 1241

      PHY_vars_UE_g[UE_id][CC_id]->use_ia_receiver      = 0;
      PHY_vars_UE_g[UE_id][CC_id]->mode                 = normal_txrx;
      PHY_vars_UE_g[UE_id][CC_id]->mac_enabled          = 1;
      PHY_vars_UE_g[UE_id][CC_id]->no_timing_correction = 1;
1242

1243 1244
      if (PHY_vars_UE_g[UE_id][CC_id]->frame_parms.frame_type == TDD) {
        if (PHY_vars_UE_g[UE_id][CC_id]->frame_parms.N_RB_DL == 100)
1245
          PHY_vars_UE_g[UE_id][CC_id]->N_TA_offset = 624;
1246
        else if (PHY_vars_UE_g[UE_id][CC_id]->frame_parms.N_RB_DL == 50)
1247
          PHY_vars_UE_g[UE_id][CC_id]->N_TA_offset = 624/2;
1248
        else if (PHY_vars_UE_g[UE_id][CC_id]->frame_parms.N_RB_DL == 25)
1249 1250 1251
          PHY_vars_UE_g[UE_id][CC_id]->N_TA_offset = 624/4;
      } else {
        PHY_vars_UE_g[UE_id][CC_id]->N_TA_offset = 0;
1252 1253
      }
    }
1254 1255

    for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) {
1256 1257
      if (PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.frame_type == TDD) {
        if (PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.N_RB_DL == 100)
1258
          PHY_vars_eNB_g[eNB_id][CC_id]->N_TA_offset = 624;
1259
        else if (PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.N_RB_DL == 50)
1260
          PHY_vars_eNB_g[eNB_id][CC_id]->N_TA_offset = 624/2;
1261
        else if (PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.N_RB_DL == 25)
1262 1263 1264
          PHY_vars_eNB_g[eNB_id][CC_id]->N_TA_offset = 624/4;
      } else {
        PHY_vars_eNB_g[eNB_id][CC_id]->N_TA_offset = 0;
1265
      }
Raymond Knopp's avatar
Raymond Knopp committed
1266 1267
    } // eNB_id
  } // CC_id
1268

Raymond Knopp's avatar
Raymond Knopp committed
1269
  for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1270 1271 1272 1273 1274 1275
    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
      if (phy_test==1)
	PHY_vars_eNB_g[eNB_id][CC_id]->mac_enabled=0;
      else
	PHY_vars_eNB_g[eNB_id][CC_id]->mac_enabled=1;
    }
Raymond Knopp's avatar
Raymond Knopp committed
1276 1277
  }

1278 1279 1280
  init_devices ();

  init_eNB(oai_emulation.info.node_function,oai_emulation.info.node_timing,NB_eNB_INST);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1281

1282
  // init_ue_status();
Raymond Knopp's avatar
Raymond Knopp committed
1283
  for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
1284
    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
Raymond Knopp committed
1285
      
hbilel's avatar
hbilel committed
1286
      PHY_vars_UE_g[UE_id][CC_id]->tx_power_max_dBm=10;
Raymond Knopp's avatar
Raymond Knopp committed
1287
      
1288
      PHY_vars_UE_g[UE_id][CC_id]->rx_total_gain_dB=100;
1289

1290 1291
      // update UE_mode for each eNB_id not just 0
      if (abstraction_flag == 0)
Raymond Knopp's avatar
 
Raymond Knopp committed
1292
        PHY_vars_UE_g[UE_id][CC_id]->UE_mode[0] = NOT_SYNCHED;
1293
      else {
1294 1295
        // 0 is the index of the connected eNB
        PHY_vars_UE_g[UE_id][CC_id]->UE_mode[0] = PRACH;
1296
      }
1297

Florian Kaltenberger's avatar
Florian Kaltenberger committed
1298 1299 1300 1301 1302
      if (phy_test==1)
	PHY_vars_UE_g[UE_id][CC_id]->mac_enabled=0;
      else
	PHY_vars_UE_g[UE_id][CC_id]->mac_enabled=1;

1303
      PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[0]->crnti = 0x1235 + UE_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1304
      PHY_vars_UE_g[UE_id][CC_id]->current_dlsch_cqi[0] = 10;
1305

Raymond Knopp's avatar
 
Raymond Knopp committed
1306
      LOG_I(EMU, "UE %d mode is initialized to %d\n", UE_id, PHY_vars_UE_g[UE_id][CC_id]->UE_mode[0] );
1307
#if ENABLE_RAL
Raymond Knopp's avatar
 
Raymond Knopp committed
1308
      PHY_vars_UE_g[UE_id][CC_id]->ral_thresholds_timed = hashtable_create (64, NULL, NULL);
1309

1310
      for (list_index = 0; list_index < RAL_LINK_PARAM_GEN_MAX; list_index++) {
1311
        SLIST_INIT(&PHY_vars_UE_g[UE_id][CC_id]->ral_thresholds_gen_polled[list_index]);
1312
      }
1313

1314
      for (list_index = 0; list_index < RAL_LINK_PARAM_LTE_MAX; list_index++) {
1315
        SLIST_INIT(&PHY_vars_UE_g[UE_id][CC_id]->ral_thresholds_lte_polled[list_index]);
1316
      }
1317

1318 1319
#endif

Raymond Knopp's avatar
Raymond Knopp committed
1320 1321 1322
    } // CC_id
  } // UE_id
  init_UE(NB_UE_INST);
1323
    }
1324

1325 1326
void init_openair2(void)
{
1327
#ifdef OPENAIR2
Raymond Knopp's avatar
 
Raymond Knopp committed
1328
  int CC_id;
Cedric Roux's avatar
Cedric Roux committed
1329
//#warning "eNB index is hard coded to zero"
1330 1331

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++)
1332
    l2_init (&PHY_vars_eNB_g[0][CC_id]->frame_parms,
1333 1334 1335 1336 1337
             oai_emulation.info.eMBMS_active_state,
             NULL,
             oai_emulation.info.cba_group_active,
             oai_emulation.info.handover_active);

1338
  mac_xface->macphy_exit = exit_fun;
1339

1340 1341 1342
#endif
}

1343 1344
void init_ocm(void)
{
Lionel Gauthier's avatar
Lionel Gauthier committed
1345
  module_id_t UE_id, eNB_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1346
  int CC_id;
1347

1348
  /* Added for PHY abstraction */
1349 1350

  char* frame_type = "unknown";
1351

1352 1353 1354 1355
  switch (oai_emulation.info.frame_type[0]) {
  case FDD:
    frame_type = "FDD";
    break;
1356

1357 1358 1359 1360
  case TDD:
    frame_type = "FDD";
    break;
  }
1361

1362
  LOG_I(OCM,"Running with frame_type %d (%s), Nid_cell %d, N_RB_DL %d, EP %d, mode %d, target dl_mcs %d, rate adaptation %d, nframes %d, abstraction %d, channel %s\n",
1363 1364
        oai_emulation.info.frame_type[0], frame_type, Nid_cell, oai_emulation.info.N_RB_DL[0], oai_emulation.info.extended_prefix_flag[0], oai_emulation.info.transmission_mode[0],target_dl_mcs,
        rate_adaptation_flag,oai_emulation.info.n_frames,abstraction_flag,oai_emulation.environment_system_config.fading.small_scale.selected_option);
1365

1366
  if (abstraction_flag) {
1367

1368
    get_beta_map();
1369
#ifdef PHY_ABSTRACTION_UL
1370
    get_beta_map_up();
1371
#endif
1372
    get_MIESM_param();
1373
    
1374
    //load_pbch_desc();
1375
  }
1376

1377 1378

  for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++) {
1379 1380
    enb_data[eNB_id] = (node_desc_t *)malloc(sizeof(node_desc_t));
    init_enb(enb_data[eNB_id],oai_emulation.environment_system_config.antenna.eNB_antenna);
1381 1382 1383
  }

  for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) {
1384 1385
    ue_data[UE_id] = (node_desc_t *)malloc(sizeof(node_desc_t));
    init_ue(ue_data[UE_id],oai_emulation.environment_system_config.antenna.UE_antenna);
1386 1387 1388 1389 1390 1391
  }

  if ((oai_emulation.info.ocm_enabled == 1)&& (ethernet_flag == 0 ) &&
      (oai_emulation.environment_system_config.fading.shadowing.decorrelation_distance_m>0) &&
      (oai_emulation.environment_system_config.fading.shadowing.variance_dB>0)) {

1392 1393 1394 1395
    // init SF map here!!!
    map1 =(int)oai_emulation.topology_config.area.x_m;
    map2 =(int)oai_emulation.topology_config.area.y_m;
    ShaF = init_SF(map1,map2,oai_emulation.environment_system_config.fading.shadowing.decorrelation_distance_m,oai_emulation.environment_system_config.fading.shadowing.variance_dB);
1396

1397 1398
    // size of area to generate shadow fading map
    LOG_D(EMU,"Simulation area x=%f, y=%f\n",
1399 1400 1401 1402 1403
          oai_emulation.topology_config.area.x_m,
          oai_emulation.topology_config.area.y_m);
  }

  if (abstraction_flag == 0)
Raymond Knopp's avatar
 
Raymond Knopp committed
1404
    init_channel_vars (frame_parms[0], &s_re, &s_im, &r_re, &r_im, &r_re0, &r_im0);
1405 1406 1407

  // initialize channel descriptors
  for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1408
    for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) {
1409 1410
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
        LOG_D(OCM,"Initializing channel (%s, %d) from eNB %d to UE %d\n", oai_emulation.environment_system_config.fading.small_scale.selected_option,
1411
              map_str_to_int(small_scale_names,oai_emulation.environment_system_config.fading.small_scale.selected_option), eNB_id, UE_id);
1412

1413

Florian Kaltenberger's avatar
Florian Kaltenberger committed
1414
        eNB2UE[eNB_id][UE_id][CC_id] = 
1415 1416
	  new_channel_desc_scm(PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.nb_antennas_tx,
			       PHY_vars_UE_g[UE_id][CC_id]->frame_parms.nb_antennas_rx,
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1417
			       map_str_to_int(small_scale_names,oai_emulation.environment_system_config.fading.small_scale.selected_option),
1418 1419
			       N_RB2sampling_rate(PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.N_RB_DL),
			       N_RB2channel_bandwidth(PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.N_RB_DL),
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1420 1421 1422
			       forgetting_factor,
			       0,
			       0);
1423 1424 1425
        random_channel(eNB2UE[eNB_id][UE_id][CC_id],abstraction_flag);
        LOG_D(OCM,"[SIM] Initializing channel (%s, %d) from UE %d to eNB %d\n", oai_emulation.environment_system_config.fading.small_scale.selected_option,
              map_str_to_int(small_scale_names, oai_emulation.environment_system_config.fading.small_scale.selected_option),UE_id, eNB_id);
1426

Florian Kaltenberger's avatar
Florian Kaltenberger committed
1427
        UE2eNB[UE_id][eNB_id][CC_id] = 
1428 1429
	  new_channel_desc_scm(PHY_vars_UE_g[UE_id][CC_id]->frame_parms.nb_antennas_tx,
			       PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.nb_antennas_rx,
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1430
			       map_str_to_int(small_scale_names, oai_emulation.environment_system_config.fading.small_scale.selected_option),
1431 1432
			       N_RB2sampling_rate(PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.N_RB_UL),
			       N_RB2channel_bandwidth(PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.N_RB_UL),
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1433 1434 1435
			       forgetting_factor,
			       0,
			       0);
1436

1437 1438 1439 1440
        random_channel(UE2eNB[UE_id][eNB_id][CC_id],abstraction_flag);

        // to make channel reciprocal uncomment following line instead of previous. However this only works for SISO at the moment. For MIMO the channel would need to be transposed.
        //UE2eNB[UE_id][eNB_id] = eNB2UE[eNB_id][UE_id];
Raymond Knopp's avatar
 
Raymond Knopp committed
1441
      }
1442 1443
    }
  }
1444 1445
}

1446 1447
void init_otg_pdcp_buffer(void)
{
Lionel Gauthier's avatar
Lionel Gauthier committed
1448
  module_id_t i;
1449
  otg_pdcp_buffer = malloc((NB_UE_INST + NB_eNB_INST) * sizeof(Packet_OTG_List_t));
1450 1451

  for (i = 0; i < NB_UE_INST + NB_eNB_INST; i++) {
1452 1453
    pkt_list_init(&(otg_pdcp_buffer[i]));
    //LOG_I(EMU,"HEAD of otg_pdcp_buffer[%d] is %p\n", i, pkt_list_get_head(&(otg_pdcp_buffer[i])));
1454 1455 1456
  }
}

1457 1458
void update_omg (frame_t frameP)
{
Lionel Gauthier's avatar
Lionel Gauthier committed
1459
  module_id_t UE_id, eNB_id;
1460 1461
  int new_omg_model;

1462
  if ((frameP % omg_period) == 0 ) { // call OMG every 10ms
1463 1464 1465 1466 1467 1468 1469 1470 1471 1472
    update_nodes(oai_emulation.info.time_s);
    display_node_list(enb_node_list);
    display_node_list(ue_node_list);

    if (oai_emulation.info.omg_model_ue >= MAX_NUM_MOB_TYPES) { // mix mobility model
      for(UE_id=oai_emulation.info.first_ue_local; UE_id<(oai_emulation.info.first_ue_local+oai_emulation.info.nb_ue_local); UE_id++) {
        new_omg_model = randomgen(STATIC,RWALK);
        LOG_D(OMG, "[UE] Node of ID %d is changing mobility generator ->%d \n", UE_id, new_omg_model);
        // reset the mobility model for a specific node
        set_new_mob_type (UE_id, UE, new_omg_model, oai_emulation.info.time_s);
1473
      }
1474
    }
1475

1476 1477 1478 1479 1480 1481
    if (oai_emulation.info.omg_model_enb >= MAX_NUM_MOB_TYPES) {      // mix mobility model
      for (eNB_id = oai_emulation.info.first_enb_local; eNB_id < (oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local); eNB_id++) {
        new_omg_model = randomgen (STATIC, RWALK);
        LOG_D (OMG,"[eNB] Node of ID %d is changing mobility generator ->%d \n", eNB_id, new_omg_model);
        // reset the mobility model for a specific node
        set_new_mob_type (eNB_id, eNB, new_omg_model, oai_emulation.info.time_s);
1482
      }
1483
    }
1484 1485 1486
  }
}

1487 1488 1489 1490 1491
void update_omg_ocm()
{

  enb_node_list=get_current_positions(oai_emulation.info.omg_model_enb, eNB, oai_emulation.info.time_s);
  ue_node_list=get_current_positions(oai_emulation.info.omg_model_ue, UE, oai_emulation.info.time_s);
1492

1493 1494
}

1495 1496
void update_ocm()
{
Lionel Gauthier's avatar
Lionel Gauthier committed
1497
  module_id_t UE_id, eNB_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1498 1499
  int CC_id;

1500
  for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++)
1501
    enb_data[eNB_id]->tx_power_dBm = PHY_vars_eNB_g[eNB_id][0]->frame_parms.pdsch_config_common.referenceSignalPower;
1502

1503
  for (UE_id = 0; UE_id < NB_UE_INST; UE_id++)
1504
    ue_data[UE_id]->tx_power_dBm = PHY_vars_UE_g[UE_id][0]->tx_power_dBm[0];
1505

1506 1507 1508

  /* check if the openair channel model is activated used for PHY abstraction : path loss*/
  if ((oai_emulation.info.ocm_enabled == 1)&& (ethernet_flag == 0 )) {
1509
    //LOG_D(OMG," extracting position of eNb...\n");
1510 1511
    //display_node_list(enb_node_list);
    //  display_node_list(ue_node_list);
1512 1513 1514 1515
    extract_position(enb_node_list, enb_data, NB_eNB_INST);
    //extract_position_fixed_enb(enb_data, NB_eNB_INST,frame);
    //LOG_D(OMG," extracting position of UE...\n");
    //      if (oai_emulation.info.omg_model_ue == TRACE)
Raymond Knopp's avatar
 
Raymond Knopp committed
1516
    extract_position(ue_node_list, ue_data, NB_UE_INST);
1517

Raymond Knopp's avatar
 
Raymond Knopp committed
1518 1519 1520
    /* if (frame % 50 == 0)
       LOG_N(OCM,"Path loss for TTI %d : \n", frame);
    */
1521
    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1522
      for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++) {
1523 1524 1525 1526 1527
        for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) {
          calc_path_loss (enb_data[eNB_id], ue_data[UE_id], eNB2UE[eNB_id][UE_id][CC_id], oai_emulation.environment_system_config,ShaF);
          //calc_path_loss (enb_data[eNB_id], ue_data[UE_id], eNB2UE[eNB_id][UE_id], oai_emulation.environment_system_config,0);
          UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB = eNB2UE[eNB_id][UE_id][CC_id]->path_loss_dB;
          //    if (frame % 50 == 0)
hbilel's avatar
hbilel committed
1528
          LOG_D(OCM,"Path loss (CCid %d) between eNB %d at (%f,%f) and UE %d at (%f,%f) is %f, angle %f\n",
1529 1530
                CC_id,eNB_id,enb_data[eNB_id]->x,enb_data[eNB_id]->y,UE_id,ue_data[UE_id]->x,ue_data[UE_id]->y,
                eNB2UE[eNB_id][UE_id][CC_id]->path_loss_dB, eNB2UE[eNB_id][UE_id][CC_id]->aoa);
Cedric Roux's avatar
Cedric Roux committed
1531 1532 1533 1534
          //double dx, dy, distance;
          //dx = enb_data[eNB_id]->x - ue_data[UE_id]->x;
          //dy = enb_data[eNB_id]->y - ue_data[UE_id]->y;
          //distance = sqrt(dx * dx + dy * dy);
1535
          /*LOG_D(LOCALIZE, " OCM distance between eNB %d at (%f,%f) and UE %d at (%f,%f) is %f \n",
1536 1537 1538
                  eNB_id, enb_data[eNB_id]->x,enb_data[eNB_id]->y,
                  UE_id, ue_data[UE_id]->x,ue_data[UE_id]->y,
                  distance);*/
1539
        }
1540
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1541
    }
1542
  }
1543 1544

  else {
1545
    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1546
      for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++) {
1547 1548 1549 1550
        for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) {

          //pathloss: -132.24 dBm/15kHz RE + target SNR - eNB TX power per RE
          if (eNB_id == (UE_id % NB_eNB_INST)) {
1551 1552
            eNB2UE[eNB_id][UE_id][CC_id]->path_loss_dB = -132.24 + snr_dB - PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.pdsch_config_common.referenceSignalPower;
            UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB = -132.24 + snr_dB - PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.pdsch_config_common.referenceSignalPower; 
1553
          } else {
1554 1555
            eNB2UE[eNB_id][UE_id][CC_id]->path_loss_dB = -132.24 + sinr_dB - PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.pdsch_config_common.referenceSignalPower;
            UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB = -132.24 + sinr_dB - PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.pdsch_config_common.referenceSignalPower;
1556 1557
          }

1558
          LOG_D(OCM,"Path loss from eNB %d to UE %d (CCid %d)=> %f dB (eNB TX %d, SNR %f)\n",eNB_id,UE_id,CC_id,
1559
                eNB2UE[eNB_id][UE_id][CC_id]->path_loss_dB,
1560
                PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.pdsch_config_common.referenceSignalPower,snr_dB);
1561
        
1562
        }
1563
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1564
    }
1565 1566 1567
  }
}

1568
#ifdef OPENAIR2
1569 1570
void update_otg_eNB(module_id_t enb_module_idP, unsigned int ctime)
{
1571

1572
#if defined(USER_MODE) && defined(OAI_EMU)
1573

Cedric Roux's avatar
Cedric Roux committed
1574
  //int rrc_state=0;
1575

1576 1577
  if (oai_emulation.info.otg_enabled ==1 ) {

1578 1579 1580 1581 1582 1583 1584
    int dst_id, app_id;
    Packet_otg_elt_t *otg_pkt;

    for (dst_id = 0; dst_id < NUMBER_OF_UE_MAX; dst_id++) {
      for_times += 1;

      // generate traffic if the ue is rrc reconfigured state
1585 1586 1587 1588 1589
      //if ((rrc_state=mac_eNB_get_rrc_status(enb_module_idP, dst_id)) > 2 /*RRC_CONNECTED*/ ) {
      if (mac_eNB_get_rrc_status(enb_module_idP, oai_emulation.info.eNB_ue_module_id_to_rnti[enb_module_idP][dst_id]) > 2 ){ 
	
	if_times += 1;
	
1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609
        for (app_id=0; app_id<MAX_NUM_APPLICATION; app_id++) {
          otg_pkt = malloc (sizeof(Packet_otg_elt_t));


          (otg_pkt->otg_pkt).sdu_buffer = (uint8_t*) packet_gen(enb_module_idP, dst_id + NB_eNB_INST, app_id, ctime, &((otg_pkt->otg_pkt).sdu_buffer_size));

          if ((otg_pkt->otg_pkt).sdu_buffer != NULL) {
            otg_times += 1;
            (otg_pkt->otg_pkt).rb_id = DTCH-2; // app could be binded to a given DRB
            (otg_pkt->otg_pkt).module_id = enb_module_idP;
            (otg_pkt->otg_pkt).dst_id = dst_id;
            (otg_pkt->otg_pkt).is_ue = 0;
            (otg_pkt->otg_pkt).mode = PDCP_TRANSMISSION_MODE_DATA;
            //Adding the packet to the OTG-PDCP buffer
            pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[enb_module_idP]));
            LOG_I(EMU,"[eNB %d] ADD pkt to OTG buffer with size %d for dst %d on rb_id %d for app id %d \n",
                  (otg_pkt->otg_pkt).module_id, otg_pkt->otg_pkt.sdu_buffer_size, (otg_pkt->otg_pkt).dst_id,(otg_pkt->otg_pkt).rb_id, app_id);
          } else {
            free(otg_pkt);
            otg_pkt=NULL;
1610
          }
1611
        }
1612
      }
1613
    }
1614 1615

#ifdef Rel10
1616 1617 1618 1619 1620
    mbms_service_id_t service_id;
    mbms_session_id_t session_id;
    rb_id_t           rb_id;

    // MBSM multicast traffic
1621
    if (ctime >= 500 ) {// only generate when UE can receive MTCH (need to control this value)
1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664
      for (service_id = 0; service_id < 2 ; service_id++) { //maxServiceCount
        for (session_id = 0; session_id < 2; session_id++) { // maxSessionPerPMCH
          if (pdcp_mbms_array_eNB[enb_module_idP][service_id][session_id].instanciated_instance == TRUE) { // this service/session is configured

            otg_pkt = malloc (sizeof(Packet_otg_elt_t));
            // LOG_T(OTG,"multicast packet gen for (service/mch %d, session/lcid %d, rb_id %d)\n", service_id, session_id, service_id*maxSessionPerPMCH + session_id);
            rb_id = pdcp_mbms_array_eNB[enb_module_idP][service_id][session_id].rb_id;
            (otg_pkt->otg_pkt).sdu_buffer = (uint8_t*) packet_gen_multicast(enb_module_idP, session_id, ctime, &((otg_pkt->otg_pkt).sdu_buffer_size));

            if ((otg_pkt->otg_pkt).sdu_buffer != NULL) {
              (otg_pkt->otg_pkt).rb_id      = rb_id;
              (otg_pkt->otg_pkt).module_id  = enb_module_idP;
              (otg_pkt->otg_pkt).dst_id     = session_id;
              (otg_pkt->otg_pkt).is_ue      = FALSE;
              //Adding the packet to the OTG-PDCP buffer
              (otg_pkt->otg_pkt).mode       = PDCP_TRANSMISSION_MODE_TRANSPARENT;
              pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[enb_module_idP]));
              LOG_I(EMU, "[eNB %d] ADD packet (%p) multicast to OTG buffer for dst %d on rb_id %d\n",
                    (otg_pkt->otg_pkt).module_id, otg_pkt, (otg_pkt->otg_pkt).dst_id,(otg_pkt->otg_pkt).rb_id);
            } else {
              //LOG_I(EMU, "OTG returns null \n");
              free(otg_pkt);
              otg_pkt=NULL;
            }


            // old version
            /*      // MBSM multicast traffic
            #ifdef Rel10
            if (frame >= 46) {// only generate when UE can receive MTCH (need to control this value)
            for (service_id = 0; service_id < 2 ; service_id++) { //maxServiceCount
            for (session_id = 0; session_id < 2; session_id++) { // maxSessionPerPMCH
            //   LOG_I(OTG,"DUY:frame %d, pdcp_mbms_array[module_id][rb_id].instanciated_instance is %d\n",frame,pdcp_mbms_array[module_id][service_id*maxSessionPerPMCH + session_id].instanciated_instance);
            if ((pdcp_mbms_array[module_idP][service_id*maxSessionPerPMCH + session_id].instanciated_instance== module_idP + 1) && (eNB_flag == 1)){ // this service/session is configured
            // LOG_T(OTG,"multicast packet gen for (service/mch %d, session/lcid %d)\n", service_id, session_id);
            // Duy add
            LOG_I(OTG, "frame %d, multicast packet gen for (service/mch %d, session/lcid %d, rb_id %d)\n",frame, service_id, session_id,service_id*maxSessionPerPMCH + session_id);
            // end Duy add
            rb_id = pdcp_mbms_array[module_id][service_id*maxSessionPerPMCH + session_id].rb_id;
            otg_pkt=(uint8_t*) packet_gen_multicast(module_idP, session_id, ctime, &pkt_size);
            if (otg_pkt != NULL) {
            LOG_D(OTG,"[eNB %d] sending a multicast packet from module %d on rab id %d (src %d, dst %d) pkt size %d\n", eNB_index, module_idP, rb_id, module_idP, session_id, pkt_size);
            pdcp_data_req(module_id, frame, eNB_flag, rb_id, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, pkt_size, otg_pkt,PDCP_TM);
1665
            free(otg_pkt);
1666 1667 1668 1669 1670 1671 1672
            }
            }
            }
            }
            } // end multicast traffic
            #endif
             */
1673 1674


1675
          }
1676
        }
1677
      }
1678

1679
    } // end multicast traffic
1680

1681
#endif
1682
  }
1683

1684
#else
1685
#if 0 //  defined(EXMIMO) || defined(OAI_USRP)
1686
  if (otg_enabled==1) {
1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707
    ctime = frame * 100;

    for (dst_id = 0; dst_id < NUMBER_OF_UE_MAX; dst_id++) {
      if (mac_get_rrc_status(eNB_index, eNB_flag, dst_id ) > 2) {
        otg_pkt = malloc (sizeof(Packet_otg_elt_t));
        (otg_pkt->otg_pkt).sdu_buffer = packet_gen(module_instP, dst_id, ctime, &pkt_size);

        if (otg_pkt != NULL) {
          rb_id = DTCH-2;
          (otg_pkt->otg_pkt).rb_id     = rb_id;
          (otg_pkt->otg_pkt).module_id = module_idP;
          (otg_pkt->otg_pkt).is_ue     = FALSE;
          (otg_pkt->otg_pkt).mode      = PDCP_TRANSMISSION_MODE_DATA;
          //Adding the packet to the OTG-PDCP buffer
          pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[module_idP]));
          LOG_I(EMU, "[eNB %d] ADD pkt to OTG buffer for dst %d on rb_id %d\n", (otg_pkt->otg_pkt).module_id, (otg_pkt->otg_pkt).dst_id,(otg_pkt->otg_pkt).rb_id);
        } else {
          //LOG_I(EMU, "OTG returns null \n");
          free(otg_pkt);
          otg_pkt=NULL;
        }
1708
      }
1709
    }
1710
  }
1711

1712
#endif
1713 1714 1715
#endif
}

1716 1717
void update_otg_UE(module_id_t ue_mod_idP, unsigned int ctime)
{
Cedric Roux's avatar
Cedric Roux committed
1718
#if defined(USER_MODE) && defined(OAI_EMU)
1719

1720
  if (oai_emulation.info.otg_enabled ==1 ) {
1721 1722 1723 1724 1725 1726 1727
    module_id_t dst_id, src_id; //dst_id = eNB_index
    module_id_t module_id = ue_mod_idP+NB_eNB_INST;

    src_id = module_id;

    for (dst_id=0; dst_id<NB_SIG_CNX_UE; dst_id++) {
      // only consider the first attached eNB
1728
      if (mac_UE_get_rrc_status(ue_mod_idP, dst_id ) > 2 /*RRC_CONNECTED*/) {
1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753
        Packet_otg_elt_t *otg_pkt = malloc (sizeof(Packet_otg_elt_t));

        if (otg_pkt!=NULL)
          memset(otg_pkt,0,sizeof(Packet_otg_elt_t));
        else {
          LOG_E(OTG,"not enough memory\n");
          exit(-1);
        }// Manage to add this packet to the tail of your list

        (otg_pkt->otg_pkt).sdu_buffer = (uint8_t*) packet_gen(src_id, dst_id, 0, ctime, &((otg_pkt->otg_pkt).sdu_buffer_size));

        if ((otg_pkt->otg_pkt).sdu_buffer != NULL) {
          (otg_pkt->otg_pkt).rb_id     = DTCH-2;
          (otg_pkt->otg_pkt).module_id = module_id;
          (otg_pkt->otg_pkt).dst_id    = dst_id;
          (otg_pkt->otg_pkt).is_ue     = 1;
          //Adding the packet to the OTG-PDCP buffer
          (otg_pkt->otg_pkt).mode      = PDCP_TRANSMISSION_MODE_DATA;
          pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[module_id]));
          LOG_I(EMU, "[UE %d] ADD pkt to OTG buffer with size %d for dst %d on rb_id %d \n",
                (otg_pkt->otg_pkt).module_id, otg_pkt->otg_pkt.sdu_buffer_size, (otg_pkt->otg_pkt).dst_id,(otg_pkt->otg_pkt).rb_id);
        } else {
          free(otg_pkt);
          otg_pkt=NULL;
        }
1754
      }
1755
    }
1756
  }
1757

1758 1759
#endif
}
1760
#endif
1761

1762 1763
int init_slot_isr(void)
{
1764
  if (oai_emulation.info.slot_isr) {
1765
    struct itimerspec its;
1766

1767
    int sfd;
1768

1769
    sfd = timerfd_create(CLOCK_REALTIME, 0);
1770

1771 1772 1773 1774
    if (sfd == -1) {
      LOG_E(EMU, "Failed in timerfd_create (%d:%s)\n", errno, strerror(errno));
      exit(EXIT_FAILURE);
    }
1775

1776 1777 1778 1779 1780 1781 1782 1783 1784 1785
    /* Start the timer */
    its.it_value.tv_sec = 0;
    its.it_value.tv_nsec = 500 * 1000;
    its.it_interval.tv_sec = its.it_value.tv_sec;
    its.it_interval.tv_nsec = its.it_value.tv_nsec;

    if (timerfd_settime(sfd, TFD_TIMER_ABSTIME, &its, NULL) == -1) {
      LOG_E(EMU, "Failed in timer_settime (%d:%s)\n", errno, strerror(errno));
      exit(EXIT_FAILURE);
    }
1786

1787
    oai_emulation.info.slot_sfd = sfd;
1788
  }
1789

1790
  return 0;
1791 1792 1793 1794
}

void wait_for_slot_isr(void)
{
1795 1796
  uint64_t exp;
  ssize_t res;
1797

1798
  if (oai_emulation.info.slot_sfd > 0) {
1799
    res = read(oai_emulation.info.slot_sfd, &exp, sizeof(exp));
1800

1801 1802 1803 1804
    if ((res < 0) || (res != sizeof(exp))) {
      LOG_E(EMU, "Failed in read (%d:%s)\n", errno, strerror(errno));
      exit(EXIT_FAILURE);
    }
1805
  }
1806 1807
}

1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819
void exit_fun(const char* s)
{
  void *array[10];
  size_t size;

  size = backtrace(array, 10);
  backtrace_symbols_fd(array, size, 2);

  fprintf(stderr, "Error: %s. Exiting!\n",s);
  exit (-1);
}

1820 1821
void init_time()
{
1822
  clock_gettime (CLOCK_REALTIME, &time_spec);
1823 1824
  time_now      = (unsigned long) time_spec.tv_nsec;
  td_avg        = 0;
1825
  sleep_time_us = SLEEP_STEP_US;
1826
  td_avg        = TARGET_SF_TIME_NS;
1827 1828
}

1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839
int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params) {

	return(0);


}

int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg) {

	return(0);
}