966 lines
28 KiB
C
966 lines
28 KiB
C
/*
|
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.openairinterface.org/?page_id=698
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*-------------------------------------------------------------------------------
|
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
|
* contact@openairinterface.org
|
|
*/
|
|
|
|
/*! \file OMG.c
|
|
* \brief Main function containing the OMG API to oaisim or any other simulator/emulator
|
|
* \author S. Gashaw, N. Nikaein, J. Harri
|
|
* \date 2011 - 2014
|
|
* \version 0.1
|
|
* \company Eurecom
|
|
* \email:
|
|
* \note
|
|
* \warning
|
|
*/
|
|
|
|
|
|
#include <unistd.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <getopt.h>
|
|
#include <math.h>
|
|
#include <time.h>
|
|
#include "omg.h"
|
|
#include "static.h"
|
|
#include "rwp.h"
|
|
#include "rwalk.h"
|
|
#include "trace.h"
|
|
#include "grid.h"
|
|
#include "steadystaterwp.h"
|
|
#ifdef SUMO_IF
|
|
#include "sumo.h"
|
|
#endif
|
|
#include "../OMV/structures.h"
|
|
//#define STANDALONE
|
|
|
|
float n_frames = 20.0;
|
|
|
|
int omv_write (int pfd, node_list *ue_node_list, Data_Flow_Unit omv_data);
|
|
void omv_end (int pfd, Data_Flow_Unit omv_data);
|
|
int omv_enabled;
|
|
|
|
/*initialze global parameters*/
|
|
void
|
|
init_omg_global_params (void) {
|
|
int mob_t, node_t, i;
|
|
xloc_div = 10.0;
|
|
yloc_div = 10.0;
|
|
grid = 0;
|
|
|
|
for (mob_t = STATIC; mob_t < MAX_NUM_MOB_TYPES; mob_t++) {
|
|
job_vector_len[mob_t] = 0;
|
|
job_vector[mob_t] = NULL;
|
|
job_vector_end[mob_t] = NULL;
|
|
}
|
|
|
|
for (node_t = eNB; node_t < MAX_NUM_NODE_TYPES; node_t++) {
|
|
node_vector[node_t] = NULL;
|
|
node_vector_end[node_t] = NULL;
|
|
node_vector_len[node_t] = 0;
|
|
}
|
|
|
|
for (i = 0; i < 100; i++) {
|
|
event_sum[i] = 0;
|
|
events[i] = 0;
|
|
}
|
|
}
|
|
|
|
/*initiate mobility generator*/
|
|
void
|
|
init_mobility_generator (omg_global_param omg_param_list[]) {
|
|
int node_t, mobility_t;
|
|
|
|
for (node_t = eNB; node_t < MAX_NUM_NODE_TYPES; node_t++) {
|
|
mobility_t = omg_param_list[node_t].mobility_type;
|
|
|
|
switch (mobility_t) {
|
|
case STATIC:
|
|
start_static_generator (omg_param_list[node_t]);
|
|
break;
|
|
|
|
case RWP:
|
|
start_rwp_generator (omg_param_list[node_t]);
|
|
break;
|
|
|
|
case RWALK:
|
|
start_rwalk_generator (omg_param_list[node_t]);
|
|
break;
|
|
|
|
case TRACE:
|
|
start_trace_generator (omg_param_list[node_t]);
|
|
break;
|
|
#ifdef SUMO_IF
|
|
|
|
case SUMO:
|
|
start_sumo_generator (omg_param_list[node_t]);
|
|
break;
|
|
#endif
|
|
|
|
case STEADY_RWP:
|
|
start_steadystaterwp_generator (omg_param_list[node_t]);
|
|
break;
|
|
|
|
default:
|
|
LOG_W (OMG, "Unsupported generator\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
/**************************************************************************************/
|
|
/*stop sumo mobiity generator*/
|
|
void
|
|
stop_mobility_generator (omg_global_param *omg_param_list) {
|
|
int i;
|
|
|
|
for (i = 0; i < MAX_NUM_NODE_TYPES; i++) {
|
|
switch (omg_param_list[i].mobility_type) {
|
|
case STATIC:
|
|
break;
|
|
|
|
case RWP:
|
|
break;
|
|
|
|
case RWALK:
|
|
break;
|
|
|
|
case TRACE:
|
|
clear_list ();
|
|
break;
|
|
|
|
case STEADY_RWP:
|
|
break;
|
|
#ifdef SUMO_IF
|
|
|
|
case SUMO:
|
|
stop_sumo_generator ();
|
|
//LOG_D(OMG," --------OMG will interface with SUMO for mobility generation-------- \n");
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
LOG_W (OMG, "Unsupported generator\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
void
|
|
update_nodes (double cur_time) {
|
|
//LOG_D(OMG, "UPDATE NODES" );
|
|
int i = 0;
|
|
|
|
for (i = (STATIC + 1); i < MAX_NUM_MOB_TYPES; i++) {
|
|
if (job_vector[i] != NULL) {
|
|
update_node_vector (i, cur_time);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
update_node_vector (int mobility_type, double cur_time) {
|
|
//set_time(cur_time);
|
|
switch (mobility_type) {
|
|
case RWP:
|
|
update_rwp_nodes (cur_time);
|
|
break;
|
|
|
|
case RWALK:
|
|
update_rwalk_nodes (cur_time);
|
|
break;
|
|
|
|
case TRACE:
|
|
update_trace_nodes (cur_time);
|
|
break;
|
|
#ifdef SUMO_IF
|
|
|
|
case SUMO:
|
|
// printf("in SUMO case \n");
|
|
update_sumo_nodes (cur_time);
|
|
break;
|
|
#endif
|
|
|
|
case STEADY_RWP:
|
|
update_steadystaterwp_nodes (cur_time);
|
|
break;
|
|
|
|
default:
|
|
LOG_W (OMG, "STATIC or Unsupported generator\n");
|
|
}
|
|
}
|
|
|
|
/*********************************************************************************/
|
|
|
|
/*return updated node position for a given node type*/
|
|
node_list *
|
|
get_current_positions (int mobility_type, int node_type, double cur_time) {
|
|
get_nodes_positions (mobility_type, cur_time);
|
|
return node_vector[node_type];
|
|
}
|
|
|
|
/*update current position of nodes for specific mobility type*/
|
|
void
|
|
get_nodes_positions (int mobility_type, double cur_time) {
|
|
//printf("%d \n",mobility_type);
|
|
switch (mobility_type) {
|
|
case STATIC:
|
|
break;
|
|
|
|
case RWP:
|
|
get_rwp_positions_updated (cur_time);
|
|
break;
|
|
|
|
case RWALK:
|
|
get_rwalk_positions_updated (cur_time);
|
|
break;
|
|
|
|
case TRACE:
|
|
get_trace_positions_updated (cur_time);
|
|
break;
|
|
#ifdef SUMO_IF
|
|
|
|
case SUMO:
|
|
LOG_I (OMG, "getting positions from SUMO\n");
|
|
get_sumo_positions_updated (cur_time);
|
|
break;
|
|
#endif
|
|
|
|
case STEADY_RWP:
|
|
get_steadystaterwp_positions_updated (cur_time);
|
|
break;
|
|
|
|
default:
|
|
LOG_E (OMG, " Unsupported generator \n");
|
|
}
|
|
}
|
|
|
|
/***************************************************************/
|
|
|
|
// get the position for a specific node
|
|
|
|
node_struct *
|
|
get_node_position (int node_type, int nid) {
|
|
node_list *tmp;
|
|
tmp = node_vector[node_type];
|
|
|
|
while (tmp != NULL) {
|
|
if (tmp->node->id == nid)
|
|
return tmp->node;
|
|
|
|
tmp = tmp->next;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/*set new mobility for a node*/
|
|
void
|
|
set_new_mob_type (int id, int node_t, int mob_t, double cur_time) {
|
|
int prev_mob;
|
|
node_list *tmp;
|
|
//job_list *tmp2, *prev_job;
|
|
pair_struct *pair;
|
|
double pause_p;
|
|
//find previous mobility type
|
|
tmp = node_vector[node_t];
|
|
|
|
while (tmp != NULL) {
|
|
if (tmp->node->id == id && tmp->node->type == node_t) {
|
|
prev_mob = tmp->node->generator;
|
|
break;
|
|
}
|
|
|
|
tmp = tmp->next;
|
|
}
|
|
|
|
//end
|
|
|
|
if (tmp != NULL && prev_mob != mob_t) {
|
|
//initialize node position
|
|
if (mob_t == STATIC || mob_t == RWP || mob_t == RWALK || mob_t == STEADY_RWP) {
|
|
tmp->node->x_pos =
|
|
(double) ((int)
|
|
(randomgen
|
|
(omg_param_list[node_t].min_x,
|
|
omg_param_list[node_t].max_x) * 100)) / 100;
|
|
tmp->node->mob->x_from = tmp->node->x_pos;
|
|
tmp->node->mob->x_to = tmp->node->x_pos;
|
|
tmp->node->y_pos =
|
|
(double) ((int)
|
|
(randomgen
|
|
(omg_param_list[node_t].min_y,
|
|
omg_param_list[node_t].max_y) * 100)) / 100;
|
|
tmp->node->mob->y_from = tmp->node->y_pos;
|
|
tmp->node->mob->y_to = tmp->node->y_pos;
|
|
tmp->node->mob->speed = 0.0;
|
|
tmp->node->generator = mob_t;
|
|
|
|
if (prev_mob != STATIC)
|
|
job_vector[prev_mob] =
|
|
remove_job (job_vector[prev_mob], id, node_t);
|
|
}
|
|
|
|
//end
|
|
|
|
switch (mob_t) {
|
|
case STATIC:
|
|
break;
|
|
|
|
case RWP:
|
|
pair = (pair_struct *) malloc (sizeof (struct pair_struct));
|
|
pair->b = tmp->node;
|
|
sleep_rwp_node (pair, cur_time);
|
|
job_vector[RWP] = addjob (pair, job_vector[RWP]);
|
|
break;
|
|
|
|
case RWALK:
|
|
pair = (pair_struct *) malloc (sizeof (struct pair_struct));
|
|
pair->b = tmp->node;
|
|
sleep_rwalk_node (pair, cur_time);
|
|
job_vector[RWALK] = addjob (pair, job_vector[RWALK]);
|
|
break;
|
|
|
|
case STEADY_RWP:
|
|
tmp->node->event_num = 0;
|
|
pair = (pair_struct *) malloc (sizeof (struct pair_struct));
|
|
pair->b = tmp->node;
|
|
pause_p = pause_probability (omg_param_list[node_t]);
|
|
|
|
if (randomgen (0, 1) < pause_p)
|
|
sleep_steadystaterwp_node (pair, cur_time);
|
|
else
|
|
move_steadystaterwp_node (pair, cur_time);
|
|
|
|
break;
|
|
#ifdef SUMO_IF
|
|
|
|
case SUMO:
|
|
LOG_E (OMG, "not possible to change mobility type to sumo \n");
|
|
break;
|
|
#endif
|
|
|
|
case TRACE:
|
|
LOG_E (OMG, "not possible to change mobility type to trace \n");
|
|
break;
|
|
|
|
default:
|
|
LOG_E (OMG, " Unsupported generator \n");
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef STANDALONE
|
|
|
|
/************************** get options ************************************/
|
|
void
|
|
usage (void) {
|
|
fprintf (stderr,
|
|
"\n\t-X: assign maximum width of the simulation area for UE nodes(X_max)"
|
|
"\n\t-x: assign minimum width of the simulation area for UE nodes(X_min)"
|
|
"\n\t-C: assign maximum width of the simulation area for eNB nodes(X_max)"
|
|
"\n\t-c: assign minimum width of the simulation area for eNB nodes(X_min)"
|
|
"\n\t-B: assign maximum width of the simulation area for relay nodes(X_max)"
|
|
"\n\t-b: assign minimum width of the simulation area for relay nodes(X_min)"
|
|
"\n\t-Y: assign maximum height of the simulation area for UE nodes(Y_max)"
|
|
"\n\t-y: assign minimum height of the simulation area for UE nodes (Y_min)"
|
|
"\n\t-Z: assign maximum height of the simulation area for eNB nodes(Y_max)"
|
|
"\n\t-z: assign minimum height of the simulation area for eNB nodes(Y_min)"
|
|
"\n\t-W: assign maximum height of the simulation area for relay nodes(Y_max)"
|
|
"\n\t-w: assign minimum height of the simulation area for relay nodes(Y_min)"
|
|
//"\n\t-N: assign number of nodes" "\n\t-n: assign number of frames"
|
|
"\n\t-S: assign maximum duration of sleep/pause time for UE nodes(max_break)"
|
|
"\n\t-s: assign minimum duration of sleep/pause time for UE nodes(min_break)"
|
|
"\n\t-L: assign maximum duration of sleep/pause time for eNB nodes(max_break)"
|
|
"\n\t-l: assign minimum duration of sleep/pause time for eNB nodes(min_break)"
|
|
"\n\t-P: assign maximum duration of sleep/pause time for relay nodes(max_break)"
|
|
"\n\t-p: assign minimum duration of sleep/pause time for relay nodes(min_break)"
|
|
"\n\t-J: assign maximum duration of journey for UE nodes(max_journey_time)"
|
|
"\n\t-j: assign minimum duration of journey for UE nodes(min_journey_time)"
|
|
"\n\t-J: assign maximum duration of journey for eNB nodes(max_journey_time)"
|
|
"\n\t-j: assign minimum duration of journey for eNB nodes(min_journey_time)"
|
|
"\n\t-J: assign maximum duration of journey for relay nodes(max_journey_time)"
|
|
"\n\t-j: assign minimum duration of journey for relay nodes(min_journey_time)"
|
|
"\n\t-D: assign maximum speed for UE nodes"
|
|
"\n\t-d: assign minimum speed for UE nodes"
|
|
"\n\t-I: assign maximum speed for eNB nodes"
|
|
"\n\t-i: assign minimum speed for eNB nodes"
|
|
"\n\t-A: assign maximum speed for relay nodes"
|
|
"\n\t-a: assign minimum speed for relay nodes"
|
|
//"\n\t-g: choose generator(STATIC: 0x00, RWP: 0x01, RWALK: 0x02,TRACE: 0x03 or SUMO:0x04, STEADY_RWP:0x05)\n"
|
|
"\n\t-g: choose to use map for random mobility" "\n\t-h: help"
|
|
"\n\t-U: specifiy number of UE nodes"
|
|
"\n\t-E: specifiy number of eNB nodes"
|
|
"\n\t-R: specifiy number of relay nodes"
|
|
"\n\t-u: choose mobility generator for UE nodes"
|
|
"\n\t-e: choose mobility generator for eNB nodes"
|
|
"\n\t-r: choose mobility generator for relay nodes"
|
|
"\n\t-f: choose seed \n");
|
|
exit (0);
|
|
}
|
|
|
|
|
|
|
|
int
|
|
get_options (int argc, char *argv[]) {
|
|
int node_t;
|
|
char tag;
|
|
|
|
while ((tag =
|
|
getopt (argc, argv,
|
|
"U:u:E:e:R:r:A:a:B:b:C:c:D:d:f:g:hI:i:J:j:k:L:l:N:n:P:p:S:s:T:t:vW:w:X:x:Y:y:Z:z:"))
|
|
!= EOF) {
|
|
switch (tag) {
|
|
case 'U':
|
|
if (atoi (optarg) < 0) {
|
|
usage ();
|
|
exit (1);
|
|
}
|
|
|
|
omg_param_list[UE].nodes = atoi (optarg);
|
|
LOG_D (OMG, "#Number of UE nodes : %d \n",
|
|
omg_param_list[UE].nodes);
|
|
break;
|
|
|
|
case 'E':
|
|
if (atoi (optarg) < 0) {
|
|
usage ();
|
|
exit (1);
|
|
}
|
|
|
|
omg_param_list[eNB].nodes = atoi (optarg);
|
|
LOG_D (OMG, "#Number of eNB nodes : %d \n",
|
|
omg_param_list[eNB].nodes);
|
|
break;
|
|
|
|
case 'R':
|
|
if (atoi (optarg) < 0) {
|
|
usage ();
|
|
exit (1);
|
|
}
|
|
|
|
omg_param_list[RELAY].nodes = atoi (optarg);
|
|
LOG_D (OMG, "#Number of relay nodes : %d \n",
|
|
omg_param_list[RELAY].nodes);
|
|
break;
|
|
|
|
case 'k':
|
|
if (atof (optarg) < 0)
|
|
LOG_E (OMG, "#Number of frames can not be negative \n");
|
|
|
|
n_frames = abs (atof (optarg));
|
|
LOG_D (OMG, "#Number of frames : %f \n", n_frames);
|
|
break;
|
|
|
|
case 'u':
|
|
if (atoi (optarg) < 0 || atoi (optarg) >= MAX_NUM_MOB_TYPES) {
|
|
usage ();
|
|
exit (1);
|
|
}
|
|
|
|
omg_param_list[UE].mobility_type = atoi (optarg);
|
|
LOG_D (OMG, "#UE nodes mobility type: %d \n",
|
|
omg_param_list[UE].mobility_type);
|
|
break;
|
|
|
|
case 'e':
|
|
if (atoi (optarg) < 0 || atoi (optarg) >= MAX_NUM_MOB_TYPES) {
|
|
usage ();
|
|
exit (1);
|
|
}
|
|
|
|
omg_param_list[eNB].mobility_type = atoi (optarg);
|
|
LOG_D (OMG, "#eNB nodes mobility type: %d \n",
|
|
omg_param_list[eNB].mobility_type);
|
|
break;
|
|
|
|
case 'r':
|
|
if (atoi (optarg) < 0 || atoi (optarg) >= MAX_NUM_MOB_TYPES) {
|
|
usage ();
|
|
exit (1);
|
|
}
|
|
|
|
omg_param_list[RELAY].mobility_type = atoi (optarg);
|
|
LOG_D (OMG, "#relay nodes mobility type: %d \n",
|
|
omg_param_list[RELAY].mobility_type);
|
|
break;
|
|
|
|
case 's':
|
|
if (atof (optarg) < 0)
|
|
LOG_E (OMG, "#min sleep can not be negative \n");
|
|
|
|
omg_param_list[UE].min_sleep = fabs (atof (optarg));
|
|
LOG_D (OMG, "#UE min sleep is set to: %.2f \n",
|
|
omg_param_list[UE].min_sleep);
|
|
break;
|
|
|
|
case 'S':
|
|
if (atof (optarg) < 0)
|
|
LOG_E (OMG, "#max_sleep can not be negative \n");
|
|
|
|
omg_param_list[UE].max_sleep = fabs (atof (optarg));
|
|
LOG_D (OMG, "#UE max_sleep is set to : %.2f \n",
|
|
omg_param_list[UE].max_sleep);
|
|
break;
|
|
|
|
case 'l':
|
|
if (atof (optarg) < 0)
|
|
LOG_E (OMG, "#min sleep can not be negative or zero \n");
|
|
|
|
if (atof (optarg) != 0)
|
|
omg_param_list[eNB].min_sleep = fabs (atof (optarg));
|
|
|
|
LOG_D (OMG, "#eNB min sleep is set to : %.2f \n",
|
|
omg_param_list[eNB].min_sleep);
|
|
break;
|
|
|
|
case 'L':
|
|
if (atof (optarg) <= 0)
|
|
LOG_E (OMG, "#max_sleep can not be negative or zero \n");
|
|
|
|
if (atof (optarg) != 0)
|
|
omg_param_list[eNB].max_sleep = fabs (atof (optarg));
|
|
|
|
LOG_D (OMG, "#eNB max_sleep is set to : %.2f \n",
|
|
omg_param_list[eNB].max_sleep);
|
|
break;
|
|
|
|
case 'p':
|
|
if (atof (optarg) < 0)
|
|
LOG_E (OMG, "#min sleep can not be negative \n");
|
|
|
|
omg_param_list[RELAY].min_sleep = fabs (atof (optarg));
|
|
LOG_D (OMG, "#relay min sleep is set to: %.2f \n",
|
|
omg_param_list[RELAY].min_sleep);
|
|
break;
|
|
|
|
case 'P':
|
|
if (atof (optarg) < 0)
|
|
LOG_E (OMG, "#max_sleep can not be negative \n");
|
|
|
|
omg_param_list[RELAY].max_sleep = fabs (atof (optarg));
|
|
LOG_D (OMG, "#relay max_sleep is set to : %.2f \n",
|
|
omg_param_list[RELAY].max_sleep);
|
|
break;
|
|
|
|
case 'd':
|
|
if (atof (optarg) < 0)
|
|
LOG_E (OMG, "#min_speed can not be negative \n");
|
|
|
|
if (atof (optarg) != 0)
|
|
omg_param_list[UE].min_speed = fabs (atof (optarg));
|
|
|
|
LOG_D (OMG, "#UE min_speed is set to: %.2f \n",
|
|
omg_param_list[UE].min_speed);
|
|
break;
|
|
|
|
case 'D':
|
|
if (atof (optarg) < 0)
|
|
LOG_E (OMG, "#max_speed can not be negative \n");
|
|
|
|
omg_param_list[UE].max_speed = fabs (atof (optarg));
|
|
LOG_D (OMG, "#UE max_speed is set to: %.2f \n",
|
|
omg_param_list[UE].max_speed);
|
|
break;
|
|
|
|
case 'i':
|
|
if (atof (optarg) < 0)
|
|
LOG_E (OMG, "#min_speed can not be negative \n");
|
|
|
|
if (atof (optarg) != 0)
|
|
omg_param_list[eNB].min_speed = fabs (atof (optarg));
|
|
|
|
LOG_D (OMG, "#eNB min_speed is set to: %.2f \n",
|
|
omg_param_list[eNB].min_speed);
|
|
break;
|
|
|
|
case 'I':
|
|
if (atof (optarg) < 0)
|
|
LOG_E (OMG, "#max_speed can not be negative \n");
|
|
|
|
omg_param_list[eNB].max_speed = fabs (atof (optarg));
|
|
LOG_D (OMG, "#eNB max_speed is set to : %.2f \n",
|
|
omg_param_list[eNB].max_speed);
|
|
break;
|
|
|
|
case 'a':
|
|
if (atof (optarg) < 0)
|
|
LOG_E (OMG, "#min_speed can not be negative \n");
|
|
|
|
if (atof (optarg) != 0)
|
|
omg_param_list[RELAY].min_speed = fabs (atof (optarg));
|
|
|
|
LOG_D (OMG, "#relay min_speed is set to : %.2f \n",
|
|
omg_param_list[RELAY].min_speed);
|
|
break;
|
|
|
|
case 'A':
|
|
if (atof (optarg) < 0)
|
|
LOG_E (OMG, "#max_speed can not be negative \n");
|
|
|
|
omg_param_list[RELAY].max_speed = fabs (atof (optarg));
|
|
LOG_D (OMG, "#relay max_speed is set to: %.2f \n",
|
|
omg_param_list[RELAY].max_speed);
|
|
break;
|
|
|
|
case 'v':
|
|
omv_enabled = 1;
|
|
break;
|
|
|
|
case 'X':
|
|
omg_param_list[UE].max_x = fabs (atof (optarg));
|
|
LOG_D (OMG, "#UE X_max : %.2f \n", omg_param_list[UE].max_x);
|
|
break;
|
|
|
|
case 'x':
|
|
omg_param_list[UE].min_x = fabs (atof (optarg));
|
|
LOG_D (OMG, "#UE X_min : %.2f \n", omg_param_list[UE].min_x);
|
|
break;
|
|
|
|
case 'C':
|
|
omg_param_list[eNB].max_x = fabs (atof (optarg));
|
|
LOG_D (OMG, "#eNB X_max : %.2f \n", omg_param_list[eNB].max_x);
|
|
break;
|
|
|
|
case 'c':
|
|
omg_param_list[eNB].min_x = fabs (atof (optarg));
|
|
LOG_D (OMG, "#eNB X_min : %.2f \n", omg_param_list[eNB].min_x);
|
|
break;
|
|
|
|
case 'B':
|
|
omg_param_list[RELAY].max_x = fabs (atof (optarg));
|
|
LOG_D (OMG, "#relay X_max : %.2f \n", omg_param_list[RELAY].max_x);
|
|
break;
|
|
|
|
case 'b':
|
|
omg_param_list[RELAY].min_x = fabs (atof (optarg));
|
|
LOG_D (OMG, "#relay X_min : %.2f \n", omg_param_list[RELAY].min_x);
|
|
break;
|
|
|
|
case 'Y':
|
|
omg_param_list[UE].max_y = fabs (atof (optarg));
|
|
LOG_D (OMG, "#UE Y_max : %.2f \n", omg_param_list[UE].max_y);
|
|
break;
|
|
|
|
case 'y':
|
|
omg_param_list[UE].min_y = fabs (atof (optarg));
|
|
LOG_D (OMG, "#UE Y_min : %.2f \n", omg_param_list[UE].min_y);
|
|
break;
|
|
|
|
case 'Z':
|
|
omg_param_list[eNB].max_y = fabs (atof (optarg));
|
|
LOG_D (OMG, "#eNB Y_max : %.2f \n", omg_param_list[eNB].max_y);
|
|
break;
|
|
|
|
case 'z':
|
|
omg_param_list[eNB].min_y = fabs (atof (optarg));
|
|
LOG_D (OMG, "#eNB Y_min : %.2f \n", omg_param_list[eNB].min_y);
|
|
break;
|
|
|
|
case 'W':
|
|
omg_param_list[RELAY].max_y = fabs (atof (optarg));
|
|
LOG_D (OMG, "#relay Y_max : %.2f \n", omg_param_list[RELAY].max_y);
|
|
break;
|
|
|
|
case 'w':
|
|
omg_param_list[RELAY].min_y = fabs (atof (optarg));
|
|
LOG_D (OMG, "#relay Y_min : %.2f \n", omg_param_list[RELAY].min_y);
|
|
break;
|
|
|
|
case 'J':
|
|
if (atof (optarg) < 0)
|
|
LOG_E (OMG, "#Journey_time_max can not be negative \n");
|
|
|
|
omg_param_list[UE].max_journey_time = fabs (atof (optarg));
|
|
LOG_D (OMG, "UE Journey_time_max : %.2f \n",
|
|
omg_param_list[UE].max_journey_time);
|
|
break;
|
|
|
|
case 'j':
|
|
if (atof (optarg) < 0)
|
|
LOG_E (OMG, "#Journey_time_min can not be negative \n");
|
|
|
|
omg_param_list[UE].min_journey_time = fabs (atof (optarg));
|
|
LOG_D (OMG, "#UE Journey_time_min : %.2f \n",
|
|
omg_param_list[UE].min_journey_time);
|
|
break;
|
|
|
|
case 'T':
|
|
if (atof (optarg) < 0)
|
|
LOG_E (OMG, "#Journey_time_max can not be negative \n");
|
|
|
|
omg_param_list[eNB].max_journey_time = fabs (atof (optarg));
|
|
LOG_D (OMG, "#eNB Journey_time_max : %.2f \n",
|
|
omg_param_list[eNB].max_journey_time);
|
|
break;
|
|
|
|
case 't':
|
|
if (atof (optarg) < 0)
|
|
LOG_E (OMG, "#Journey_time_min can not be negative \n");
|
|
|
|
omg_param_list[eNB].min_journey_time = fabs (atof (optarg));
|
|
LOG_D (OMG, "#eNB Journey_time_min : %.2f \n",
|
|
omg_param_list[eNB].min_journey_time);
|
|
break;
|
|
|
|
case 'N':
|
|
if (atof (optarg) < 0)
|
|
LOG_E (OMG, "#Journey_time_max can not be negative \n");
|
|
|
|
omg_param_list[RELAY].max_journey_time = fabs (atof (optarg));
|
|
LOG_D (OMG, "#relay Journey_time_max : %.2f \n",
|
|
omg_param_list[RELAY].max_journey_time);
|
|
break;
|
|
|
|
case 'n':
|
|
if (atof (optarg) < 0)
|
|
LOG_E (OMG, "#Journey_time_min can not be negative \n");
|
|
|
|
omg_param_list[RELAY].min_journey_time = fabs (atof (optarg));
|
|
LOG_D (OMG, "#relay Journey_time_min : %.2f \n",
|
|
omg_param_list[RELAY].min_journey_time);
|
|
break;
|
|
|
|
case 'f':
|
|
for (node_t = eNB; node_t < MAX_NUM_NODE_TYPES; node_t++) {
|
|
omg_param_list[node_t].seed = atoi (optarg);
|
|
LOG_D (OMG, "#Seed is %d \n", omg_param_list[node_t].seed);
|
|
}
|
|
|
|
break;
|
|
|
|
case 'g':
|
|
if (atoi (optarg) < 1 || atoi (optarg) > 2) {
|
|
LOG_E (OMG, "#value given for graph should be 1 or 2 \n");
|
|
exit (-1);
|
|
}
|
|
|
|
grid = abs (atof (optarg));
|
|
LOG_D (OMG, "#graph value is %d \n", grid);
|
|
break;
|
|
|
|
case 'h':
|
|
usage ();
|
|
break;
|
|
|
|
default:
|
|
usage ();
|
|
exit (1);
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**************************** main **********************************/
|
|
|
|
int
|
|
main (int argc, char *argv[]) {
|
|
int i, node_type;
|
|
double cur_time = 0.0;
|
|
double ms = 0.0;
|
|
node_list *current_positions = NULL;
|
|
node_struct *my_node = NULL;
|
|
int my_id = 0, time_s;
|
|
double emu_info_time;
|
|
char full_name[200];
|
|
int pfd[2]; // fd for omv : fixme: this could be a local var
|
|
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 fname[64], vname[64];
|
|
Data_Flow_Unit omv_data = {0};
|
|
|
|
//default parameters
|
|
for (node_type = eNB; node_type < MAX_NUM_NODE_TYPES; node_type++) {
|
|
if (node_type == UE)
|
|
omg_param_list[node_type].nodes = 5;
|
|
else
|
|
omg_param_list[node_type].nodes = 0;
|
|
|
|
omg_param_list[node_type].min_x = 0;
|
|
omg_param_list[node_type].max_x = 100;
|
|
omg_param_list[node_type].min_y = 0;
|
|
omg_param_list[node_type].max_y = 100;
|
|
omg_param_list[node_type].min_speed = 0.1;
|
|
omg_param_list[node_type].max_speed = 20.0;
|
|
omg_param_list[node_type].min_journey_time = 0.1;
|
|
omg_param_list[node_type].max_journey_time = 20.0;
|
|
omg_param_list[node_type].min_azimuth = 0;
|
|
omg_param_list[node_type].max_azimuth = 360;
|
|
omg_param_list[node_type].min_sleep = 0.1;
|
|
omg_param_list[node_type].max_sleep = 5.0;
|
|
omg_param_list[node_type].mobility_file = "TRACE/mobility_3ues.tr";
|
|
omg_param_list[node_type].mobility_type = STATIC;
|
|
omg_param_list[node_type].nodes_type = node_type;
|
|
//omg_param_list.sumo_config = "SUMO/SCENARIOS/traci.koln.sumo.cfg";
|
|
omg_param_list[node_type].sumo_command = "sumo-gui";
|
|
omg_param_list[node_type].sumo_config =
|
|
"SUMO/SCENARIOS/traci.scen.sumo.cfg";
|
|
omg_param_list[node_type].sumo_start = 0; //25900;
|
|
omg_param_list[node_type].sumo_end = 200; //26200;
|
|
omg_param_list[node_type].sumo_step = 1;
|
|
omg_param_list[node_type].sumo_host = "localhost";
|
|
omg_param_list[node_type].sumo_port = 8890;
|
|
}
|
|
|
|
init_omg_global_params (); //initialize global paramaters
|
|
get_options (argc, argv); // overwrite the default params if any input parameter
|
|
|
|
for (node_type = eNB; node_type < MAX_NUM_NODE_TYPES; node_type++) {
|
|
omg_param_list[node_type].max_vertices =
|
|
max_vertices_ongrid (omg_param_list[node_type]);
|
|
omg_param_list[node_type].max_block_num =
|
|
max_connecteddomains_ongrid (omg_param_list[node_type]);
|
|
}
|
|
|
|
init_mobility_generator (omg_param_list); //initialize choosen mobility generator
|
|
|
|
// ****************init omv********************
|
|
if (omv_enabled == 1) {
|
|
if (pipe (pfd) == -1)
|
|
perror ("pipe error \n");
|
|
|
|
sprintf (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:
|
|
if (close (pfd[1]) == -1)
|
|
perror ("close on write\n");
|
|
|
|
sprintf (fdstr, "%d", pfd[0]);
|
|
sprintf (num_enb, "%d", 1);
|
|
sprintf (num_ue, "%d", omg_param_list[UE].nodes);
|
|
sprintf (x_area, "%f", omg_param_list[UE].max_x);
|
|
sprintf (y_area, "%f", omg_param_list[UE].max_y);
|
|
sprintf (z_area, "%f", 200.0);
|
|
sprintf (frames, "%d", (int) n_frames);
|
|
execl (full_name, "OMV", fdstr, frames, num_enb, num_ue, x_area,
|
|
y_area, z_area, NULL);
|
|
perror ("error in execl the OMV");
|
|
}
|
|
|
|
//parent
|
|
if (close (pfd[0]) == -1)
|
|
perror ("close on read\n");
|
|
}
|
|
|
|
//******************************
|
|
|
|
for (emu_info_time = 0.0; emu_info_time <= n_frames; emu_info_time += 0.1) {
|
|
update_nodes (emu_info_time);
|
|
time_s = round (emu_info_time * 1000.0);
|
|
|
|
//printf("%d \n",time_s);
|
|
for (node_type = eNB; node_type < MAX_NUM_NODE_TYPES; node_type++) {
|
|
current_positions =
|
|
get_current_positions (omg_param_list[node_type].mobility_type,
|
|
node_type, emu_info_time);
|
|
|
|
if (current_positions != NULL)
|
|
display_job_list (emu_info_time,
|
|
job_vector[omg_param_list
|
|
[node_type].mobility_type]);
|
|
|
|
/*if(current_positions!= NULL && time_s %1000==0)
|
|
LOG_D(OMG, "%.2f %d\n",emu_info_time,
|
|
nodes_avgspeed(job_vector[omg_param_list [node_type].mobility_type])); */
|
|
}
|
|
|
|
//display current postion of nodes
|
|
if (omv_enabled == 1)
|
|
omv_write (pfd[1], node_vector[SUMO], omv_data);
|
|
}
|
|
|
|
/*LOG_I(OMG,"#-----event average-----\n");
|
|
for (i=0;i<100;i++)
|
|
{
|
|
if(events[i]!=0)
|
|
LOG_D(OMG,"%d %d \n",i,event_sum[i]/events[i]);
|
|
} */
|
|
stop_mobility_generator (omg_param_list);
|
|
|
|
if (omv_enabled == 1)
|
|
omv_end (pfd[1], omv_data);
|
|
|
|
//clear_mem();
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**********************************sumo****************************/
|
|
int
|
|
omv_write (int pfd, node_list *ue_node_list, Data_Flow_Unit omv_data) {
|
|
int i = 0, j;
|
|
omv_data.end = 0;
|
|
// enb
|
|
omv_data.geo[i].x = 0.0;
|
|
omv_data.geo[i].y = 0.0;
|
|
omv_data.geo[i].z = 1.0;
|
|
omv_data.geo[i].mobility_type = 0;
|
|
omv_data.geo[i].node_type = 0; //eNB
|
|
omv_data.geo[i].Neighbors = 0;
|
|
|
|
for (i = 1; i < omg_param_list[SUMO-1].nodes + 1; i++) {
|
|
if (ue_node_list != NULL) {
|
|
omv_data.geo[i].x =
|
|
(int) (ue_node_list->node->x_pos <
|
|
0.0) ? 0.0 : ue_node_list->node->x_pos;
|
|
omv_data.geo[i].y =
|
|
(int) (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 = omg_param_list[SUMO-1].mobility_type;
|
|
omv_data.geo[i].node_type = 1; //UE
|
|
ue_node_list = ue_node_list->next;
|
|
omv_data.geo[i].Neighbors = 0;
|
|
printf ("node %d at (%d, %d)\n", i, omv_data.geo[i].x,
|
|
omv_data.geo[i].y);
|
|
}
|
|
}
|
|
|
|
if (write (pfd, &omv_data, sizeof (struct Data_Flow_Unit)) == -1)
|
|
perror ("write omv failed");
|
|
|
|
return 1;
|
|
}
|
|
|
|
void
|
|
omv_end (int pfd, Data_Flow_Unit omv_data) {
|
|
omv_data.end = 1;
|
|
|
|
if (write (pfd, &omv_data, sizeof (struct Data_Flow_Unit)) == -1)
|
|
perror ("write omv failed");
|
|
}
|
|
#endif
|