Commit 1ca500d2 authored by Navid Nikaein's avatar Navid Nikaein

* update the Openair mobility generator, add steadystatefor RWP, trace-driven...

* update the Openair mobility generator, add steadystatefor RWP, trace-driven mobility, two grid-based mobility models (restricted RWP, and connected domains)


git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5576 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent a1f4f1e5
......@@ -53,6 +53,8 @@ typedef enum {
/* decomposition of node functions into jobs for a given event */
typedef enum Job_type_e { JT_OTG, JT_PDCP, JT_PHY_MAC, JT_INIT_SYNC, JT_DL, JT_UL, RN_DL, RN_UL, JT_END} Job_Type_t;
typedef enum Operation_Type_e { READ, WRITE, RESET} Operation_Type_t;
typedef struct Job_s {
enum Job_type_e type;
int exe_time; /* execution time at the worker*/
......@@ -87,9 +89,12 @@ typedef struct Packet_otg_s {
typedef struct {
Event_Type_t type;
enum Operation_Type_e optype; //op
char *key;
void *value;
frame_t frame;
int ue;
int lcid;
} Event_t;
/*typedef struct Global_Time {
......@@ -101,6 +106,8 @@ typedef struct {
double time_ms;
};*/
typedef struct Packet_otg_elt_s {
struct Packet_otg_elt_s *next;
struct Packet_otg_elt_s *previous;
......
......@@ -178,7 +178,7 @@ int logInit (void)
g_log->log_component[OMG].interval = 1;
g_log->log_component[OMG].fd = 0;
g_log->log_component[OMG].filelog = 0;
g_log->log_component[OMG].filelog_name = "";
g_log->log_component[OMG].filelog_name = "/tmp/omg.csv";
g_log->log_component[OTG].name = "OTG";
g_log->log_component[OTG].level = LOG_EMERG;
......
......@@ -50,7 +50,7 @@ OMG_OBJS += $(OMG_DIR)/job.o
OMG_OBJS += $(OMG_DIR)/static.o
OMG_OBJS += $(OMG_DIR)/rwp.o
OMG_OBJS += $(OMG_DIR)/rwalk.o
OMG_OBJS += $(OMG_DIR)/omg_hashtable.o
#OMG_OBJS += $(OMG_DIR)/omg_hashtable.o
OMG_OBJS += $(OMG_DIR)/mobility_parser.o
OMG_OBJS += $(OMG_DIR)/trace.o
OMG_OBJS += $(OMG_DIR)/sumo.o
......@@ -58,6 +58,10 @@ OMG_OBJS += $(OMG_DIR)/id_manager.o
OMG_OBJS += $(OMG_DIR)/client_traci_OMG.o
OMG_OBJS += $(OMG_DIR)/storage_traci_OMG.o
OMG_OBJS += $(OMG_DIR)/socket_traci_OMG.o
OMG_OBJS += $(OMG_DIR)/steadystaterwp.o
OMG_OBJS += $(OMG_DIR)/grid.o
OMG_OBJS += $(OMG_DIR)/trace_hashtable.o
OTG_OBJS = $(OTG_DIR)/otg_tx.o
OTG_OBJS += $(OTG_DIR)/otg.o
......
......@@ -295,6 +295,7 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need
////// options of UE_Mobility_Type
typedef struct
{
char *selected_option;
int horizontal_grid;
int vertical_grid;
} Grid_Map;
......@@ -464,6 +465,32 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need
/* @}*/
typedef struct
{
uint16_t priority[11];//pas possible d'acceder au MAX_NUM_LCID
//
uint8_t DCI_aggregation_min;
uint8_t DLSCH_dci_size_bits;
//UL transmission bandwidth in RBs
uint8_t ul_bandwidth[11];
//DL transmission bandwidth in RBs
uint8_t dl_bandwidth[11];
//UL transmission bandwidth in RBs
uint8_t min_ul_bandwidth[11];
//DL transmission bandwidth in RBs
uint8_t min_dl_bandwidth[11];
//aggregated bit rate of non-gbr bearer per UE
uint64_t ue_AggregatedMaximumBitrateDL;
//aggregated bit rate of non-gbr bearer per UE
uint64_t ue_AggregatedMaximumBitrateUL;
//CQI scheduling interval in subframes.
uint16_t cqiSchedInterval;
//Contention resolution timer used during random access
uint8_t mac_ContentionResolutionTimer;
uint16_t max_allowed_rbs[11];
uint8_t max_mcs[11];
} Mac_config;
/** @defgroup _Predefined_traffic Configuration
* @ingroup _OSD_basic
* @brief Including Application type, Source, destination, background, etc
......@@ -685,6 +712,7 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need
unsigned char omg_model_rn;
unsigned char omg_model_enb;
unsigned char omg_model_ue;
unsigned char omg_rwp_type;
unsigned char omg_model_ue_current; // when mixed mbility is used
// control eNB/UE instance through CLI
unsigned char cli_enabled;
......@@ -733,6 +761,7 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need
* @{*/
typedef struct
{
Mac_config mac_config[NUMBER_OF_UE_MAX];
Environment_System_Config environment_system_config; /*!< \brief Evironment configuration */
Topology_Config topology_config; /*!< \brief Topology configuration */
Application_Config application_config; /*!< \brief Applications configuration */
......
......@@ -1016,13 +1016,17 @@ void characters(void *user_data, const xmlChar *xmlch, int xmllen) { // called o
if (UE_mobility_) {
if (UE_mobility_type_) {
oai_emulation.topology_config.mobility.UE_mobility.UE_mobility_type.selected_option = strndup(ch, len);
} else if (grid_walk_) {
}else if (grid_walk_) {
if (grid_map_) {
oai_emulation.topology_config.mobility.UE_mobility.grid_walk.grid_map.selected_option = strndup(ch, len);
/*
if (horizontal_grid_) {
oai_emulation.topology_config.mobility.UE_mobility.grid_walk.grid_map.horizontal_grid = atoi(ch);
} else if (vertical_grid_) {
oai_emulation.topology_config.mobility.UE_mobility.grid_walk.grid_map.vertical_grid = atoi(ch);
}
*/
} else if (grid_trip_type_) {
oai_emulation.topology_config.mobility.UE_mobility.grid_walk.grid_trip_type.selected_option = strndup(ch, len);
}
......@@ -1087,6 +1091,7 @@ void characters(void *user_data, const xmlChar *xmlch, int xmllen) { // called o
} else if (eNB_mobility_) {
if (eNB_mobility_type_) {
oai_emulation.topology_config.mobility.eNB_mobility.eNB_mobility_type.selected_option = strndup(ch, len);
} else if (eNB_initial_distribution_) {
oai_emulation.topology_config.mobility.eNB_mobility.eNB_initial_distribution.selected_option = strndup(ch, len);
} else if (eNB_initial_coordinates_) {
......
......@@ -105,12 +105,12 @@ void init(int max_sim_time) {
sendExact(storageLength(storageStart));
extractCommandStatus(receiveExact(), CMD_SUBSCRIBE_SIM_VARIABLE, description);
if (departed == NULL) {
departed = (String_list)malloc(sizeof(String_list)); // departed MUST point to HEAD
departed = (string_list*) malloc(sizeof(string_list)); // departed MUST point to HEAD
departed->string = NULL;
departed->next = NULL;
}
if (arrived == NULL) {
arrived = (String_list)malloc(sizeof(String_list)); // arrived MUST point to HEAD
arrived = (string_list*) malloc(sizeof(string_list)); // arrived MUST point to HEAD
arrived->string = NULL;
arrived->next = NULL;
}
......@@ -123,8 +123,8 @@ void init(int max_sim_time) {
void processSubscriptions() {
int noSubscriptions = readInt();
String_list tmp_departed = departed;
String_list tmp_arrived = arrived;
string_list* tmp_departed = departed;
string_list* tmp_arrived = arrived;
int s;
for (s = 0; s<noSubscriptions; ++s) {
......@@ -240,12 +240,12 @@ void commandSimulationStep(double time)
extractCommandStatus(receiveExact(), CMD_SIMSTEP2, description);
if (departed == NULL) {
departed = (String_list)malloc(sizeof(String_list)); // departed MUST point to HEAD
departed = (string_list*) malloc(sizeof(string_list)); // departed MUST point to HEAD
departed->string = NULL;
departed->next = NULL;
}
if (arrived == NULL) {
arrived = (String_list)malloc(sizeof(String_list)); // arrived MUST point to HEAD
arrived = (string_list*) malloc(sizeof(string_list)); // arrived MUST point to HEAD
arrived->string = NULL;
arrived->next = NULL;
}
......@@ -402,14 +402,14 @@ int commandGetMaxSUMONodesVariable()
void GetSpeed(NodePtr node, char * sumo_id)
void GetSpeed(node_struct* node, char * sumo_id)
{
commandGetVehicleVariable(sumo_id, VAR_SPEED);
double speed_double = readDouble();
node->mob->speed = speed_double;
}
void GetPosition(NodePtr node, char * sumo_id)
void GetPosition(node_struct* node, char * sumo_id)
{
commandGetVehicleVariable(sumo_id, VAR_POSITION);
double x_double = readDouble();
......@@ -420,6 +420,6 @@ void GetPosition(NodePtr node, char * sumo_id)
if (y_double < 0.0)
y_double = 0.0;
node->X_pos = x_double;
node->Y_pos = y_double;
node->x_pos = x_double;
node->y_pos = y_double;
}
......@@ -56,8 +56,8 @@ int targetTime;
char *description;
String_list departed; // string list of all vehicles appearing in SUMO at the current time step
String_list arrived; // string list of all vehicles leaving SUMO at the current time step
string_list* departed; // string list of all vehicles appearing in SUMO at the current time step
string_list* arrived; // string list of all vehicles leaving SUMO at the current time step
/**
* Global parameters defined in storage_traci_OMG.h
......@@ -89,10 +89,10 @@ int extractCommandStatus(storage *, unsigned char , char *);
void commandSimulationStep(double);
/**
* \fn commandClose();
* \fn commandClose(void);
* \brief Send termination command to SUMO
*/
void commandClose();
void commandClose(void);
/**
* \fn commandGetVehicleVariable(char *vehID, int varID)
......@@ -103,10 +103,10 @@ void commandGetVehicleVariable(char *vehID, int varID);
/**
* \fn get_num_sumo_nodes()
* \fn get_num_sumo_nodes(void)
* \brief Return the total number of nodes to be simulated in SUMO
*/
int commandGetMaxSUMONodesVariable();
int commandGetMaxSUMONodesVariable(void);
/**
* \fn init(int max_sim_time)
......@@ -126,7 +126,7 @@ void processSubscriptions(void);
* \param NodePtr node the pointer to the OAISim node
* \param char *sumo_id the SUMO ID of the target node
*/
void GetSpeed(NodePtr node, char * sumo_id);
void GetSpeed(node_struct* node, char * sumo_id);
/**
* \fn void Position(NodePtr node, char * sumo_id);
......@@ -134,7 +134,7 @@ void GetSpeed(NodePtr node, char * sumo_id);
* \param NodePtr node the pointer to the OAISim node
* \param char *sumo_id the SUMO ID of the target node
*/
void GetPosition(NodePtr node, char * sumo_id);
void GetPosition(node_struct* node, char * sumo_id);
#endif
......
......@@ -47,127 +47,175 @@
#define frand() ((double) rand() / (RAND_MAX+1))
//#ifndef STANDALONE
mapping nodes_type[] =
{
{"eNB", eNB},
{"UE", UE},
mapping nodes_type[] = {
{"eNB", eNB}
,
{"UE", UE}
,
{NULL, -1}
};
mapping nodes_status[] =
{
{"sleeping", 0},
{"moving", 1},
mapping nodes_status[] = {
{"sleeping", 0}
,
{"moving", 1}
,
{NULL, -1}
};
mapping mob_type[] =
{
{"STATIC", STATIC},
{"RWP", RWP},
{"RWALK", RWALK},
{"TRACE", TRACE},
{"SUMO", SUMO},
mapping mob_type[] = {
{"STATIC", STATIC}
,
{"RWP", RWP}
,
{"RWALK", RWALK}
,
{"TRACE", TRACE}
,
{"SUMO", SUMO}
,
{NULL, -1}
};
//#endif
NodePtr create_node(void) {
NodePtr ptr;
ptr = calloc(1, sizeof(node_struct));
node_struct *
create_node (void)
{
node_struct *ptr;
ptr = calloc (1, sizeof (node_struct));
return ptr;
}
void delete_node(NodePtr node) {
free(node->mob);
void
delete_node (node_struct * node)
{
free (node->mob);
node->mob = NULL;
free(node);
free (node);
}
double randomGen(double a, double b){
double
randomgen (double a, double b)
{
return ( rand()/(double)RAND_MAX ) * (b-a) + a;
return (rand () / (double) RAND_MAX) * (b - a) + a;
}
MobilityPtr create_mobility(void) {
MobilityPtr ptr;
ptr = calloc(1, sizeof(mobility_struct));
mobility_struct *
create_mobility (void)
{
mobility_struct *ptr;
ptr = calloc (1, sizeof (mobility_struct));
return ptr;
}
Node_list add_entry(NodePtr node, Node_list Node_Vector){
Node_list entry = malloc(sizeof(node_list_struct));
node_list *
add_entry (node_struct * node, node_list * node_vector_end)
{
node_list *entry = malloc (sizeof (struct node_list_struct));
entry->node = node;
entry->next = NULL;
if (Node_Vector == NULL) {
// LOG_D(OMG, "\nempty Node_list");
//LOG_D(OMG, "\nadded elmt ID %d\n", entry->node->ID);
if (node_vector_end == NULL)
{
return entry;
}
else {
Node_list tmp = Node_Vector;
while (tmp->next != NULL){
tmp = tmp->next;
}
else
{
node_list *tmp = node_vector_end;
tmp->next = entry;
//LOG_D(OMG, "\nnon empty Node_list");
//LOG_D(OMG, "added elmt ID %d\n", entry->node->ID);
return Node_Vector;
}
return entry;
}
Node_list remove_node_entry(NodePtr node, Node_list Node_Vector){
Node_list list = Node_Vector;
Node_list tmp, toRemove;
if (list == NULL){
node_list *
remove_node_entry (node_struct * node, node_list * node_vector)
{
node_list *list = node_vector;
node_list *tmp, *toremove;
if (list == NULL)
{
return NULL;
}
if(list->node->ID == node->ID) {
if (list->node->id == node->id)
{
// TODO delete the entry
toRemove = list;
LOG_D(OMG,"removed entry for node %d \n",list->node->ID);
if(list->next ==NULL) {
Node_Vector = NULL;
toremove = list;
LOG_D (OMG, "removed entry for node %d \n", list->node->id);
if (list->next == NULL)
{
node_vector = NULL;
return NULL;
}
else {
Node_Vector = list->next;
else
{
node_vector = list->next;
}
}
else{
while (list->next !=NULL) {
else
{
while (list->next != NULL)
{
tmp = list;
if(list->next->node->ID == node->ID) {
toRemove = tmp; // TODO delete the entry
if (list->next->node->id == node->id)
{
toremove = tmp; // TODO delete the entry
tmp = list->next->next;
if(tmp !=NULL) {
if (tmp != NULL)
{
list->next = tmp;
}
else{
else
{
list->next = NULL;
}
}
}
}
return Node_Vector;
return node_vector;
}
// display list of nodes
void display_node_list(Node_list Node_Vector){
Node_list tmp = Node_Vector;
while ((tmp != NULL) &&
(tmp->node != NULL)){
LOG_I(OMG,"[%s][%s] Node of ID %d is %s. Now, it is at location (%.3f, %.3f)\n",
void
display_node_list (node_list * node_vector)
{
node_list *tmp = node_vector;
if (tmp == NULL)
{
#ifdef STANDALONE
printf ("Empty Node_list\n");
#else
LOG_I (OMG, "Empty Node_list\n");
#endif
}
while (tmp != NULL)
{
/*LOG_I(OMG,"[%s][%s] Node of ID %d is %s. Now, it is at location (%.3f, %.3f)\n",
map_int_to_str(mob_type, tmp->node->generator),
map_int_to_str(nodes_type, tmp->node->type),
tmp->node->ID,
map_int_to_str(nodes_status, tmp->node->mobile),
tmp->node->X_pos,
tmp->node->Y_pos );
tmp->node->Y_pos ); */
LOG_I (OMG, "[%s %d][%s] \t at (%.3f, %.3f)\n",
map_int_to_str(nodes_type, tmp->node->type),
tmp->node->id,
map_int_to_str(mob_type, tmp->node->generator),
tmp->node->x_pos, tmp->node->y_pos);
// two options: view node mobility of one node during the entire simulation or just a snapshot of all nodes for different timestamps
// note:gnu plot requiredifferent files for each timestamp
//use a python script to postprocess the positions, check the
// support: view node mobility of one node during the entire simulation OR only one snapshot
LOG_F(OMG,"%d; %.3f; %.3f; %.3f\n",
tmp->node->id,
tmp->node->x_pos, tmp->node->y_pos);
//LOG_I(OMG, "node number %d\tstatus(fix/mobile) %d\tX_pos %.2f\tY_pos %.2f\tnode_type(eNB, UE)%d\t", tmp->node->ID,tmp->node->mobile, tmp->node->X_pos,tmp->node->Y_pos, tmp->node->type);
//LOG_D(OMG, "mob->X_from %.3f\tmob->Y_from %.3f\tmob->X_to %.3f\tmob->Y_to %.3f\t", tmp->node->mob->X_from,tmp->node->mob->Y_from, tmp->node->mob->X_to, tmp->node->mob->Y_to );
......@@ -175,71 +223,89 @@ void display_node_list(Node_list Node_Vector){
}
}
void display_node_position(int ID, int generator, int type, int mobile, double X, double Y){
LOG_I(OMG,"[%s][%s] Node of ID %d is %s. Now, it is at location (%.2f, %.2f) \n",
map_int_to_str(mob_type, generator),
map_int_to_str(nodes_type, type),
ID,
map_int_to_str(nodes_status, mobile),
X,
Y
);
void
display_node_position (int id, int generator, int type, int mobile, double x,
double y)
{
LOG_I (OMG,
"[%s][%s] Node of ID %d is %s. Now, it is at location (%.2f, %.2f) \n",
map_int_to_str (mob_type, generator), map_int_to_str (nodes_type,
type), id,
map_int_to_str (nodes_status, mobile), x, y);
}
Node_list filter(Node_list Vector, int node_type){
Node_list tmp1, tmp2;
tmp1 = Vector;
node_list *
filter (node_list * vector, int node_type)
{
node_list *tmp1, *tmp2;
tmp1 = vector;
tmp2 = NULL;
while (tmp1 != NULL){
if (tmp1->node->type == node_type){
tmp2 = add_entry(tmp1->node, tmp2);
while (tmp1 != NULL)
{
if (tmp1->node->type == node_type)
{
tmp2 = add_entry (tmp1->node, tmp2);
}
tmp1 = tmp1->next;
}
return tmp2;
}
void delete_node_entry(Node_list entry) {
NodePtr node = entry->node;
delete_node(node);
void
delete_node_entry (node_list * entry)
{
node_struct *node = entry->node;
delete_node (node);
entry->node = NULL;
free(entry);
free (entry);
}
Node_list remove_node(Node_list list, int nID, int node_type){
node_list *
remove_node (node_list * list, int nid, int node_type)
{
int found;
Node_list current, previous;
node_list *current, *previous;
//int cond=0;
//int i=0;
if (list == NULL){
if (list == NULL)
{
found = 1; //false
return NULL;
}
else{ //start search
else
{ //start search
current = list;
while ((current != NULL) && ((current->node->ID != nID) || (current->node->type != node_type ))){
while ((current != NULL)
&& ((current->node->id != nid)
|| (current->node->type != node_type)))
{
previous = current; // previous hobbles after
current = current->next;
}
//holds: current = NULL or type != node_type or.., but not both
if (current ==NULL) {
found= 1 ;
LOG_E(OMG," Element to remove is not found\n ");
if (current == NULL)
{
found = 1;
LOG_E (OMG, " Element to remove is not found\n ");
return NULL;
} //value not found
else{
else
{
found = 0; // true value found
if (current == list) {
if (current == list)
{
list = current->next;
LOG_D(OMG,"Element to remove is found at beginning\n");
LOG_D (OMG, "Element to remove is found at beginning\n");
}
else {
else
{
previous->next = current->next;
}
delete_node_entry(current); // freeing memory
delete_node_entry (current); // freeing memory
current = NULL;
}
......@@ -247,35 +313,49 @@ Node_list remove_node(Node_list list, int nID, int node_type){
}
}
int length(char* s){
int
length (char *s)
{
int count = 0;
while(s[count] != '\0'){
while (s[count] != '\0')
{
++count;
}
return count;
}
NodePtr find_node(Node_list list, int nID, int node_type){
node_struct *
find_node (node_list * list, int nid, int node_type)
{
int found;
Node_list current;
node_list *current;
if (list == NULL){
printf(" Node_LIST for nodeID %d is NULL \n ",nID);
if (list == NULL)
{
printf (" Node_LIST for nodeID %d is NULL \n ", nid);
return NULL;
}
else{ //start search
else
{ //start search
current = list;
while ((current != NULL) && ((current->node->ID != nID) || (current->node->type != node_type ))){
while ((current != NULL)
&& ((current->node->id != nid)
|| (current->node->type != node_type)))
{
current = current->next;
}
//holds: current = NULL or type != node_type or.., but not both
if (current ==NULL) {
found= 1 ;
LOG_D(OMG," Element to find in Node_Vector with ID: %d could not be found\n ",nID);
if (current == NULL)
{
found = 1;
LOG_D (OMG,
" Element to find in Node_Vector with ID: %d could not be found\n ",
nid);
return NULL;
} //value not found
else{
else
{
//printf(" found a node for nodeID %d \n ",nID);
return current->node;
}
......@@ -283,33 +363,43 @@ NodePtr find_node(Node_list list, int nID, int node_type){
}
}
Node_list clear_node_list(Node_list list) {
Node_list tmp;
node_list *
clear_node_list (node_list * list)
{
node_list *tmp;
if (list == NULL){
if (list == NULL)
{
return NULL;
}
else{
while (list->next !=NULL) {
else
{
while (list->next != NULL)
{
tmp = list;
list = list->next;
delete_node_entry(tmp);
delete_node_entry (tmp);
}
delete_node_entry(list); // clearing the last one
delete_node_entry (list); // clearing the last one
}
return NULL;
}
// TODO rewrite this part...not working correctly
Node_list reset_node_list(Node_list list) {
Node_list tmp;
Node_list last = list;
if (list == NULL){
node_list *
reset_node_list (node_list * list)
{
node_list *tmp;
node_list *last = list;
if (list == NULL)
{
//printf("Node_list is NULL\n");
return NULL;
}
else{
while (list->next !=NULL) {
else
{
while (list->next != NULL)
{
tmp = list;
list = list->next;
tmp->node = NULL;
......@@ -322,19 +412,24 @@ Node_list reset_node_list(Node_list list) {
}
// TODO rewrite this part...not working correctly
String_list clear_String_list(String_list list) {
String_list tmp;
string_list *
clear_string_list (string_list * list)
{
string_list *tmp;
if (list == NULL){
if (list == NULL)
{
return NULL;
}
else{
while (list->next !=NULL) {
else
{
while (list->next != NULL)
{
tmp = list;
list = list->next;
free(tmp->string);
free (tmp->string);
tmp->string = NULL;
free(tmp);
free (tmp);
}
list->string = NULL; // clearing the last one | JHNOTE: dangerous here: the pointer is not NULL, but node is...that leads to segfault...
}
......@@ -347,32 +442,43 @@ String_list clear_String_list(String_list list) {
* with string value NULL
*/
/* map a string to an int. Takes a mapping array and a string as arg */
int map_str_to_int(mapping *map, const char *str){
while (1) {
if (map->name == NULL) {
return(-1);
int
map_str_to_int (mapping * map, const char *str)
{
while (1)
{
if (map->name == NULL)
{
return (-1);
}
if (!strcmp(map->name, str)) {
return(map->value);
if (!strcmp (map->name, str))
{
return (map->value);
}
map++;
}
}
/* map an int to a string. Takes a mapping array and a value */
char *map_int_to_str(mapping *map, int val) {
while (1) {
if (map->name == NULL) {
char *
map_int_to_str (mapping * map, int val)
{
while (1)
{
if (map->name == NULL)
{
return NULL;
}
if (map->value == val) {
if (map->value == val)
{
return map->name;
}
map++;
}
}
#endif
#endif
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
Copyright(c) 1999 - 2011 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
......@@ -28,16 +28,9 @@
*******************************************************************************/
/**
* \file defs.h
* \brief Typedefs & Prototypes of OMG functions
* \author Navid Nikaein and Andre Gomes (one source)
* \date 2014
* \version 1.0
* \company Eurecom
* \email: navid.nikaein@eurecom.fr
* \note
* \warning
*/
* \file defs.h
* \brief Typedefs & Prototypes of OMG functions
*/
#ifndef __DEFS_H__
#define __DEFS_H__
......@@ -61,69 +54,90 @@ int map_str_to_int(mapping *map, const char *str);
char *map_int_to_str(mapping *map, int val);
#endif
/*!A sructure that includes all the characteristic mobility elements of a node */
typedef struct mobility_struct {
double X_from; /*!< The X coordinate of the previous location of the node */
double Y_from; /*!< The Y coordinate of the previous location of the node */
double X_to; /*!< The X coordinate of the destination location of the node */
double Y_to; /*!< The Y coordinate of the destination location of the node */
/****************************************************************************
!A sructure that includes all the characteristic mobility elements of a node
*****************************************************************************/
struct mobility_struct {
double x_from; /*!< The X coordinate of the previous location of the node */
double y_from; /*!< The Y coordinate of the previous location of the node */
double x_to; /*!< The X coordinate of the destination location of the node */
double y_to; /*!< The Y coordinate of the destination location of the node */
double speed; /*!< The speed of the node */
double sleep_duration; /*!< The sleep duration of the node (Used with the RWP model) */
double azimuth; /*!< The direction in which the node moves (Used with RWALK model) */
double journey_time; /*!< The duration of the node trip */
double start_journey; /*!< The instant on which the node trip starts*/
double target_time;/*!<The time instant before the node should complete>*/ double target_speed;/*!<The time instant before the node should complete>*/
}mobility_struct;
double target_time;/*!<The time instant before the node should complete>*/
double target_speed;/*!<The time instant before the node should complete>*/
};
typedef struct mobility_struct *MobilityPtr; /*!< The typedef that reflects a #mobility_struct*/
typedef struct mobility_struct mobility_struct; /*!< The typedef that reflects a #mobility_struct*/
/*!A sructure that defines a node and its associated informaion */
typedef struct node_struct {
int ID; /*!< The identifier of the node in question */
/******************************************************************************
!A sructure that defines a node and its associated informaion
*******************************************************************************/
struct node_struct {
int id; /*!< The identifier of the node in question */
int gid; /*!< given id of node used for trace mobility */
int type; /*!< The node's type, it is one of types enumarated in #node_types */
int mobile; /*!< The node status: static or mobile */
double X_pos; /*!< The X coordinate of the current location of the node */
double Y_pos; /*!< The Y coordinate of the current location of the node */
mobility_struct *mob; /*!< An instantiation of the structure #mobility_struct that includes the mobility elements corresponding to the node*/
double x_pos; /*!< The X coordinate of the current location of the node */
double y_pos; /*!< The Y coordinate of the current location of the node */
struct mobility_struct *mob; /*!< An instantiation of the structure #mobility_struct that includes the mobility elements corresponding to the node*/
int generator; /*!< The mobility generator according to which the node is moving or stagnating. It is one of the types enumarated in #mobility_types*/
}node_struct;
int block_num; /*!<block identification for connected domain rwp*/
int event_num;
};
typedef struct node_struct* NodePtr; /*!< The typedef that reflects a #node_struct*/
typedef struct node_struct node_struct; /*!< The typedef that reflects a #node_struct*/
/*!A sructure that gathers all the existing nodes */
/********************************************************************************
!A sructure that gathers all the existing nodes
*********************************************************************************/
struct node_list_struct {
node_struct *node; /*!< Avariable of type #NodePtr. It represents a node */
struct node_struct *node; /*!< Avariable of type #NodePtr. It represents a node */
struct node_list_struct *next; /*!< A pointer to the next element */
}node_list_struct;
};
typedef struct node_list_struct* Node_list; /*!< The typedef that reflects a #node_list_struct*/
typedef struct node_list_struct node_list; /*!< The typedef that reflects a #node_list_struct*/
/*!A sructure that represents a peer (Node, Time), i.e the node in question and its job (move or sleep) execution time. It is the atomic component of the #job_list_struct structure*/
typedef struct pair_struct {
/********************************************************************************
!A sructure that represents a peer (Node, Time),
i.e the node in question and its job (move or sleep) execution time.
It is the atomic component of the #job_list_struct structure
*********************************************************************************/
struct pair_struct {
node_struct *b; /*!< A variable of type #NodePtr. It represents a node */
double a; /*!< The corresponding time of job execution */
}pair_struct;
double next_event_t; /*!< The corresponding time of job execution */
};
typedef struct pair_struct* Pair; /*!< The typedef that reflects a #pair_struct*/
typedef struct pair_struct pair_struct; /*!< The typedef that reflects a #pair_struct*/
/*!A sructure that gathers the jobs to be executed by all the non static nodes. In the context of OMG, a job is either a move or a sleep */
/*****************************************************************************
!A sructure that gathers the jobs to be executed by all the non static nodes.
In the context of OMG, a job is either a move or a sleep
*****************************************************************************/
struct job_list_struct {
Pair pair; /*!< A variable of type #Pair. It represents a (Node, job-execution Time) peer */
pair_struct* pair; /*!< A variable of type #Pair. It represents a (Node, job-execution Time) peer */
struct job_list_struct *next; /*!< A pointer to the next element */
}job_list_struct;
typedef struct job_list_struct* Job_list; /*!< The typedef that reflects a #job_list_struct*/
};
typedef struct job_list_struct job_list; /*!< The typedef that reflects a #job_list_struct*/
/*!A sructure that gathers the ultimate parameters needed to launch a simulation scenario */
typedef struct omg_global_param{
/****************************************************************************************
!A sructure that gathers the ultimate parameters needed to launch a simulation scenario
***************************************************************************************/
typedef struct{
int nodes; /*!< The total number of nodes */
double min_X; /*!< The minimum value that the X coordinate might take. In other words, the minimum boundary of the simulation area according to the X axis */
double max_X; /*!< The maximum value that the X coordinate might take, i.e the maximum boundary of the simulation area according to the X axis*/
double min_Y; /*!< The minimum value that the Y coordinate might take, i.e the minimum boundary of the simulation area according to the Y axis */
double max_Y; /*!< The minimum value that the Y coordinate might take, i.e the maximum boundary of the simulation area according to the Y axis */
//int number_of_nodes[MAX_NUM_NODE_TYPES];
double min_x; /*!< The minimum value that the X coordinate might take. In other words, the minimum boundary of the simulation area according to the X axis */
double max_x; /*!< The maximum value that the X coordinate might take, i.e the maximum boundary of the simulation area according to the X axis*/
double min_y; /*!< The minimum value that the Y coordinate might take, i.e the minimum boundary of the simulation area according to the Y axis */
double max_y; /*!< The minimum value that the Y coordinate might take, i.e the maximum boundary of the simulation area according to the Y axis */
bool user_fixed; /*!< Sets if the coordinates are user defined*/
double fixed_X; /*!< The user defined x value*/
double fixed_Y; /*!< The user defined y value*/
double fixed_x; /*!< The user defined x value*/
double fixed_y; /*!< The user defined y value*/
double min_speed; /*!< The minimum speed. It should be different than 0.0 in order to avoid instability*/
double max_speed; /*!< The maximum allowed speed */
double min_journey_time; /*!< The minimum allowed trip duration. It should be different than 0.0 in order to avoid instability and properly reflect the mobility model behavior */
......@@ -133,7 +147,12 @@ typedef struct omg_global_param{
double min_sleep; /*!< The minimum allowed sleep duration. It should be different than 0.0 in order to avoid instability */
double max_sleep; /*!< The minimum allowed sleep duration*/
int mobility_type; /*!< The chosen mobility model for the nodes in question. It should be one of the types inumarated as #mobility_types*/
int rwp_type; /*!< The chosen RWP mobility model for the nodes in question either RESTRICTED or CONNECTED_DOMAIN. */
int nodes_type; /*!< The type of the nodes in question. It should be one of the types inumarated as #node_types */
//int nodes_mob_type[MAX_NUM_NODE_TYPES];
int max_vertices; /*!<maximum number of verices in the grid>*/
int max_block_num; /*!<maximum number of blocks in the grid>*/
int seed; /*!< The seed used to generate the random positions*/
char* mobility_file; /*!< The mobility file name containing the mobility traces used by the TRACE model; DEFAULT: TRACE/example_trace.tr */
char* sumo_command; /*!< The command to start SUMO; Either 'sumo' or 'sumo-gui' in case a GUI would be required; see SUMO for further details; DEFAULT: sumo */
......@@ -145,13 +164,15 @@ typedef struct omg_global_param{
int sumo_port; /*!< The port number attached to SUMO on the host DEFAULT: TBC */
}omg_global_param;
/*!A string List structure */
/******************************************************************************
!A string List structure
*******************************************************************************/
struct string_list_struct {
char* string; /*! a string */
struct string_list_struct *next; /*!< A pointer to the next string in the list */
}string_list_struct;
};
typedef struct string_list_struct* String_list; /*!< The typedef that reflects a #string_list_struct*/
typedef struct string_list_struct string_list; /*!< The typedef that reflects a #string_list_struct*/
/* PROTOTYPES */
......@@ -171,7 +192,7 @@ void update_node_vector(int mobility_type, double cur_time);
* \param nID a variable of type int that represents the specific node's ID
* \return a NodePtr structure that stores the updated information about the specific node ((X,Y) coordinates), speed, etc.)
*/
NodePtr get_node_position(int node_type, int nID);
node_struct* get_node_position(int node_type, int nid);
/**
......@@ -181,7 +202,7 @@ NodePtr get_node_position(int node_type, int nID);
* \param Node_Vector a pointer of type Node_list that represents the Node_Vector storing all the nodes of the specified mobility type
* \return the Node_list to which a new entry is added
*/
Node_list add_entry(NodePtr node, Node_list Node_Vector);
node_list* add_entry(node_struct* node, node_list* node_vector);
/**
* \fn Node_list remove_node_entry(NodePtr node, Node_list Node_Vector)
......@@ -191,14 +212,14 @@ Node_list add_entry(NodePtr node, Node_list Node_Vector);
* \param Node_Vector a pointer of type Node_list that represents the Node_Vector storing all the nodes of the specified mobility type
* \return the Node_list to which a new entry is removed
*/
Node_list remove_node_entry(NodePtr node, Node_list Node_Vector);
node_list* remove_node_entry(node_struct* node, node_list* node_vector);
/**
* \fn void display_node_list(Node_list Node_Vector)
* \brief Display the useful informaion about the specified Node_list (for instance the nodes IDs, their types (UE, eNB, etc.), their corresponding mobility models, their status (moving, sleeping) and their current positions)
* \param Node_Vector a pointer of type Node_list that represents the Node_list to be dispalyed
*/
void display_node_list(Node_list Node_Vector);
void display_node_list(node_list* node_vector);
/**
......@@ -209,7 +230,7 @@ void display_node_list(Node_list Node_Vector);
* \param node_type an int that represents the type of the node to be removed from the Node_list
* \return a pointer to the Node_list from which a new entry is removed
*/
Node_list remove_node(Node_list list, int nID, int node_type);
node_list* remove_node(node_list* list, int nid, int node_type);
/**
* \fn NodePtr find_node(Node_list list, int nID, int node_type)
......@@ -219,21 +240,21 @@ Node_list remove_node(Node_list list, int nID, int node_type);
* \param node_type an int that represents the type of the node to be located in the Node_list
* \return a pointer to the Node
*/
NodePtr find_node(Node_list list, int nID, int node_type);
node_struct* find_node(node_list* list, int nid, int node_type);
/**
* \fn void delete_entry(Node_list Node_Vector)
* \brief Delete a Node_list entry node; calls delete_node to subsequently delete the node; free the memory
* \param list a pointer of type Node_list that represents the entry to be deleted
*/
void delete_entry(Node_list Node_Vector);
void delete_entry(node_list* node_vector);
/**
* \fn void delete_entry(NodePtr node)
* \brief Delete a node, and all subsequent data in its structure; free the memory
* \param node a pointer to the node that should be deleted
*/
void delete_node(NodePtr node);
void delete_node(node_struct* node);
/**
* \fn void clear node_List(Node_list list)
......@@ -241,7 +262,7 @@ void delete_node(NodePtr node);
* \param list a pointer of type Node_list that represents the list to be cleared
* \return reference to the HEAD of the cleared Node_list
*/
Node_list clear_node_List(Node_list list);
node_list* clear_node_List(node_list* list);
/**
* \fn void init_node_list(Node_list list)
......@@ -249,7 +270,7 @@ Node_list clear_node_List(Node_list list);
* \param list a pointer of type Node_list that represents the list to be reset
* \return reference to the HEAD of the reset Node_list
*/
Node_list reset_node_list(Node_list list);
node_list* reset_node_list(node_list* list);
/**
* \fn void display_node_position(int ID, int generator, int type, int mobile, double X, double Y)
......@@ -261,7 +282,7 @@ Node_list reset_node_list(Node_list list);
* \param X the node's current location according to the X axis
* \param Y the node's current location according to the Y axis
*/
void display_node_position(int ID, int generator, int type, int mobile, double X, double Y);
void display_node_position(int id, int generator, int type, int mobile, double x, double y);
/**
......@@ -271,7 +292,7 @@ void display_node_position(int ID, int generator, int type, int mobile, double X
* \param node_type the desired type
* \return a pointer to a new Node_list which is the input Node_list after filtering
*/
Node_list filter(Node_list Vector, int node_type);
node_list* filter(node_list* vector, int node_type);
/**
......@@ -281,7 +302,7 @@ Node_list filter(Node_list Vector, int node_type);
* \param b upper limit
* \return double: the generated random number
*/
double randomGen(double a, double b);
double randomgen(double a, double b);
/**
......@@ -289,7 +310,7 @@ double randomGen(double a, double b);
* \brief Creates a new #NodePtr by allocating the needed memory space for it
* \return the created node structure
*/
NodePtr create_node(void);
node_struct* create_node(void);
/**
......@@ -297,7 +318,7 @@ NodePtr create_node(void);
* \brief Creates a new #MobilityPtr by allocating the needed memory space for it
* \return the created mobility structure
*/
MobilityPtr create_mobility(void);
mobility_struct* create_mobility(void);
/**
......@@ -307,7 +328,8 @@ MobilityPtr create_mobility(void);
* \param Job_Vector a variable #Job_list that represents the Job_list that stores all the scheduled jobs
* \return the created mobility structure
*/
Job_list add_job(Pair job, Job_list Job_Vector);
job_list* add_job(pair_struct* job, job_list* job_vector);
job_list* addjob(pair_struct* job, job_list* job_vector);
/**
......@@ -315,9 +337,11 @@ Job_list add_job(Pair job, Job_list Job_Vector);
* \brief Traverse the Job_Vector to diplay its contents
* \param Job_Vector the structure that stoks all the jobs
*/
void display_job_list(Job_list Job_Vector);
void display_job_list(double curr_t, job_list* job_vector);
/**
*time average of nodes speed
*/
unsigned int nodes_avgspeed(job_list* job_vector);
/**
* \fn Job_list job_list_sort (Job_list list, Job_list end)
* \brief Called by the function Job_list quick_sort (Job_list list), it executes the quick sort
......@@ -325,7 +349,7 @@ void display_job_list(Job_list Job_Vector);
* \param end Job_list needed for intermediate computation
* \return a Job_list that is used by Job_list quick_sort (Job_list list) to perform the sort operation
*/
Job_list job_list_sort (Job_list list, Job_list end);
job_list* job_list_sort (job_list* list, job_list* end);
/**
......@@ -334,7 +358,7 @@ Job_list job_list_sort (Job_list list, Job_list end);
* \param list the structure that stoks all the jobs
* \return the sorted list
*/
Job_list quick_sort (Job_list list);
job_list* quick_sort (job_list* list);
/**
......@@ -345,7 +369,7 @@ Job_list quick_sort (Job_list list);
* \param node_type the type of the node whose job should be removed
* \return the updated Job_list after removing the job in question
*/
Job_list remove_job(Job_list list, int nID, int node_type);
job_list* remove_job(job_list* list, int nid, int node_type);
/**
* \fn int length(char* s)
......@@ -361,7 +385,7 @@ int length(char* s);
* \param list the String_list to be cleared;
* \return reference to the HEAD of the cleared String_list
*/
String_list clear_String_list(String_list list);
string_list* clear_string_list(string_list* list);
/**
* \fn void usage()
......
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2011 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.frm
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fsr/openairinterface
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
*******************************************************************************/
/*! \file grid.c
* \brief
* \author S. Gashaw, N. Nikaein, J. Harri
* \date 2014
* \version 0.1
* \company Eurecom
* \email:
* \note
* \warning
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include "grid.h"
#define LEFT 0
#define RIGHT 1
#define UPPER 2
#define LOWER 3
int
max_vertices_ongrid (omg_global_param omg_param)
{
return ((int) (omg_param.max_x / xloc_div + 1.0) *
(int) (omg_param.max_y / yloc_div + 1.0)) - 1;
}
int
max_connecteddomains_ongrid (omg_global_param omg_param)
{
return ((int) (omg_param.max_x / xloc_div) *
(int) (omg_param.max_y / yloc_div)) - 1;
}
double
vertice_xpos (int loc_num, omg_global_param omg_param)
{
int div, mod;
double x_pos;
div = (int) (omg_param.max_x / xloc_div + 1.0);
mod = (loc_num % div) * xloc_div;
x_pos = omg_param.min_x + (double) mod;
//LOG_D(OMG,"mod %d div %d x pos %.2f \n\n",mod,div,x_pos);
return x_pos;
}
double
vertice_ypos (int loc_num, omg_global_param omg_param)
{
//LOG_D(OMG,"y pos %.2f \n\n",omg_param.min_y + (double)yloc_div * (int)( loc_num / (int)(omg_param.max_x/xloc_div + 1.0) ));
return omg_param.min_y +
(double) yloc_div *(int) (loc_num /
(int) (omg_param.max_x / xloc_div + 1.0));
}
double
area_minx (int block_num, omg_global_param omg_param)
{
return omg_param.min_x +
xloc_div * (block_num % (int) (omg_param.max_x / xloc_div));
}
double
area_miny (int block_num, omg_global_param omg_param)
{
return omg_param.min_y +
yloc_div * (int) (block_num / (int) (omg_param.max_x / xloc_div));
}
/*for connected domain that only move to the neighbor domains */
unsigned int
next_block (int current_bn, omg_global_param omg_param)
{
double rnd = randomgen (0, 1);
unsigned int blk;
int div = (int) (omg_param.max_x / xloc_div);
/*left border blocks*/
if ((current_bn % div) == 0)
{
/*case 1 for left upper and lower corners(only 2 neighbors) */
if ((int) (current_bn / div) == 0)
{
if (rnd <= 0.5)
blk = selected_blockn (current_bn, RIGHT, div);
else
blk = selected_blockn (current_bn, UPPER, div);
}
else if ((int) (current_bn / div) ==
(int) (omg_param.max_y / yloc_div) - 1)
{
if (rnd <= 0.5)
blk = selected_blockn (current_bn, RIGHT, div);
else
blk = selected_blockn (current_bn, LOWER, div);
}
/*for 3 neighbor blocks */
else
{
if (rnd <= 0.33)
blk = selected_blockn (current_bn, RIGHT, div);
else if (rnd > 0.33 && rnd <= 0.66)
blk = selected_blockn (current_bn, UPPER, div);
else
blk = selected_blockn (current_bn, LOWER, div);
}
}
/*right boredr blocks*/
else if ((current_bn % (int) (omg_param.max_x / xloc_div)) == div - 1)
{
/*case 1 for right upper and lower corners(only 2 neighbors) */
if ((int) (current_bn / div) == 0)
{
if (rnd <= 0.5)
blk = selected_blockn (current_bn, LEFT, div);
else
blk = selected_blockn (current_bn, UPPER, div);
}
else if ((int) (current_bn / div) ==
(int) (omg_param.max_y / yloc_div) - 1)
{
if (rnd <= 0.5)
blk = selected_blockn (current_bn, LEFT, div);
else
blk = selected_blockn (current_bn, LOWER, div);
}
/*for 3 neighbor blocks */
else
{
if (rnd <= 0.33)
blk = selected_blockn (current_bn, LEFT, div);
else if (rnd > 0.33 && rnd <= 0.66)
blk = selected_blockn (current_bn, UPPER, div);
else
blk = selected_blockn (current_bn, LOWER, div);
}
}
/*for 3 neighbor uper and lower borders*/
else if ((int) (current_bn / div) == 0
|| (int) (current_bn / div) ==
(int) (omg_param.max_y / yloc_div) - 1)
{
if ((int) (current_bn / div) == 0)
{
if (rnd <= 0.33)
blk = selected_blockn (current_bn, LEFT, div);
else if (rnd > 0.33 && rnd <= 0.66)
blk = selected_blockn (current_bn, RIGHT, div);
else
blk = selected_blockn (current_bn, UPPER, div);
}
else
{
if (rnd <= 0.33)
blk = selected_blockn (current_bn, LEFT, div);
else if (rnd > 0.33 && rnd <= 0.66)
blk = selected_blockn (current_bn, RIGHT, div);
else
blk = selected_blockn (current_bn, LOWER, div);
}
}
else
{
if (rnd <= 0.25)
blk = selected_blockn (current_bn, LEFT, div);
else if (rnd > 0.25 && rnd <= 0.50)
blk = selected_blockn (current_bn, RIGHT, div);
else if (rnd > 0.50 && rnd <= 0.75)
blk = selected_blockn (current_bn, UPPER, div);
else
blk = selected_blockn (current_bn, LOWER, div);
}
return blk;
}
/*retun the block number of neighbor selected for next move */
unsigned int
selected_blockn (int block_n, int type, int div)
{
unsigned int next_blk = 0;
switch (type)
{
case LEFT:
next_blk = block_n - 1;
break;
case RIGHT:
next_blk = block_n + 1;
break;
case UPPER:
next_blk = block_n + div;
break;
case LOWER:
next_blk = block_n - div;
break;
default:
LOG_E (OMG, "wrong type input\n");
}
return next_blk;
}
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2011 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fsr/openairinterface
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
*******************************************************************************/
/**
* \file grid.h **/
#ifndef GRID_H_
#define GRID_H_
#include "omg.h"
int max_vertices_ongrid(omg_global_param omg_param);
int max_connecteddomains_ongrid(omg_global_param omg_param);
double vertice_xpos(int loc_num, omg_global_param omg_param);
double vertice_ypos(int loc_num, omg_global_param omg_param);
double area_minx(int block_num, omg_global_param omg_param);
double area_miny(int block_num, omg_global_param omg_param);
unsigned int next_block(int current_bn, omg_global_param omg_param);
unsigned int selected_blockn(int block_n,int type,int div);
#endif
......@@ -29,8 +29,8 @@
/*! \file job.c
* \brief handle jobs for future nodes' update
* \author M. Mahersi, J. Harri, N. Nikaein,
* \date 2011
* \author S. Gashaw, M. Mahersi, J. Harri, N. Nikaein,
* \date 2014
* \version 0.1
* \company Eurecom
* \email:
......@@ -44,42 +44,78 @@
#include "omg.h"
Job_list add_job(Pair job, Job_list Job_Vector){
Job_list entry = malloc(sizeof(Job_list));
job_list *
add_job (pair_struct * job, job_list * job_vector)
{
job_list *tmp;
job_list *entry = (job_list *) malloc (sizeof (struct job_list_struct));
entry->pair = job;
entry->next = NULL;
if (job_vector != NULL)
{
//LOG_D(OMG, " Job_Vector_len %d", Job_Vector_len);
tmp = job_vector;
tmp->next = entry;
}
return entry;
}
//add_job2
job_list *
addjob (pair_struct * job, job_list * job_vector)
{
job_list *tmp;
job_list *entry = (job_list *) malloc (sizeof (struct job_list_struct));
entry->pair = job;
entry->next = NULL;
if (Job_Vector == NULL) {
//LOG_D(OMG, "empty Job_Vector\n");
//LOG_D(OMG, "added elmt ID %d\n", entry->pair->b->ID);
if (job_vector == NULL)
{
return entry;
}
else {
Job_list tmp = Job_Vector;
while (tmp->next != NULL){
else
{
tmp = job_vector;
while (tmp->next != NULL)
{
tmp = tmp->next;
}
tmp->next = entry;
//LOG_D(OMG, "non empty Job_Vector\n");
//LOG_D(OMG, "dded elmt ID %d\n", entry->pair->b->ID);
return Job_Vector;
tmp->next = entry;
}
}
return job_vector;
}
// display list of jobs
void display_job_list(Job_list Job_Vector){
void
display_job_list (double curr_t, job_list * job_vector)
{
Job_list tmp = Job_Vector;
if (tmp == NULL){LOG_D(OMG, "Empty Job_list\n");}
else{
job_list *tmp = job_vector;
if (tmp == NULL)
{
LOG_D (OMG, "Empty Job_list\n");
}
else
{
//LOG_D(OMG, "first_Job_time in Job_Vector %f\n", Job_Vector->pair->a);
while (tmp != NULL){
if ((tmp->pair != NULL))
LOG_D(OMG, "node %d \ttime %.2f\n", tmp->pair->b->ID, tmp->pair->a);
while (tmp != NULL)
{
if ((tmp->pair != NULL) /*&& tmp->pair->b->id==0 */ )
//LOG_D(OMG, "%.2f %.2f \n",tmp->pair->b->x_pos, tmp->pair->b->y_pos);
LOG_D (OMG, "%.2f %d %d %.2f %.2f %.2f\n", curr_t, tmp->pair->b->id,tmp->pair->b->gid,
tmp->pair->b->x_pos, tmp->pair->b->y_pos,
tmp->pair->b->mob->speed);
tmp = tmp->next;
......@@ -87,19 +123,48 @@ void display_job_list(Job_list Job_Vector){
}
}
//average nodes speed for each mobility type
unsigned int
nodes_avgspeed (job_list * job_vector)
{
job_list *tmp = job_vector;
unsigned int avg = 0, cnt = 0;
if (tmp == NULL)
{
LOG_D (OMG, "Empty Job_list\n");
return 0;
}
else
{
while (tmp != NULL)
{
if ((tmp->pair != NULL))
{
avg += tmp->pair->b->mob->speed;
cnt++;
}
tmp = tmp->next;
}
}
return avg / cnt;
}
// quick sort of the linked list
Job_list job_list_sort (Job_list list, Job_list end){
job_list *
job_list_sort (job_list * list, job_list * end)
{
Job_list pivot, tmp, next, before, after;
if ( list != end && list->next != end ){
job_list *pivot, *tmp, *next, *before, *after;
if (list != end && list->next != end)
{
pivot = list;
before = pivot;
after = end;
for ( tmp=list->next; tmp != end; tmp=next )
for (tmp = list->next; tmp != end; tmp = next)
{
next = tmp->next;
if (tmp->pair->a > pivot->pair->a)
if (tmp->pair->next_event_t > pivot->pair->next_event_t)
tmp->next = after, after = tmp;
else
tmp->next = before, before = tmp;
......@@ -114,57 +179,37 @@ Job_list job_list_sort (Job_list list, Job_list end){
return list;
}
Job_list quick_sort (Job_list list)
job_list *
quick_sort (job_list * list)
{
return job_list_sort(list, NULL);
return job_list_sort (list, NULL);
}
Job_list remove_job(Job_list list, int nID, int node_type){
Job_list current, previous;
//int cond=0;
int i=0;
if (list == NULL){
return NULL;
}
else{ //start search
current = list;
if ((current != NULL) && (current->pair->b->ID == nID) && (current->pair->b->type == node_type )){LOG_D(OMG, "(current != NULL) && (current->pair->b->ID != nID) && (current->pair->b->type != node_type ");}
while ( (current != NULL) && ((current->pair->b->ID != nID) || (current->pair->b->type != node_type ))){
LOG_D(OMG, "current->pair->b->ID %d",current->pair->b->ID);
LOG_D(OMG, "nID %d",nID);
LOG_D(OMG, "current->pair->b->type %d",current->pair->b->type ); // UE, eNB 1
LOG_D(OMG, "node_type %d",node_type ); //UE, eNB 0
LOG_D(OMG, "current->pair->b->generator %d",current->pair->b->generator ); //static
LOG_D(OMG, "i = %d", i);
previous = current; // previous hobbles after
current = current->next;
i++;
if (current ==NULL){LOG_D(OMG, "current ==NULL");}
job_list *
remove_job (job_list * list, int nid, int node_type)
{
}
job_list *current, *previous;
current = list;
previous = NULL;
while (current != NULL)
{
if (current->pair->b->id == nid && current->pair->b->type == node_type)
{
if (current == list || previous == NULL)
list = current->next;
else
previous->next = current->next;
//if (current->pair->b->ID == nID){LOG_D(OMG, "current->pair->b->ID == nID");}
//if (current->pair->b->type == node_type){LOG_D(OMG, "current->pair->b->type == node_type");}
free (current);
break;
if (current ==NULL) {
LOG_D(OMG," Job to remove is not found\n "); //LOG_N
return NULL;
} //value not found
else{
if (current == list) {
list = current->next ;
LOG_D(OMG,"Job to remove is found at the beginning\n");
}
else {
previous->next = current->next;
}
previous = current;
current = current->next;
}
return list;
}
}
}
CC= gcc
OBJstatic = omg.c common.c static.c
OBJrwp = omg.c common.c job.c rwp.c
OBJrwp = omg.c common.c job.c rwp.c grid.c
OBJrwalk = omg.c common.c job.c rwalk.c
OBJtrace = omg.c common.c job.c trace.c mobility_parser.c omg_hashtable.c
OBJtrace = omg.c common.c job.c trace.c mobility_parser.c hashtable.c
OBJsumo = omg.c common.c sumo.c client_traci_OMG.c socket_traci_OMG.c storage_traci_OMG.c id_manager.c
OBJ = omg.c common.c static.c job.c rwp.c rwalk.c trace.c sumo.c mobility_parser.c omg_hashtable.c client_traci_OMG.c socket_traci_OMG.c storage_traci_OMG.c id_manager.c
OBJ = omg.c common.c static.c job.c rwp.c rwalk.c trace.c steadystaterwp.c sumo.c grid.c mobility_parser.c hashtable.c client_traci_OMG.c socket_traci_OMG.c storage_traci_OMG.c id_manager.c
CFLAGS += -DSTANDALONE -DUSER_MODE
CFLAGS += -DSTANDALONE -DUSER_MODE -g
.PHONY: help staticOMG rwpOMG clean
......
......@@ -29,11 +29,11 @@
/*! \file mobility_parser.c
* \brief A parser for trace-based mobility information (parsed from a file)
* \author S. Uppoor
* \date 2011
* \author S. Gashaw, N. Nikaein, J. Harri
* \date 2014
* \version 0.1
* \company INRIA
* \email: sandesh.uppoor@inria.fr
* \company EURECOM
* \email:
* \note
* \warning
*/
......@@ -42,442 +42,226 @@
#include <string.h>
#include <stdlib.h>
#include "mobility_parser.h"
#include "omg_hashtable.h"
#include "omg.h"
#include <math.h>
extern hash_table_t **table;
extern node_info **list_head;
node_info* head_node_info =NULL;
omg_hash_table_t* table=NULL;
//read the mobility file and generates a hashtable of linked list
void
parse_data (char *trace_file, int node_type)
{
FILE *fp;
char *pch, *p;
char str[128];
int fmt, id = 0, gid;
node_container *value;
//need to be removed , used only once (old code)
struct Exnode* gen_list(){
struct Exnode* head = NULL;
return head;
}
//if(table==NULL)
create_new_table (node_type);
if(list_head ==NULL)
list_head = (node_info **) calloc (MAX_NUM_NODE_TYPES, sizeof (node_info*));
//read the mobility file and generates a hashtable of linked list with key pointing to vehicle id
void read_mobility_file(char* mobility_file[]){
FILE *fp;
char str[128],*p;
if (table == NULL){
table = hash_table_new(MODE_ALLREF);
if (list_head == NULL )
{
LOG_E (OMG, "-------node list table creation failed--------\n");
exit (-1);
}
if((fp=fopen(mobility_file, "r"))==NULL) {
LOG_D(OMG,"Cannot open file %s\n", mobility_file);
exit(1);
if ((fp = fopen (trace_file, "r")) == NULL)
{
LOG_E (OMG, "[OMG]:Cannot open file %s\n", trace_file);
exit (1);
}
Exnode* headRef;
static node_info* Node_info=NULL;
int *keyholder[10];
int i=0;
while(!feof(fp)) {
if(fgets(str, 126, fp)) { // happy go for small mobility file :-)
char * pch;
int fmt=0;
p=str;
while(*p==' ' || *p=='\t') p++; // skip whitespaces
if(*p=='\r') p++;
if (*p!='\n') {
pch = strtok (p," "); // the separator between the items in the list is a space
Exnode* node = malloc(sizeof(Exnode));
while (pch != NULL){
node->visit=0;
switch(fmt){
while (!feof (fp))
{
if (fgets (str, 126, fp))
{
fmt = 0;
p = str;
while (*p == ' ' || *p == '\t' || *p == '\r')
p++; // skip whitespaces
if (*p != '\n') //escape empty line
{
pch = strtok (p, " "); // the separator between the items in the list is a space
node_data *node = (node_data *) calloc (1, sizeof (node_data));
node->type=-1;
while (pch != NULL)
{
switch (fmt)
{
case 0:
node->time=(atof(pch));
if (atof (pch) < 0)
LOG_E (OMG, "error: negative time input \n");
node->time = fabs (atof (pch));
LOG_D (OMG, "%.2f \n",node->time);
break;
case 1:
node->vid =atoi(pch);
node->vid = atoi (pch);
LOG_D (OMG, "%d \n",node->vid);
break;
case 2:
node->x=atof(pch);
node->x_pos = atof (pch);
LOG_D (OMG, "%.2f \n",node->x_pos);
break;
case 3:
node->y=atof(pch);
node->y_pos = atof (pch);
LOG_D (OMG, "%.2f \n",node->y_pos);
break;
case 4:
node->speed=atof(pch);
if (atof (pch) < 0)
LOG_D (OMG, "error: negative speed input");
node->speed = fabs (atof (pch));
LOG_D (OMG, "speed %.2f \n",node->speed);
break;
/*case 5:
node->type = atof (pch);
break;*/
default:
//need a log statement here
LOG_E (OMG,
"[Error in trance file]:incorrect data format \n");
break;
}
fmt +=1;
fmt += 1;
pch = strtok (NULL, " ");
}
node->next=NULL;
//check in the hash table if the key exist node->vid if exist ? initialize headRef
int *value = NULL;
value = (int *)HT_LOOKUP(table, &(node->vid));
node->next = NULL;
node->visit = 0;
if (value==NULL){
if (Node_info==NULL){
Node_info=build_node_info(Node_info,node->vid,&(node->vid));
head_node_info=Node_info;
}
else{
Node_info=build_node_info(Node_info,node->vid,&(node->vid));
}
Node_info->next=NULL;
//LOG_D(OMG,"[TRACE] build info for node %d %d head %p node %p next %p\n",
// Node_info->vid, node->vid, head_node_info, Node_info, Node_info->next);
keyholder[i]=&node->vid;
i++;
hash_table_add(table, &(node->vid), sizeof(node->vid), node, sizeof(node));
headRef=gen_list();
// look for node in node info
gid = find_node_info (node->vid, node_type);
if (gid == -1)
{
node->gid = id;
add_node_info (node->vid, node->gid, node_type);
//store node data in the table
hash_table_add (table[node_type], node, NULL);
id++;
}
else{
//puts("Yes node exist");
headRef = (Exnode *)value;
//printf("value returned %f\n",headRef->time);
//printf("After from hash %p %d\n",headRef, headRef->vid );
}
if (headRef!=NULL){
AppendNode(headRef, node);
}
else
{
node->gid = gid;
value = hash_table_lookup (table[node_type], node->gid);
hash_table_add (table[node_type], node, value);
}
}
}
fclose(fp);
//return table;
}
//builds linked list with each node holding vehicle is and linked list pointer on the hastable
node_info* build_node_info(node_info* headRef, int vid, int *vid_addr){
node_info* newNode=malloc(sizeof(node_info));
newNode->vid=vid;
newNode->vid_addr=vid_addr;
if (headRef==NULL){
headRef=newNode;
return headRef;
}
while(headRef->next!=NULL){
headRef = headRef->next;
}
if (headRef->next==NULL ){
headRef->next = newNode;
}
return headRef->next;
}
void AppendNode(struct Exnode* headRef, struct Exnode* newNode) {
while(headRef->next!=NULL){
headRef = headRef->next;
}
if (headRef->next==NULL ){
headRef->next = newNode;
}
}
//Just used for testing, it prints a linked list given the head pointer
void print_list(struct Exnode* head){
fclose (fp);
while(head->next !=NULL)
head=head->next;
}
Exnode* get_next_position(omg_hash_table_t *table,int node_id){
node_info* head_node=head_node_info;
while(head_node->next!=NULL){
if(head_node->vid==node_id){
int *value1 = NULL;
value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
if (value1!=NULL){
Exnode* value2=(Exnode *)value1;
while(value2->next!=NULL){
if (value2->visit==1) value2=value2->next;
else {
value2->visit=1;
return value2;
}
}
if (value2->visit!=1){
value2->visit=1;
return value2;
}
}
}
head_node=head_node->next;
}
// not to leave the last node with ->next=NULL
if(head_node->vid==node_id){
int *value1 = NULL;
value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
if (value1!=NULL){
Exnode* value2=(Exnode *)value1;
while(value2->next!=NULL){
if (value2->visit==1) value2=value2->next;
else {
value2->visit=1;
return value2;
}
}
if (value2->visit!=1){
value2->visit=1;
return value2;
}
}
}
return NULL;
}
void reset_visit_status(omg_hash_table_t *table,float time, int node_id){
node_info* head_node=head_node_info;
while(head_node->next!=NULL){
//search for node given id if exist
if(head_node->vid==node_id){
int *value1 = NULL;
value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
if (value1!=NULL){
Exnode* value2=(Exnode *)value1;
while(value2->next!=NULL){
if (value2->time == time) {
value2->visit=0;
}
value2=value2->next;
}
if (value2->time == time){
value2->visit=0;
}
}
}
head_node=head_node->next;
}
// not to leave the last node with ->next=NULL
if(head_node->vid==node_id){
int *value1 = NULL;
value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
if (value1!=NULL){
Exnode* value2=(Exnode *)value1;
while(value2->next!=NULL){
if (value2->time==time) value2->visit=0;
value2=value2->next;
}
if (value2->time==time) value2->visit=0;
int
find_node_info (int vid, int node_type)
{
node_info *search;
if (list_head[node_type] != NULL)
{
search = list_head[node_type];
while (search != NULL)
{
if (search->vid == vid)
return search->g_id;
search = search->next;
}
}
return -1;
}
int get_num_nodes(){
int count=1; //Last node also need to be counted
node_info * head_node=head_node_info;
while (head_node->next!=NULL){
count += 1;
head_node=head_node->next;
//builds linked list with each node holding vehicle id read from file & given id
void
add_node_info (int nid, int n_gid, int node_type)
{
node_info *new = (node_info *) malloc (sizeof (node_info));
if (new != NULL)
{
new->vid = nid;
new->g_id = n_gid;
new->next = NULL;
if (list_head[node_type] == NULL)
list_head[node_type] = new;
else
{
node_info *temp, *save;
temp = list_head[node_type];
while (temp != NULL)
{
save = temp;
temp = temp->next;
}
save->next = new;
}
}
else
{
LOG_E (OMG, "node info list creation failed\n");
exit (-1);
}
return count;
}
void sort_veh_movement(omg_hash_table_t *table){
node_info* head_node=head_node_info;
while(head_node->next!=NULL){
int *value1 = NULL;
value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
Exnode* head_veh_node = (Exnode *)value1;
Exnode* value2 = (Exnode *)value1;
while (value2->next!=NULL){
value2 = value2->next;
}
Exnode* tail_veh_node = (Exnode *)value2;
quicksortlist(head_veh_node, tail_veh_node);
head_node=head_node->next;
}
// come on !! use functions :-)
// last node with ->next == NULL
int *value1 = NULL;
value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
Exnode* head_veh_node = (Exnode *)value1;
Exnode* value2 = (Exnode *)value1;
while (value2->next!=NULL){
value2 = value2->next;
}
Exnode* tail_veh_node = (Exnode *)value2;
quicksortlist(head_veh_node, tail_veh_node);
}
// quick sort list
void quicksortlist(Exnode *pLeft, Exnode *pRight){
Exnode *pStart;
Exnode *pCurrent;
double swp_time;
int swp_vid;
double swp_x;
double swp_y;
double swp_speed;
int swp_visit;
// If the left and right pointers are the same, then return
if (pLeft == pRight) return;
// Set the Start and the Current item pointers
pStart = pLeft;
pCurrent = pStart->next;
// Loop forever (well until we get to the right)
while (1){
if (pStart->time > pCurrent->time){
// Swap the items,swapping address could be critical, head pointer change will disrupt
// so swapping values
swp_time = pCurrent->time;
swp_vid = pCurrent->vid;
swp_x = pCurrent->x;
swp_y = pCurrent->y;
swp_speed = pCurrent->speed;
swp_visit = pCurrent->visit;
pCurrent->time = pStart->time;
pCurrent->vid = pStart->vid;
pCurrent->x = pStart->x;
pCurrent->y = pStart->y;
pCurrent->speed = pStart->speed;
pCurrent->visit = pStart->visit;
pStart->time = swp_time;
pStart->vid = swp_vid;
pStart->x = swp_x;
pStart->y = swp_y;
pStart->speed = swp_speed;
pStart->visit = swp_visit;
}
// Check if we have reached the end
if (pCurrent == pRight) break;
// Move to the next item in the list
pCurrent = pCurrent->next;
}
quicksortlist(pStart->next,pCurrent);
int
get_number_of_nodes (int node_type)
{
return table[node_type]->key_count;
}
void clear_llist(){
node_data *
get_next_data (hash_table_t * table, int vid, int flag)
{
node_container *block = hash_table_lookup (table, vid);
node_data *links = NULL, *save = NULL;
node_info* TempNode=NULL;
node_info* tmp=NULL;
TempNode=head_node_info;
if (block != NULL)
links = block->next;
while(TempNode->next!=NULL){
int *value1 = NULL;
value1 = (int *) HT_LOOKUP(table, TempNode->vid_addr);
Exnode* TempMob = (Exnode *)value1;
if (links == NULL)
LOG_E (OMG, "ERROR in reading-: NO data for node %d in this block \n",
vid);
while (TempMob->next!=NULL){
Exnode* tmp=NULL;
tmp=TempMob;
TempMob=TempMob->next;
free(tmp);
tmp=NULL;
}
if (TempMob->next == NULL){
free(TempMob);
TempMob=NULL;
}
tmp=TempNode;
TempNode=TempNode->next;
free(tmp);
tmp=NULL;
}
if (TempNode->next==NULL ){
free(TempNode);
TempNode=NULL;
}
hash_table_delete(table);
}
/*
int main(){
//char *mobility_file[50];
Exnode* next_loc=NULL;
//mobility_file = (char*) malloc(256);
//mobility_file=strtok("regular.tr");
omg_hash_table_t *table=read_mobility_file();
sort_veh_movement(table);
printf("Number of nodes --> %d \n",get_num_nodes());
next_loc=get_next_position(table,140392);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
//next_loc=NULL;
next_loc=get_next_position(table,140392);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
//next_loc=NULL;
next_loc=get_next_position(table,140392);
if (next_loc!=NULL){
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
//next_loc=NULL;
}next_loc=get_next_position(table,140392);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
next_loc=get_next_position(table,140392);
//if (next_loc!=NULL){
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
next_loc=get_next_position(table,140392);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
next_loc=get_next_position(table,140392);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
next_loc=get_next_position(table,140392);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
next_loc=get_next_position(table,140392);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
next_loc=get_next_position(table,140392);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
next_loc=get_next_position(table,140392);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
next_loc=get_next_position(table,140392);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
next_loc=get_next_position(table,140392);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
next_loc=get_next_position(table,140392);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
next_loc=get_next_position(table,140392);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
next_loc=get_next_position(table,140392);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
next_loc=get_next_position(table,140396);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
next_loc=get_next_position(table,140396);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
next_loc=get_next_position(table,140396);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
next_loc=get_next_position(table,140396);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
next_loc=get_next_position(table,140396);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
next_loc=get_next_position(table,140396);
printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
//reset_visit_status(table,20.0,11);
node_info* head_node=head_node_info;
while(head_node->next!=NULL){
if(head_node->vid==140392){
int *value1 = NULL;
value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
Exnode *value=(Exnode *)value1;
while(value->next!=NULL){
printf("checking reset %d\n",value->visit);
value=value->next;
while (links != NULL)
{
if (links->visit == 0)
break;
save = links;
links = links->next;
}
printf("checking reset %d\n",value->visit);
if (links != NULL)
{
if (flag == DATA_AND_STATUS_CHANGE)
{
if (block->next != block->end)
links->visit = 1;
return links;
}
head_node=head_node->next;
else if (flag == DATA_ONLY)
{
return save;
}
int *value1 = NULL;
value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
Exnode *value=(Exnode *)value1;
while(value->next!=NULL){
printf("checking reset %d %d\n",value->visit,value->vid);
value=value->next;
}
printf("checking reset %d %d\n",value->visit,value->vid);
return 0;
}*/
else
return links;
}
......@@ -41,62 +41,16 @@
#ifndef MOBILITY_PARSER_H_
#define MOBILITY_PARSER_H_
#include "omg_hashtable.h"
#include "trace_hashtable.h"
/**
* @struct Simple struct to hold only few information
* @brief The entry in each node is a line from the external mobility file
*/
typedef struct Exnode {
double time;
int vid;
double x;
double y;
double speed;
int visit;
struct Exnode* next;
}Exnode;
/**
* @struct struct acts as gateway to hashtable
* @brief holds vehicle id and initial pointer to the head of the linked list in hastable
*/
typedef struct node_info {
int vid;
int *vid_addr;
struct node_info* next;
//struct node_info* prev;
}node_info;
// head pointer to a linked list containing vid,vid_addr
/**
* function just to initialize the head of the linked list to NULL, this can be removed later(check).
*/
struct Exnode* gen_list();
/**
* Function to append the line content to build a linked list.
* @param headRef is the pointer to the head of the existing list to which append has to be done
* @param newNode , item to be appended
*/
void AppendNode(struct Exnode* headRef, struct Exnode* newNode);
/**
* function just prints the linked list (need to be removed, used for testing)
* @param pointer to the head of the linked list
*/
void print_list(struct Exnode* head);
/**
/*
* function reads each line and checks if vehicle has an entry in the hastable,
* if so append append is called else a new linked list to the vehicle is created.
* @param need mobility file to be given
*/
void read_mobility_file(); // mobility file need to be given here, add in omg_param_list, get it from there
void parse_data (char *trace_file, int node_type); // mobility file need to be given here, add in omg_param_list, get it from there
/**
* function builds a linked list which holds vehicle id and its mapping pointer to
......@@ -105,23 +59,16 @@ void read_mobility_file(); // mobility file need to be given here, add in omg_pa
* @param vid is the vehicle id
* @param pointer to the head of the linked list to the vehicle entry in the hash table
*/
node_info* build_node_info(node_info* headRef, int vid, int *vid_addr);
void add_node_info (int nid,int n_gid, int node_type);
int find_node_info (int vid, int node_type);
/**
* just counts the number of nodes in the mobility file
*/
int get_num_nodes();
int get_number_of_nodes (int node_type);
/**
* these function are used since there might be a possibility if user provides a mobility
* discription which is out of order.
* @param hashtable
* @param starting pointer for the vehicles linked list
* @param ending pointer of the vehicles linked list
*/
void sort_veh_movement(omg_hash_table_t *table);
void quicksortlist(Exnode *pLeft, Exnode *pRight);
/**
* function returns the node containing next position (just reads the linked list from the hashtable)
......@@ -129,10 +76,8 @@ void quicksortlist(Exnode *pLeft, Exnode *pRight);
* @param hashtable from which the node is to be looked
* @param node_id is the nodes whose next location need to be retrieved from the linked list
*/
Exnode* get_next_position(omg_hash_table_t *table,int node_id);
node_data* get_next_data (hash_table_t* table, int vid, int flag);
void reset_visit_status(omg_hash_table_t *table, float time, int node_id);
void clear_llist();
#endif /* MOBILITY_PARSER_H_ */
......@@ -29,8 +29,8 @@
/*! \file OMG.c
* \brief Main function containing the OMG interface
* \author M. Mahersi, N. Nikaein, J. Harri
* \date 2011
* \author S. Gashaw, N. Nikaein, J. Harri
* \date 2011 - 2014
* \version 0.1
* \company Eurecom
* \email:
......@@ -51,77 +51,103 @@
#include "rwp.h"
#include "rwalk.h"
#include "trace.h"
#include "grid.h"
#include "steadystaterwp.h"
#include "sumo.h"
#include "../OMV/structures.h"
//#define STANDALONE
int omv_write (int pfd, Node_list ue_node_list, Data_Flow_Unit omv_data);
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;
void init_omg_global_params(void){ //if we want to re initialize all
int i = 0;
Job_Vector_len=0;
Job_Vector = NULL;
for (i=0; i<MAX_NUM_MOB_TYPES; i++){
Node_Vector[i] = NULL;
Node_Vector_len[i] = 0;
//Initial_Node_Vector_len[i] = 0;
/*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_MOB_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;
}
}
// maybe remplace 'start_OMG(omg_global_param omg_param_list)
// of course, add 'stop_OMG(), which calls recursively
// stop_XX_generator();
//
void init_mobility_generator(omg_global_param omg_param_list) {
switch (omg_param_list.mobility_type) {
/*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);
start_static_generator (omg_param_list[node_t]);
break;
case RWP:
start_rwp_generator(omg_param_list);
LOG_D(OMG," --------DISPLAY JOB LIST-------- \n");
display_job_list(Job_Vector);
Job_Vector = quick_sort (Job_Vector);
LOG_D(OMG,"--------DISPLAY JOB LIST AFTER SORTING--------\n");
display_job_list(Job_Vector);
start_rwp_generator (omg_param_list[node_t]);
break;
case RWALK:
start_rwalk_generator(omg_param_list);
LOG_D(OMG," --------DISPLAY JOB LIST-------- \n");
display_job_list(Job_Vector);
Job_Vector = quick_sort (Job_Vector);
LOG_D(OMG,"--------DISPLAY JOB LIST AFTER SORTING--------\n");
display_job_list(Job_Vector);
start_rwalk_generator (omg_param_list[node_t]);
break;
case TRACE:
start_trace_generator(omg_param_list);
LOG_D(OMG," --------DISPLAY JOB LIST-------- \n");
display_job_list(Job_Vector);
Job_Vector = quick_sort (Job_Vector);
LOG_D(OMG,"--------DISPLAY JOB LIST AFTER SORTING--------\n");
display_job_list(Job_Vector);
LOG_D(OMG," --------OMG will load static mobility traces from user specified file-------- \n");
start_trace_generator (omg_param_list[node_t]);
break;
case SUMO:
start_sumo_generator(omg_param_list);
//LOG_D(OMG," --------OMG will interface with SUMO for mobility generation-------- \n");
start_sumo_generator (omg_param_list[node_t]);
break;
case STEADY_RWP:
start_steadystaterwp_generator (omg_param_list[node_t]);
break;
default:
LOG_N(OMG, "Unsupported generator %d \n", omg_param_list.mobility_type);
LOG_N (OMG, "Unsupported generator\n");
}
}
}
void stop_mobility_generator(int mobility_type) {
switch (mobility_type) {
/**************************************************************************************/
/*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;
......@@ -130,403 +156,630 @@ void stop_mobility_generator(int mobility_type) {
case RWALK:
break;
case TRACE:
clear_llist();
clear_list ();
break;
case STEADY_RWP:
break;
case SUMO:
stop_sumo_generator();
stop_sumo_generator ();
//LOG_D(OMG," --------OMG will interface with SUMO for mobility generation-------- \n");
break;
default:
LOG_N(OMG, "Unsupported generator %d \n", omg_param_list.mobility_type);
LOG_N (OMG, "Unsupported generator\n");
}
}
}
void update_nodes(double cur_time){
/*****************************************************************************/
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 (Node_Vector[i] != NULL){
//printf(" Mob model to update is: %d \n ", i);
LOG_I(OMG, " Mob model to update is: %d \n ", i);
update_node_vector(i, cur_time);
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){
void
update_node_vector (int mobility_type, double cur_time)
{
//set_time(cur_time);
switch (mobility_type) {
switch (mobility_type)
{
case RWP:
update_rwp_nodes(cur_time);
update_rwp_nodes (cur_time);
break;
case RWALK:
update_rwalk_nodes(cur_time);
update_rwalk_nodes (cur_time);
break;
case TRACE:
update_trace_nodes(cur_time);
update_trace_nodes (cur_time);
break;
case SUMO:
// printf("in SUMO case \n");
update_sumo_nodes(cur_time);
update_sumo_nodes (cur_time);
break;
case STEADY_RWP:
update_steadystaterwp_nodes (cur_time);
break;
default:
//printf("STATIC or Unsupported generator %d \n", omg_param_list.mobility_type);
LOG_N(OMG, "STATIC or Unsupported generator %d \n", omg_param_list.mobility_type);
LOG_N (OMG, "STATIC or Unsupported generator\n");
}
}
Node_list get_current_positions(int mobility_type, int node_type, double cur_time){
Node_list Vector = NULL;
if (Node_Vector[mobility_type] != NULL){
switch (mobility_type) {
/*********************************************************************************/
/*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:
Vector = (Node_list)Node_Vector[STATIC];
LOG_T(OMG,"static vector %p is \n",Vector);
break;
case RWP:
get_rwp_positions_updated(cur_time);
Vector = Node_Vector[RWP];
get_rwp_positions_updated (cur_time);
break;
case RWALK:
get_rwalk_positions_updated(cur_time);
Vector = Node_Vector[RWALK];
get_rwalk_positions_updated (cur_time);
break;
case TRACE:
get_trace_positions_updated(cur_time);
Vector = Node_Vector[TRACE];
get_trace_positions_updated (cur_time);
break;
case SUMO:
LOG_I(OMG,"getting positions from SUMO\n");
//printf("getting positions from SUMO\n");
Vector = get_sumo_positions_updated(cur_time);
// Vector = Node_Vector[SUMO];
LOG_I (OMG, "getting positions from SUMO\n");
get_sumo_positions_updated (cur_time);
break;
case STEADY_RWP:
get_steadystaterwp_positions_updated (cur_time);
break;
default:
Vector = NULL;
LOG_N(OMG, " Unsupported generator %c \n", omg_param_list.mobility_type);
}
if (node_type != ALL){
Vector = filter(Vector, node_type);
}
return Vector;
}
else {
LOG_T( OMG, " No node of mobility type %d is available \n", mobility_type);
return NULL;
LOG_E (OMG, " Unsupported generator \n");
}
}
/***************************************************************/
// get the position for a specific node
NodePtr get_node_position(int node_type, int nID){
int found = 0; //not found
int i=0;
while ((i<MAX_NUM_MOB_TYPES) && (found == 0)){
if (Node_Vector[i] != NULL){
Node_list tmp = Node_Vector[i];
while ((tmp != NULL) && (found == 0)){
if ((tmp->node->ID == nID) && (tmp->node->type == node_type)) {
LOG_T(OMG, "found a node vector %d node id %d with type %d\n",i, tmp->node->ID, tmp->node->type);
found = 1; //found
display_node_position(tmp->node->ID, tmp->node->generator, tmp->node->type ,tmp->node->mobile, tmp->node->X_pos, tmp->node->Y_pos );
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;
}
}
i++;
}
if (found == 0 ){
LOG_N(OMG, "Node does not exist\n");
}
return NULL;
}
/*NodePtr get_node_position(int mobility_type, int node_type, int nID){
if (Node_Vector[mobility_type] != NULL){
Node_list Vector = NULL;
int done =1;
switch (mobility_type) {
case RWP:
Vector = Node_Vector[RWP];
/*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:
Vector = Node_Vector[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:
Vector = Node_Vector[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;
case SUMO:
LOG_E (OMG, "not possible to change mobility type to sumo \n");
break;
case TRACE:
LOG_E (OMG, "not possible to change mobility type to trace \n");
break;
default:
Vector = NULL;
LOG_E(OMG, "Static or Unsupported generator %c \n", omg_param_list.mobility_type);
LOG_E (OMG, " Unsupported generator \n");
}
if (Vector == NULL){
LOG_D(OMG, "\n Vector == NULL");
}
while (Vector != NULL){
if (Vector->node->ID == nID && Vector->node->type == node_type){
done =0;
display_node_position(Vector->node->ID, Vector->node->generator, Vector->node->type ,Vector->node->mobile, Vector->node->X_pos, Vector->node->Y_pos );
// LOG_I(OMG, "Node number %d is in position: (%.2f, %.2f) with mobility_type: %d\n",Vector->node->ID,Vector->node->X_pos,Vector->node->Y_pos,Vector->node->mobile);
return Vector->node;
}
Vector = Vector->next;
}
if (done!= 0 ){LOG_N(OMG, "Node does not exist\n");}
return NULL;
}
else {
LOG_N( OMG, "No node of mobility type %d is available \n", mobility_type);
return NULL;
}
}*/
void set_new_mob_type(int nID, int node_type, int new_mob, double cur_time){
double first_Job_time;
int err = 999;
int i = STATIC;
int old_mob = err;
int found = 0; //not found
while ((i<MAX_NUM_MOB_TYPES) && (found == 0)){
if (Node_Vector[i] != NULL){
Node_list tmp = Node_Vector[i];
while ((tmp != NULL) && (found == 0)){
if ((tmp->node->ID == nID) && (tmp->node->type == node_type)) {
found = 1; //found
old_mob = i;
LOG_D( OMG,"old mob %d\n", old_mob ); //LOG_N
if (old_mob == new_mob){
LOG_D(OMG, "Nothing to change (%d == %d)\n",old_mob, new_mob);
return;
}
else {
LOG_D(OMG,"Node_Vector[%d] != NULL\n", old_mob);
//int done = 1;
//Node_list Vector = Node_Vector[old_mob];
//NodePtr nd = NULL;
NodePtr nd = tmp->node;
if (new_mob == STATIC) { //OKEY // remove from Job_Vector
LOG_D(OMG, "new_mob == STATIC\n");
nd->mobile = 0;
nd->mob->speed = 0.0;
nd->mob->X_from = nd->X_pos;
nd->mob->Y_from = nd->Y_pos;
nd->mob->X_to = nd->X_pos;
nd->mob->Y_to = nd->Y_pos;
//nd->X_pos = nd->mob->X_to;
//nd->Y_pos = nd->mob->Y_to;
LOG_D(OMG, "Before remove");
display_job_list( Job_Vector);
if (Job_Vector != NULL){
Job_Vector = remove_job(Job_Vector, nID, node_type); //nd->ID
//LOG_D(OMG, "After remove\n");
Job_Vector_len--;
LOG_D(OMG, "After remove\n");
display_job_list( Job_Vector);
}
else {
LOG_E(OMG, "ERROR, Job_Vector == NULL while there are mobile nodes");
}
}
Node_Vector[old_mob] = remove_node(Node_Vector[old_mob], nID, node_type);
Node_Vector_len[old_mob]--;
nd->ID = nID; //Node_Vector_len[new_mob];
LOG_D(OMG, "Node_Vector_len[new_mob] %d\n", Node_Vector_len[new_mob]);
LOG_D(OMG, "nd->ID %d\n", nd->ID);
nd->generator = new_mob; // ---> it is changed in Job_Vector if new_mob is RWP or RWALK
Node_Vector[new_mob] = add_entry(nd, Node_Vector[new_mob]);
Node_Vector_len[new_mob]++;
if (old_mob == STATIC){ // add to Job_Vector , start by sleeping
LOG_D(OMG, "old_mob == STATIC\n");
if(Job_Vector == NULL){
LOG_D(OMG, "Job_Vector == NULL\n");
first_Job_time = cur_time;
}
else {
LOG_D(OMG, "Job_Vector != NULL\n");
first_Job_time = Job_Vector->pair->a;
}
LOG_D(OMG, "------------------------------------------------------------- first_Job_time %f\n", first_Job_time);
Pair pair = malloc(sizeof(Pair)) ;
nd->mob->sleep_duration = (double) ((int) (randomGen(omg_param_list.min_sleep, omg_param_list.max_sleep)*100))/ 100;
LOG_D(OMG, "node: %d \tsleep duration : %.2f\n",nd->ID, nd->mob->sleep_duration);
pair->a = first_Job_time + 1 + nd->mob->sleep_duration; //when to wake up ????
LOG_D(OMG, "to wake up at time: cur_time + sleep_duration : %.2f\n", pair->a);
pair->b = nd;
Job_Vector = add_job(pair, Job_Vector);
Job_Vector_len++;
}
LOG_D(OMG," --------DISPLAY JOB LIST-------- \n");
display_job_list(Job_Vector);
Job_Vector = quick_sort (Job_Vector);
LOG_D(OMG,"--------DISPLAY JOB LIST AFTER SORTING--------\n");
display_job_list(Job_Vector);
LOG_D(OMG, "--------display Node_Vector[new_mob]--------\n");
display_node_list(Node_Vector[new_mob]);
LOG_D(OMG, "--------display Node_Vector[old_mob]--------\n");
display_node_list(Node_Vector[old_mob]);
return;
}
}
tmp = tmp->next;
}
}
i++;
}
}
/*// openair emu will set this valut as a function of frame number
void set_time(double time) {
m_time = time;
}
double get_time() {
return m_time;
}*/
}
#ifdef STANDALONE
void usage(void){
fprintf(stderr, "\n\t-X: assign maximum width of the simulation area (X_max)"\
"\n\t-x: assign minimum width of the simulation area (X_min)"\
"\n\t-Y: assign maximum height of the simulation area (Y_max)"\
"\n\t-y: assign minimum height of the simulation area (Y_min)"\
"\n\t-N: assign number of nodes"\
"\n\t-n: assign number of frames" \
"\n\t-B: assign maximum duration of sleep/pause time (max_break)"
"\n\t-b: assign minimum duration of sleep/pause time (min_break)"\
"\n\t-J: assign maximum duration of journey (max_journey_time)"\
"\n\t-j: assign minimum duration of journey (min_journey_time)"\
"\n\t-S: assign maximum speed "\
"\n\t-s: assign minimum speed"\
"\n\t-g: choose generator (STATIC: 0x00, RWP: 0x01, RWALK: 0x02, TRACE: 0x03 or SUMO: 0x04)\n"\
"\n\t-e: choose seed \n"\
);
exit(0);
/************************** 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);
}
float n_frames=200.0;
int get_options(int argc, char *argv[]){
int
get_options (int argc, char *argv[])
{
int node_t;
char tag;
while ((tag = getopt(argc, argv, "vj:J:g:B:b:S:s:Y:y:X:x:n:N:he:t:")) != EOF) {
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) {
switch (tag)
{
case 'N':
omg_param_list.nodes = atoi(optarg);
LOG_D(OMG, "Number of nodes : %d \n",omg_param_list.nodes);
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 'n':
n_frames = atof(optarg);
LOG_D(OMG, "Number of frames : %f \n",n_frames );
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 't':
omg_param_list.nodes_type = atoi(optarg);
LOG_D(OMG, "Type of nodes : %d \n",omg_param_list.nodes_type);
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 'b':
omg_param_list.min_sleep = atof(optarg);
LOG_D(OMG, "min sleep : %.2f \n",omg_param_list.min_sleep);
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 'B':
omg_param_list.max_sleep = atof(optarg);
LOG_D(OMG, "max_sleep : %.2f \n",omg_param_list.max_sleep);
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':
omg_param_list.min_speed = atof(optarg);
LOG_D(OMG, "min_speed : %.2f \n",omg_param_list.min_speed);
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':
omg_param_list.max_speed = atof(optarg);
LOG_D(OMG, "max_speed : %.2f \n",omg_param_list.max_speed);
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.max_X = atof(optarg);
LOG_D(OMG, "X_max : %.2f \n",omg_param_list.max_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.min_X = atof(optarg);
LOG_D(OMG, "X_min : %.2f \n",omg_param_list.min_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.max_Y = atof(optarg);
LOG_D(OMG, "Y_max : %.2f \n",omg_param_list.max_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.min_Y = atof(optarg);
LOG_D(OMG, "Y_min : %.2f \n",omg_param_list.min_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 'J':
omg_param_list.max_journey_time = atof(optarg);
LOG_D(OMG, "Journey_time_max : %.2f \n",omg_param_list.max_journey_time);
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':
omg_param_list.min_journey_time = atof(optarg);
LOG_D(OMG, "Journey_time_min : %.2f \n",omg_param_list.min_journey_time);
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 'g':
omg_param_list.mobility_type = atoi(optarg);
LOG_D(OMG, "Mobility type is %d \n",omg_param_list.mobility_type);
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 'e':
omg_param_list.seed = atoi(optarg);
LOG_D(OMG, "Seed is %d \n",omg_param_list.seed );
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();
usage ();
break;
default:
usage();
exit(1);
usage ();
exit (1);
}
}
return 0;
return 1;
}
int main(int argc, char *argv[]) {
int i;
double cur_time=0.0;
//srand(time(NULL));
double ms=0.0;
Node_list Current_positions = NULL;
NodePtr my_node = NULL;
int my_ID = 0;
/**************************** 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;
//omv
char full_name[200];
int pfd[2]; // fd for omv : fixme: this could be a local var
char fdstr[10];
......@@ -537,252 +790,195 @@ int main(int argc, char *argv[]) {
char x_area[20];
char y_area[20];
char z_area[20];
char fname[64],vname[64];
Data_Flow_Unit omv_data ;
//float n_frames=200.0;
omg_param_list.nodes = 200;
omg_param_list.min_X = 0;
omg_param_list.max_X = 1000;
omg_param_list.min_Y = 0;
omg_param_list.max_Y = 1000;
omg_param_list.min_speed = 0.1;
omg_param_list.max_speed = 20.0;
omg_param_list.min_journey_time = 0.1;
omg_param_list.max_journey_time = 10.0;
omg_param_list.min_azimuth = 0;
omg_param_list.max_azimuth = 360;
omg_param_list.min_sleep = 0.1;
omg_param_list.max_sleep = 5.0;
omg_param_list.mobility_file = "TRACE/example_trace.tr";
omg_param_list.sumo_command = "sumo-gui";
omg_param_list.sumo_config = "SUMO/SCENARIOS/traci.scen.sumo.cfg";
// omg_param_list.sumo_config = "SUMO/SCENARIOS/traci.koln.sumo.cfg";
omg_param_list.sumo_start = 0;//25900;
omg_param_list.sumo_end = 200;//26200;
omg_param_list.sumo_step = 1;
omg_param_list.sumo_host = "localhost";
omg_param_list.sumo_port = 8890;
omg_param_list.mobility_type = STATIC;
omg_param_list.nodes_type = UE;
// overwrite the default params if defined
get_options(argc, argv);
// check if we are out of range
if(omg_param_list.max_X == 0.0 || omg_param_list.max_Y == 0.0 ) {
usage();
exit(1);
}
//char sumo_line[300];
//printf("TEST %s \n", sumo_line);
// sprintf(sumo_line, "%s -c %s -b %d -e %d --remote-port %d --step-length %d -v ",omg_param_list.sumo_command, omg_param_list.sumo_config, omg_param_list.sumo_start, omg_param_list.sumo_end, omg_param_list.sumo_port, omg_param_list.sumo_step);
//printf("%s \n",sumo_line);
//pid_t pid;
//pid_t cpid;
// char *sumo_arg[] = { omg_param_list.sumo_command, sumo_line, NULL };
//char *sumo_arg[] = { "ls -la", NULL };
// char *sumo_env[] = { NULL };
//printf("%s \n",omg_param_list.sumo_command);
//execve("ls -la",sumo_arg, sumo_env);
//execve(omg_param_list.sumo_command, sumo_arg, sumo_env);
//exec(omg_param_list.sumo_command);
// if ( (pid = fork()) == 0)
// {
// Start SUMO in the child process
//execve(omg_param_list.sumo_command, sumo_arg, sumo_env);// starts SUMO in a child proces
// system("sumo-gui");
//childs addresss space
// }
//printf("%d \n",pid);
//pid++;
//pid++;
//printf("%d \n",pid);
//printf("%d \n",cpid);
//char kill_line[300];
//printf("TEST %s \n", sumo_line);
//sprintf(kill_line, "kill(%d)",cpid);
//printf("%s \n",kill_line);
//system(kill_line);
init_omg_global_params(); //initialization de Node_Vector et Job_Vector
init_mobility_generator(omg_param_list); // initial positions + sleep /// need to indicate time of initialization
//LOG_I(OMG, "*****DISPLAY NODE LIST********\n");
//display_node_list(Node_Vector[0]);
/*LOG_T(OMG, "********DISPLAY JOB LIST********\n");
display_job_list(Job_Vector);
Job_Vector = quick_sort (Job_Vector);
LOG_T(OMG, "**********DISPLAY JOB LIST AFTER SORTING**********\n");
display_job_list(Job_Vector);
*/
// omg_param_list.mobility_type = RWP;
// omg_param_list.nodes_type = UE;
// init_mobility_generator(omg_param_list); // initial positions + sleep /// need to indicate time of initialization
//omg_param_list.mobility_type = RWALK;
//omg_param_list.nodes_type = UE;
//init_mobility_generator(omg_param_list); // initial positions + sleep /// need to indicate time of initialization
//omg_param_list.mobility_type = STATIC;
//omg_param_list.nodes_type = UE;
//init_mobility_generator(omg_param_list); // initial positions + sleep /// need to indicate time of initialization
//LOG_I(OMG, "*****DISPLAY NODE LIST********\n");
//display_node_list(Node_Vector[0]);
/*LOG_T(OMG, "********DISPLAY JOB LIST********\n");
display_job_list(Job_Vector);
Job_Vector = quick_sort (Job_Vector);
LOG_T(OMG, "**********DISPLAY JOB LIST AFTER SORTING**********\n");
display_job_list(Job_Vector);*/
/*init_omg_global_params(); //re-initialization de Node_Vector et Job_Vector
LOG_I(OMG, "*****DISPLAY NODE LIST********\n");
display_node_list(Node_Vector[0]);
LOG_T(OMG, "********DISPLAY JOB LIST********\n");
display_job_list(Job_Vector);
Job_Vector = quick_sort (Job_Vector);
LOG_T(OMG, "**********DISPLAY JOB LIST AFTER SORTING**********\n");
display_job_list(Job_Vector);*/
/////////////// to call by OCG
// 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.nodes);
sprintf(x_area, "%f", omg_param_list.max_X );
sprintf(y_area, "%f", omg_param_list.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" );
char fname[64], vname[64];
Data_Flow_Unit omv_data;
//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;
}
//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){
//printf("updating node positions\n");
// update_nodes(emu_info_time*1000);
update_nodes(emu_info_time);
//double emu_info.time += 1.0/100; // emu time in ms
/* for (i=(STATIC+1); i<MAX_NUM_MOB_TYPES; i++){ //
if (Node_Vector[i] != NULL){
LOG_D(OMG, " mob model %d \n ", i);
update_nodes(i ,emu_info_time);
}
else {LOG_D( "nodes are STATIC\n"); }
}*/
printf(" **********asking for positions in %d **********\n ", omg_param_list.mobility_type);
Current_positions = get_current_positions(omg_param_list.mobility_type,
omg_param_list.nodes_type,
emu_info_time); // type: enb, ue, all
if(Current_positions !=NULL) {
printf(" **********Current_positions at time %f**********\n ",emu_info_time);
display_node_list(Current_positions);
printf(" **********DONE**********\n ");
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)
omv_write(pfd[1], Current_positions, omv_data);
{
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])); */
}
stop_mobility_generator(omg_param_list.mobility_type);
/*LOG_D(OMG, " **********DISPLAY JOB LIST**********\n ");
display_job_list(Job_Vector);
emu_info_time = 10.0;*/
//Current_positions = get_current_positions(SUMO, emu_info_time); // type: enb, ue, all
//LOG_D(OMG, " **********Current_positions**********\n ");
//display_node_list(Current_positions);
//if (Current_positions == NULL)
// {LOG_D(OMG, " Cur_pos == NULL\n");}
//my_node = (NodePtr) get_node_position( RWP, UE, my_ID);
//LOG_D(OMG, "********At %.2f, Node number %d is in position: (%.2f, %.2f) with mobility_type: %d\n",emu_info_time, my_ID,my_node->X_pos,my_node->Y_pos,my_node->mobile);
//display current postion of nodes
if (omv_enabled == 1)
omv_write (pfd[1], node_vector[SUMO], omv_data);
if (omv_enabled == 1 )
omv_end(pfd[1],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;
}
int omv_write (int pfd, Node_list ue_node_list, Data_Flow_Unit omv_data){
int i=0,j;
omv_data.end=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.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].Neighbors = 0;
for (i = 1; i < omg_param_list[SUMO].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.mobility_type;
omv_data.geo[i].mobility_type = omg_param_list[SUMO].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 );
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" );
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" );
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
......@@ -30,7 +30,7 @@
/*! \file OMG.h
* \brief Prototypes of OMG functions that may be called by OCG
* \author M. Mahersi, N. Nikaein, J. Harri
* \date 2011
* \date 2011 - 2014
* \version 0.1
* \company Eurecom
* \email:
......@@ -43,6 +43,7 @@
#include "omg_constants.h"
#include "defs.h"
#include "omg_vars.h"
#if STANDALONE
#define LOG_G(c, x...) printf(x)
#define LOG_A(c, x...) printf(x)
......@@ -57,6 +58,8 @@
#else
#include "UTIL/LOG/log.h"
#endif
/** @defgroup _omg OpenAir Mobility Generation (OMG)
......@@ -195,14 +198,14 @@ void init_omg_global_params(void);
* \brief Assign initial positions to all the nodes. To do so, call the start_generator..... function corresponding to each requested mobility generator
* \param omg_param_list a structure that contains the main parameters needed to establish the random positions distribution
*/
void init_mobility_generator(omg_global_param omg_param_list);
void init_mobility_generator(omg_global_param omg_param_list[]);
/**
* \fn void stop_mobility_generator(int mobility_type)
* \brief Call the destructor for the respective mobility type.
* \param int mobility_type to stop and call destructor
*/
void stop_mobility_generator(int mobility_type);
void stop_mobility_generator(omg_global_param* omg_param_list);
/**
* \fn void update_nodes(double cur_time)
......@@ -220,9 +223,9 @@ void update_nodes(double cur_time);
* \param cur_time a variable of type double that represents the current time
* \return a Node_list structure that stores the basic information about the all the nodes of a given mobility model
*/
Node_list get_current_positions(int mobility_type, int node_type, double cur_time);
node_list* get_current_positions(int mobility_type, int node_type, double cur_time);
void get_nodes_positions (int mobility_type, double cur_time);
/**
* \fn void set_new_mob_type(int nID, int node_type, int new_mob, double cur_time)
......
......@@ -45,14 +45,29 @@ RWP, /*!< Random Way Point mobility model */
RWALK, /*!< Random Walk mobility model */
TRACE, /*!< Trace-based Mobility description file */
SUMO, /*!< SUMO-based mobility model */
STEADY_RWP, /*!steady state RWP*/
MAX_NUM_MOB_TYPES /*!< The maximum number of mobility models. Used to adjust the length of the #Node_Vector */
}mobility_types;
/*
* this is a sub type of standard RWP (not steady_RWP)
*/
typedef enum {
MIN_RWP_TYPES=0, /*!< STATIC mobility model */
RESTIRICTED_RWP, /*!< Random Way Point mobility model */
CONNECTED_DOMAIN, /*!< Random Walk mobility model */
MAX_RWP_TYPES /*!< The maximum number of mobility models. Used to adjust the length of the #Node_Vector */
}omg_rwp_types;
//#define RESTIRICTED_RWP 1
//#define CONNECTED_DOMAIN 2
/*! The available nodes types */
typedef enum {
eNB=0, /*!< enhanced Node B */
UE, /*!< User Equipement */
ALL /*!< All the types. Used to perform the same operations to all the types of nodes */
RELAY,
MAX_NUM_NODE_TYPES /*!< All the types. Used to perform the same operations to all the types of nodes */
}node_types;
......@@ -60,6 +75,11 @@ ALL /*!< All the types. Used to perform the same operations to all the types of
/*! A constant used to compare two doubles */
#define eps 0.10 //10.99
#define SLEEP 1
#define GET_DATA 0
#define GET_DATA_UPDATE 1
#endif /* __OMG_H_ */
......@@ -39,21 +39,29 @@
#include "omg.h"
/*!A global variable used to store all the nodes information. It is an array in which every cell stocks the nodes information for a given mobility type. Its length is equal to the maximum number of mobility models that can exist in a single simulation scenario */
Node_list Node_Vector[MAX_NUM_MOB_TYPES];
node_list* node_vector[MAX_NUM_NODE_TYPES];
node_list* node_vector_end[MAX_NUM_NODE_TYPES];
/*! A global variable which represents the length of the Node_Vector */
int Node_Vector_len[MAX_NUM_MOB_TYPES];
int node_vector_len[MAX_NUM_NODE_TYPES];
/*!a global veriable used for event average computation*/
int event_sum[100];
int events[100];
/*!A global variable used to store the scheduled jobs, i.e (node, job_time) peers */
Job_list Job_Vector;
job_list* job_vector[MAX_NUM_MOB_TYPES];
job_list* job_vector_end[MAX_NUM_MOB_TYPES];
/*! A global variable which represents the length of the Job_Vector */
int Job_Vector_len;
int job_vector_len[MAX_NUM_MOB_TYPES];
/*! A global variable used gather the fondamental parameters needed to launch a simulation scenario*/
omg_global_param omg_param_list;
omg_global_param omg_param_list[MAX_NUM_NODE_TYPES];
//double m_time;
/*!A global variable used to store selected node position generation way*/
int grid;
double xloc_div;
double yloc_div;
#endif /* __OMG_VARS_H__ */
......@@ -29,8 +29,8 @@
/*! \file rwalk.c
* \brief random walk mobility generator
* \author M. Mahersi, J. Harri, N. Nikaein,
* \date 2011
* \author S. Gashaw, N. Nikaein, J. Harri, M. Mahersi
* \date 2014
* \version 0.1
* \company Eurecom
* \email:
......@@ -41,422 +41,478 @@
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include "rwalk.h"
#include "omg.h"
#include "steadystaterwp.h"
int start_rwalk_generator(omg_global_param omg_param_list) {
int
start_rwalk_generator (omg_global_param omg_param_list)
{
int n_id=0;
//omg_omg_param_list.seed= time(NULL);
srand(omg_param_list.seed + RWALK);
int id;
static int n_id = 0;
double cur_time = 0.0, pause_p, mean_pause, mean_travel;
node_struct *node = NULL;
mobility_struct *mobility = NULL;
pair_struct *pair = NULL;
double cur_time = 0.0;
NodePtr node = NULL;
MobilityPtr mobility = NULL;
srand (omg_param_list.seed + RWALK);
if (omg_param_list.nodes <= 0){
LOG_W(OMG, "Number of nodes has not been set\n");
return(-1);
}
mean_pause = (omg_param_list.max_sleep - omg_param_list.min_sleep) / 2;
mean_travel =
(omg_param_list.max_journey_time - omg_param_list.min_journey_time) / 2;
pause_p = mean_pause / (mean_travel + mean_pause);
if (omg_param_list.nodes_type == eNB) {
LOG_I(OMG, "Node type has been set to eNB\n");
} else if (omg_param_list.nodes_type == UE) {
LOG_I(OMG, "Node type has been set to UE\n");
}
LOG_I(OMG, "Number of random walk nodes has been set to %d\n", omg_param_list.nodes);
LOG_I (OMG, "#RWALK mobility model for %d %d nodes\n", omg_param_list.nodes,
omg_param_list.nodes_type);
for (id = n_id; id < (omg_param_list.nodes + n_id); id++)
{
for (n_id = 0; n_id< omg_param_list.nodes; n_id++) {
node = create_node ();
mobility = create_mobility ();
node = (NodePtr) create_node();
mobility = (MobilityPtr) create_mobility();
node->mobile = 0; // static for the moment
node->ID = n_id;
node->id = id;
node->type = omg_param_list.nodes_type;
node->generator = omg_param_list.mobility_type;
node->mob = mobility;
node->generator = RWALK;
node->event_num = 0;
place_rwalk_node (node); //initial positions
pair = (pair_struct *) malloc (sizeof (struct pair_struct));
pair->b = node;
// sleep_rwalk_node (pair, cur_time); //sleep
//pause probability...some of the nodes start at pause & the other on move
if (randomgen (0, 1) < pause_p)
sleep_steadystaterwp_node (pair, cur_time); //sleep
else
move_steadystaterwp_node (pair, cur_time);
place_rwalk_node(node); //initial positions
Pair pair = malloc (sizeof(Pair));
pair = (Pair) sleep_rwalk_node(node, cur_time); //sleep
job_vector_end[RWALK] = add_job (pair, job_vector_end[RWALK]);
Job_Vector = add_job(pair, Job_Vector);
Job_Vector_len ++;
if (job_vector[RWALK] == NULL)
job_vector[RWALK] = job_vector_end[RWALK];
if (Job_Vector == NULL)
LOG_E(OMG, "Job Vector is NULL\n");
job_vector_len[RWALK]++;
}
return(0);
}
n_id += omg_param_list.nodes;
void place_rwalk_node(NodePtr node) {
node->X_pos = (double) ((int) (randomGen(omg_param_list.min_X, omg_param_list.max_X)*100))/ 100;
node->mob->X_from = node->X_pos;
node->mob->X_to = node->X_pos;
node->Y_pos = (double) ((int) (randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100;
node->mob->Y_from = node->Y_pos;
node->mob->Y_to = node->Y_pos;
if (job_vector[RWALK] == NULL)
LOG_E (OMG, "[RWP] Job Vector is NULL\n");
return (0);
}
void
place_rwalk_node (node_struct * node)
{
node->x_pos =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_x,
omg_param_list[node->type].max_x) * 100)) / 100;
node->mob->x_from = node->x_pos;
node->mob->x_to = node->x_pos;
node->y_pos =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_y,
omg_param_list[node->type].max_y) * 100)) / 100;
node->mob->y_from = node->y_pos;
node->mob->y_to = node->y_pos;
node->mob->speed = 0.0;
node->mob->journey_time = 0.0;
LOG_D(OMG, " INITIALIZE RWALK NODE\n ");
LOG_I(OMG, "Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = 0.0\n", node->ID, node->type, node->X_pos, node->Y_pos);
Node_Vector[RWALK] = (Node_list) add_entry(node, Node_Vector[RWALK]);
Node_Vector_len[RWALK]++;
//Initial_Node_Vector_len[RWALK]++;
// LOG_D (OMG, " INITIALIZE RWALK NODE\n ");
LOG_I (OMG,
"#Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = 0.0\n",
node->id, node->type, node->x_pos, node->y_pos);
node_vector_end[node->type] =
(node_list *) add_entry (node, node_vector_end[node->type]);
if (node_vector[node->type] == NULL)
node_vector[node->type] = node_vector_end[node->type];
node_vector_len[node->type]++;
}
Pair sleep_rwalk_node(NodePtr node, double cur_time){
void
sleep_rwalk_node (pair_struct * pair, double cur_time)
{
node_struct *node;
node = pair->b;
node->mobile = 0;
node->mob->speed = 0.0;
node->mob->X_from = node->mob->X_to;
node->mob->Y_from = node->mob->Y_to;
node->X_pos = node->mob->X_to;
node->Y_pos = node->mob->Y_to;
Pair pair = malloc(sizeof(Pair)) ;
node->mob->sleep_duration = (double) ((int) (randomGen(omg_param_list.min_sleep, omg_param_list.max_sleep)*100))/ 100;
LOG_D(OMG, "node: %d \tsleep duration : %.2f\n",node->ID, node->mob->sleep_duration);
node->mob->x_from = node->mob->x_to;
node->mob->y_from = node->mob->y_to;
node->x_pos = node->mob->x_to;
node->y_pos = node->mob->y_to;
if (node->event_num == 0)
node->event_num++;
node->mob->sleep_duration =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_sleep,
omg_param_list[node->type].max_sleep) * 100)) / 100;
// LOG_D (OMG, "node: %d \tsleep duration : %.2f\n", node->ID,
// node->mob->sleep_duration);
node->mob->start_journey = cur_time;
pair->a = node->mob->start_journey + node->mob->sleep_duration; //when to wake up
LOG_D(OMG, "to wake up at time: cur_time + sleep_duration : %.2f\n", pair->a);
pair->b = node;
pair->next_event_t = cur_time + node->mob->sleep_duration; //when to wake up
// LOG_D (OMG, "to wake up at time: cur_time + sleep_duration : %.2f\n",
// pair->a);
return pair;
}
Pair move_rwalk_node(NodePtr node, double cur_time) {
Pair pair = malloc(sizeof(Pair));
LOG_D(OMG, "MOVE RWALK NODE ID: %d\n",node->ID);
node->X_pos = node->mob->X_to;
node->Y_pos = node->mob->Y_to;
node->mob->X_from = node->X_pos;
node->mob->Y_from = node->Y_pos;
void
move_rwalk_node (pair_struct * pair, double cur_time)
{
double distance, x_next, y_next, journeytime_next;
int i = 0;
double dx, dy, x_now, y_now;
double alpha, distancex, distancey;
node_struct *node;
node = pair->b;
//LOG_D (OMG, "MOVE RWALK NODE ID: %d\n", node->ID);
node->mob->x_from = node->mob->x_to;
node->mob->y_from = node->mob->y_to;
node->x_pos = node->mob->x_to;
node->y_pos = node->mob->y_to;
node->mobile = 1;
double speed_next = randomGen(omg_param_list.min_speed, omg_param_list.max_speed);
node->mob->speed = speed_next;
LOG_D(OMG, "speed_next: %f\n", speed_next); //m/s
double azimuth_next = randomGen(omg_param_list.min_azimuth, omg_param_list.max_azimuth);
node->mob->azimuth = azimuth_next;
LOG_D(OMG, "azimuth_next: %f\n", node->mob->azimuth);
node->mob->speed =
randomgen (omg_param_list[node->type].min_speed,
omg_param_list[node->type].max_speed);
double journeyTime_next = randomGen(omg_param_list.min_journey_time, omg_param_list.max_journey_time);
node->mob->journey_time = journeyTime_next;
LOG_D(OMG, "journey_time_next: %f\n", node->mob->journey_time);
node->mob->azimuth =
randomgen (omg_param_list[node->type].min_azimuth,
omg_param_list[node->type].max_azimuth);
if (node->event_num == 0)
{
node->mob->journey_time = residualtime (omg_param_list[node->type]);
node->event_num++;
}
else
{
node->mob->journey_time =
randomgen (omg_param_list[node->type].min_journey_time,
omg_param_list[node->type].max_journey_time);
}
distance = node->mob->speed * node->mob->journey_time;
double distance = node->mob->speed * node->mob->journey_time;
LOG_D(OMG, "distance = speed * journey_time: %f\n", distance);
dx = distance * cos (node->mob->azimuth * M_PI / 180);
double dX = distance * cos(node->mob->azimuth*M_PI/180);
LOG_D(OMG, "dX = distance * cos(azimuth): %f\n", dX);
double dY = distance * sin(node->mob->azimuth*M_PI/180);
LOG_D(OMG, "dY = distance * sin(azimuth): %f\n", dY);
dy = distance * sin (node->mob->azimuth * M_PI / 180);
LOG_D(OMG, "from: (%.2f, %.2f)\n", node->X_pos, node->Y_pos);
double X_next = (double) ((int)((node->X_pos + dX) *100))/ 100;
double Y_next = (double) ((int)((node->X_pos + dY) *100))/ 100;
LOG_D(OMG, "theoritical_destination: (%f, %f)\n", X_next, Y_next);
x_next = (double) ((int) ((node->mob->x_from + dx) * 100)) / 100;
y_next = (double) ((int) ((node->mob->y_from + dy) * 100)) / 100;
/* LOG_D(OMG,"#node %d X FROM %.2f x next %.2f Y FROM %.2f y next %.2f \n\n",node->id,node->mob->x_from,x_next, node->mob->y_from,y_next); */
/*if (X_next<param_list.min_X){ // first method
node->mob->X_to = param_list.min_X;
}
else if (X_next>param_list.max_X){
node->mob->X_to = param_list.max_X;
}
else {
node->mob->X_to = X_next;
}
alpha = (node->mob->azimuth * M_PI / 180); //in radian
x_now = node->mob->x_from;
y_now = node->mob->y_from;
while (true)
{
if (x_next < omg_param_list[node->type].min_x)
{
distancex =
(omg_param_list[node->type].min_x - x_now) / cos (alpha);
if (Y_next<param_list.min_Y){
node->mob->Y_to = param_list.min_Y;
}
else if (Y_next>param_list.max_Y){
node->mob->Y_to = param_list.max_Y;
}
else {
node->mob->Y_to = Y_next;
}*/
if (X_next < omg_param_list.min_X){
while (X_next < omg_param_list.min_X){
X_next = X_next + omg_param_list.max_X;
}
node->mob->X_to = X_next;
}
else if (X_next > omg_param_list.max_X){
while (X_next > omg_param_list.max_X){
X_next = X_next - omg_param_list.max_X;
}
node->mob->X_to = X_next;
}
else {
node->mob->X_to = X_next;
}
else if (x_next > omg_param_list[node->type].max_x)
{
distancex =
(omg_param_list[node->type].max_x - x_now) / cos (alpha);
if (Y_next < omg_param_list.min_Y){
while (Y_next < omg_param_list.min_Y){
Y_next = Y_next + omg_param_list.max_Y;
}
node->mob->Y_to = Y_next;
else
{
distancex = distance;
}
else if (Y_next > omg_param_list.max_Y){
while (Y_next > omg_param_list.max_Y){
Y_next = Y_next - omg_param_list.max_Y;
if (y_next < omg_param_list[node->type].min_y)
{
distancey =
(omg_param_list[node->type].min_y - y_now) / sin (alpha);
}
node->mob->Y_to = Y_next;
else if (y_next > omg_param_list[node->type].max_y)
{
distancey =
(omg_param_list[node->type].max_y - y_now) / sin (alpha);
}
else {
node->mob->Y_to = Y_next;
else
{
distancey = distance;
}
LOG_I(OMG, "destination: (%.2f, %.2f)\n", node->mob->X_to, node->mob->Y_to);
node->mob->start_journey = cur_time;
LOG_D(OMG, "start_journey %.2f\n", node->mob->start_journey );
if ((distancex == distance && distancey == distance))
break;
pair->a = (double) ((int) ( (node->mob->start_journey + journeyTime_next) *100))/ 100 ;
LOG_D(OMG, "pair->a= start journey + journeyTime_next next %.2f\n", pair->a);
pair->b = node;
return pair;
}
if (distancey < distancex)
{
x_now = distancey * cos (alpha) + x_now;
y_now = distancey * sin (alpha) + y_now;
distance = distance - distancey;
dx = distance * cos (2 * M_PI - alpha);
dy = distance * sin (2 * M_PI - alpha);
x_next = x_now + dx;
y_next = y_now + dy;
alpha = 2 * M_PI - alpha;
void update_rwalk_nodes(double cur_time) {// need to implement an out-of-area check as well as a rebound function to stay in the area
LOG_D(OMG, "--------UPDATE--------\n");
Job_list tmp = Job_Vector;
int done = 0; //
while ((tmp != NULL) && (done == 0)){
//if (tmp->pair == NULL){LOG_E(OMG, "UPDATE RWALK : tmp->pair ==NULL\n" );}
//if (tmp->pair != NULL){LOG_E(OMG, "UPDATE RWALK : tmp->pair !=NULL\n" );}
LOG_D(OMG, "cur_time %f\n", cur_time );
LOG_D(OMG, "tmp->pair->a %f\n", tmp->pair->a );
}
else if (distancex < distancey)
{
if((tmp->pair !=NULL) && ( (double)tmp->pair->a >= cur_time - eps) && ( (double)tmp->pair->a <= cur_time + eps) ) {
if (tmp->pair->b->generator == RWALK){
LOG_D(OMG, " (first_job_time) %.2f == %.2f (cur_time) \n ",tmp->pair->a, cur_time );
LOG_D(OMG, " UPDATE RWALK \n ");
NodePtr my_node = (NodePtr)tmp->pair->b;
/*if(my_node->mobile == 1) {
LOG_D(OMG, " stop node and let it sleep \n" );
my_node->mobile = 0;
Pair pair = malloc(sizeof(Pair));
pair = sleep_rwalk_node(my_node, cur_time);
tmp->pair = pair;
tmp = tmp->next;
}*/
if ((my_node->mobile ==0) || (my_node->mobile == 1)) {
LOG_D(OMG, " node %d...let's move again \n", my_node->ID);
my_node->mobile = 1;
Pair pair = malloc(sizeof(Pair));
pair = move_rwalk_node(my_node, cur_time);
tmp->pair = pair;
tmp = tmp->next;
x_now = distancex * cos (alpha) + x_now;
y_now = distancex * sin (alpha) + y_now;
distance = distance - distancex;
dx = distance * cos (M_PI - alpha);
dy = distance * sin (M_PI - alpha);
x_next = x_now + dx;
y_next = y_now + dy;
alpha = M_PI - alpha;
}
else{
LOG_E(OMG, "update_generator: unsupported node state - mobile : %d \n", my_node->mobile);
//exit(-1);
i++;
}
node->mob->x_to = x_next;
node->mob->y_to = y_next;
/*LOG_D(OMG,"#node %d x to %.2f y to %.2f \n\n",node->id,node->mob->x_to,node->mob->y_to);
node->mob->start_journey = cur_time; */
journeytime_next =
(double) ((int) (distance / node->mob->speed * 100)) / 100;
pair->next_event_t =
(double) ((int) ((node->mob->start_journey + journeytime_next) * 100)) /
100;
if (node->event_num < 100)
{
event_sum[node->event_num] += node->mob->speed;
events[node->event_num]++;
node->event_num++;
}
else {
LOG_D(OMG, " (first_job_time) %.2f == %.2f(cur_time) but (generator=%d) != (RWALK=%d)\n ",tmp->pair->a, cur_time, tmp->pair->b->generator, RWALK );
tmp = tmp->next;
}
double
residualtime (omg_global_param omg_param)
{
double u;
u = randomgen (0, 1);
if (u <
(2 * omg_param.min_sleep /
(omg_param.max_journey_time + omg_param.min_journey_time)))
return u * (omg_param.max_journey_time + omg_param.min_journey_time) / 2;
else
return omg_param.max_journey_time -
sqrtf ((1 - u) * (pow (omg_param.max_journey_time, 2) -
pow (omg_param.min_sleep, 2)));
}
void
update_rwalk_nodes (double cur_time)
{
int done = 0;
job_list *tmp = job_vector[RWALK];
node_struct *my_node;
while (tmp != NULL && done == 0)
{
my_node = (node_struct *) tmp->pair->b;
//case1:time to next event equals to current time
if (tmp->pair != NULL
&& ((double) tmp->pair->next_event_t >= cur_time - eps)
&& ((double) tmp->pair->next_event_t <= cur_time + eps))
{
if (my_node->mobile == 1)
sleep_rwalk_node (tmp->pair, cur_time);
else
move_rwalk_node (tmp->pair, cur_time);
}
//case2: current time is greater than the time to next event
else if (tmp->pair != NULL
&& (cur_time - eps) > tmp->pair->next_event_t)
{
while (cur_time >= tmp->pair->next_event_t)
{
if (my_node->mobile == 1)
sleep_rwalk_node (tmp->pair, cur_time);
else
move_rwalk_node (tmp->pair, cur_time);
}
else if ( (tmp->pair != NULL) && (cur_time < tmp->pair->a ) ){ //&& (tmp->pair->b->generator == RWALK)
LOG_D(OMG, " %.2f < %.2f \n",cur_time, tmp->pair->a);
LOG_D(OMG, "Nothing to do\n");
done = 1; //quit the loop
}
else {
LOG_E(OMG, "\n %.2f > %.2f", cur_time,tmp->pair->a ); //LOG_D(OMG, " (generator=%d) != (RWALK=%d) \n", tmp->pair->b->generator, RWALK );
//case3: current time less than the time to next event
else
{
done = 1; //quit the loop
exit(-1);
}
tmp = tmp->next;
}
//sorting the new entries
LOG_D(OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
display_job_list(Job_Vector);
Job_Vector = quick_sort (Job_Vector);///////////
LOG_D(OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
display_job_list(Job_Vector);
// LOG_D (OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
//display_job_list (Job_Vector);
job_vector[RWALK] = quick_sort (job_vector[RWALK]); ///////////
// LOG_D (OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
//display_job_list (job_vector[RWALK]);
}
void get_rwalk_positions_updated(double cur_time){
void
get_rwalk_positions_updated (double cur_time)
{
double X_now=0.0;
double Y_now=0.0;
LOG_D(OMG,"--------GET RWALK POSITIONS--------\n");
Pair my_pair = Job_Vector->pair;
if ( my_pair ==NULL) {
LOG_E(OMG, "my_pair ==NULL");
}
else if ( (my_pair !=NULL) && (cur_time <= my_pair->a ) ){
LOG_D(OMG," %.2f <= %.2f \n",cur_time, my_pair->a);
Job_list tmp = Job_Vector;
while (tmp != NULL){
if (tmp->pair->b->generator == RWALK){
if (tmp->pair->b->mobile == 0){ //node is sleeping
LOG_T(OMG,"node number %d is sleeping at location: (%.2f, %.2f)\n", tmp->pair->b->ID, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
LOG_T(OMG,"Nothing to do, node is sleeping\n");
}
else if (tmp->pair->b->mobile == 1){ //node is moving
LOG_T(OMG,"Node_number %d\n", tmp->pair->b->ID);
LOG_T(OMG, "destination not yet reached\tfrom (%.2f, %.2f)\tto (%.2f, %.2f)\tspeed %.2f\t(X_pos %.2f\tY_pos %.2f)\n", tmp->pair->b->mob->X_from, tmp->pair->b->mob->Y_from,tmp->pair->b->mob->X_to, tmp->pair->b->mob->Y_to,tmp->pair->b->mob->speed, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
double x_now = 0.0, y_now = 0.0;
double len, dx, dy;
double distancex, distancey, alpha;
double x_next, y_next;
job_list *tmp = job_vector[RWALK];
double len = sqrtf(pow(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to,2)+pow(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to,2));
double dx = fabs(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to) / len;
while (tmp != NULL)
{
double dy = fabs(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to) / len;
LOG_D(OMG,"len %f\tdx %f\tdy %f\n", len, dx, dy);
if (tmp->pair->b->mob->X_from < tmp->pair->b->mob->X_to ){
X_now = tmp->pair->b->mob->X_from + (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey) ) );
}
else{
X_now = tmp->pair->b->mob->X_from - (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
}
if (tmp->pair->b->mobile == 1 && tmp->pair->next_event_t >= cur_time)
{
if (tmp->pair->b->mob->Y_from < tmp->pair->b->mob->Y_to ){
Y_now = tmp->pair->b->mob->Y_from + (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
}
else{
Y_now = tmp->pair->b->mob->Y_from - (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
}
len =
tmp->pair->b->mob->speed * (cur_time -
tmp->pair->b->mob->start_journey);
dx = len * cos (tmp->pair->b->mob->azimuth * M_PI / 180);
dy = len * sin (tmp->pair->b->mob->azimuth * M_PI / 180);
LOG_D(OMG,"X_now %f\tY_now %f\n", X_now, Y_now);
x_next =
(double) ((int) ((tmp->pair->b->mob->x_from + dx) * 100)) / 100;
y_next =
(double) ((int) ((tmp->pair->b->mob->y_from + dy) * 100)) / 100;
if (X_now < omg_param_list.min_X){
while (X_now < omg_param_list.min_X){
X_now = X_now + omg_param_list.max_X;
}
}
else if (X_now > omg_param_list.max_X){
while (X_now > omg_param_list.max_X){
X_now = X_now - omg_param_list.max_X;
alpha = (tmp->pair->b->mob->azimuth * M_PI / 180); //in radian
x_now = tmp->pair->b->mob->x_from;
y_now = tmp->pair->b->mob->y_from;
while (true)
{
if (x_next < omg_param_list[tmp->pair->b->type].min_x)
{
distancex =
(omg_param_list[tmp->pair->b->type].min_x -
x_now) / cos (alpha);
}
else if (x_next > omg_param_list[tmp->pair->b->type].max_x)
{
distancex =
(omg_param_list[tmp->pair->b->type].max_x -
x_now) / cos (alpha);
}
else {
X_now = X_now;
else
{
distancex = len;
}
if (Y_now < omg_param_list.min_Y){
while (Y_now < omg_param_list.min_Y){
Y_now = Y_now + omg_param_list.max_Y;
if (y_next < omg_param_list[tmp->pair->b->type].min_y)
{
distancey =
(omg_param_list[tmp->pair->b->type].min_y -
y_now) / sin (alpha);
}
else if (y_next > omg_param_list[tmp->pair->b->type].max_y)
{
distancey =
(omg_param_list[tmp->pair->b->type].max_y -
y_now) / sin (alpha);
}
else if (Y_now > omg_param_list.max_Y){
while (Y_now > omg_param_list.max_Y){
Y_now = Y_now - omg_param_list.max_Y;
else
{
distancey = len;
}
}
else {
Y_now = Y_now;
}
LOG_D(OMG,"X_now %f\tY_now %f\n", X_now, Y_now);
if (distancex == len && distancey == len)
break;
tmp->pair->b->X_pos = (double) ((int) (X_now*100))/ 100;
tmp->pair->b->Y_pos = (double) ((int) (Y_now*100))/ 100;
//tmp->pair->b->mob->X_from = tmp->pair->b->X_pos;
//tmp->pair->b->mob->Y_from = tmp->pair->b->Y_pos;
//tmp->pair->b->mob->start_journey = cur_time;
LOG_D(OMG,"updated_position of node number %d is :(%.2f, %.2f)\n", tmp->pair->b->ID, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
}
else{
LOG_E(OMG,"update_generator: unsupported node state : %d \n", tmp->pair->b->mobile);
return;
}
}
tmp = tmp->next;
}
}
else {
LOG_E(OMG,"ERROR current time %f > first job_time %f\n", cur_time, my_pair->a);
}
}
if (distancey < distancex)
{
x_now = distancey * cos (alpha) + x_now;
y_now = distancey * sin (alpha) + y_now;
len = len - distancey;
dx = len * cos (2 * M_PI - alpha);
dy = len * sin (2 * M_PI - alpha);
x_next = x_now + dx;
y_next = y_now + dy;
alpha = 2 * M_PI - alpha;
/*void update_rwalk_nodes(double cur_time) {// need to implement an out-of-area check as well as a rebound function to stay in the area
LOG_D(OMG,"--------UPDATE--------\n");
int l = 0;
Job_list tmp = Job_Vector;
while (l < Job_Vector_len){
LOG_D(OMG,"l == %d \n", l);
Pair my_pair = tmp->pair;
LOG_D(OMG,"%.2f\n ",my_pair->a);
if((my_pair !=NULL) && ( (double)my_pair->a >= cur_time - eps) && ( (double)my_pair->a <= cur_time + eps)) {
LOG_D(OMG,"%.2f == %.2f \n ",my_pair->a, cur_time );
if (my_pair->b->generator == RWALK) {
LOG_D(OMG," UPDATE RWALK \n ");
NodePtr my_node= (NodePtr)my_pair->b;
//if(my_node->mobile == 1) {
// LOG_D(OMG," move again \n" );
// // stop node and let it sleep
// my_node->mobile = 0;
// Pair pair = malloc(sizeof(Pair));
// pair = sleep_rwalk_node(my_node, cur_time);
// Job_Vector->pair = pair;
//}
if ((my_node->mobile ==0) ||( my_node->mobile == 1)) {
LOG_D(OMG," ...let's move again \n" );
// ...let's move again
my_node->mobile = 1;
Pair pair = malloc(sizeof(Pair));
pair = move_rwalk_node(my_node, cur_time);
Job_Vector->pair = pair;
}
else{
LOG_E(OMG, "update_generator: unsupported node state - mobile : %d \n", my_node->mobile);
}
//sorting the new entries
LOG_D(OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
display_job_list(Job_Vector);
Job_Vector = quick_sort (Job_Vector); //////////
LOG_D(OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
display_job_list(Job_Vector);
tmp = tmp->next;
l++;
}
else {
LOG_D(OMG, " (first_job_time) %.2f == %.2f(cur_time) but (generator %d) != (RWALK %d)\n ",my_pair->a, cur_time, my_pair->b->generator, RWALK );
tmp = tmp->next;
l++;
}
}
else if ( (my_pair !=NULL) && (cur_time < my_pair->a ) && (my_pair->b->generator == RWALK) ){
LOG_D(OMG," %.2f < %.2f\n ",cur_time, my_pair->a);
l = Job_Vector_len;
LOG_D(OMG,"Nothing to do\n");
}
else {
l = Job_Vector_len;
//LOG_D(OMG,"(generator=%d) != (RWALK=%d)\n", my_pair->b->generator, RWALK );
LOG_E(OMG, " %.2f > %.2f \n", cur_time,my_pair->a);
else if (distancex < distancey)
{
x_now = distancex * cos (alpha) + x_now;
y_now = distancex * sin (alpha) + y_now;
len = len - distancex;
dx = len * cos (M_PI - alpha);
dy = len * sin (M_PI - alpha);
x_next = x_now + dx;
y_next = y_now + dy;
alpha = M_PI - alpha;
}
}
}*/
}
tmp->pair->b->x_pos = (double) ((int) (x_next * 100)) / 100;
tmp->pair->b->y_pos = (double) ((int) (y_next * 100)) / 100;
}
else
{
tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
tmp->pair->b->y_pos = tmp->pair->b->mob->y_to;
}
//if(tmp->pair->b->id==2 && ((int)(cur_time*1000)% 100)==0)
//LOG_D (OMG, "%d %.2f %.2f \n\n",tmp->pair->b->id,tmp->pair->b->x_pos,tmp->pair->b->y_pos);
tmp = tmp->next;
}
}
......@@ -49,7 +49,7 @@ int start_rwalk_generator(omg_global_param omg_param_list) ;
* \brief Called by the function start_rwalk_generator(), it generates a random position ((X,Y) coordinates) for a node and add it to the corresponding Node_Vector_Rwp
* \param node a pointer of type NodePtr that represents the node to which the random position is assigned
*/
void place_rwalk_node(NodePtr node) ;
void place_rwalk_node(node_struct* node) ;
/**
* \fn Pair sleep_rwalk_node(NodePtr node, double cur_time)
......@@ -58,7 +58,7 @@ void place_rwalk_node(NodePtr node) ;
* \param cur_time a variable of type double that represents the current time
* \return A Pair structure containing the node and the time when it is reaching the destination
*/
Pair sleep_rwalk_node(NodePtr node, double cur_time) ;
void sleep_rwalk_node(pair_struct* pair, double cur_time) ;
/**
......@@ -68,7 +68,7 @@ Pair sleep_rwalk_node(NodePtr node, double cur_time) ;
* \param cur_time a variable of type double that represents the current time
* \return A Pair structure containing the node structure and the arrival time at the destination
*/
Pair move_rwalk_node(NodePtr node, double cur_time) ;
void move_rwalk_node(pair_struct* pair, double cur_time) ;
/**
* \fn void update_rwalk_nodes(double cur_time)
......@@ -87,4 +87,7 @@ void update_rwalk_nodes(double cur_time) ; // need to implement an out-of-area c
*/
void get_rwalk_positions_updated(double cur_time) ;
/*for perfect simulation of random walk*/
double residualtime(omg_global_param omg_param);
#endif /* RWALK_H_ */
......@@ -29,7 +29,7 @@
/*! \file rwp.c
* \brief random waypoint mobility generator
* \author M. Mahersi, J. Harri, N. Nikaein,
* \author M. Mahersi, N. Nikaein, J. Harri
* \date 2011
* \version 0.1
* \company Eurecom
......@@ -43,329 +43,405 @@
#include <time.h>
#include <math.h>
#include "rwp.h"
#include "omg.h"
int start_rwp_generator(omg_global_param omg_param_list) {
int n_id=0;
//omg_omg_param_list.seed= time(NULL);
srand(omg_param_list.seed + RWP);
int
start_rwp_generator (omg_global_param omg_param_list)
{
static int n_id = 0;
int id;
double cur_time = 0.0;
NodePtr node = NULL;
MobilityPtr mobility = NULL;
node_struct *node = NULL;
mobility_struct *mobility = NULL;
pair_struct *pair = NULL;
if (omg_param_list.nodes <= 0){
LOG_W(OMG,"[RWP] Number of nodes has not been set\n");
return(-1);
}
srand (omg_param_list.seed + RWP);
if (omg_param_list.nodes_type == eNB) {
LOG_I(OMG,"[RWP] Node type has been set to eNB\n");
} else if (omg_param_list.nodes_type == UE) {
LOG_I(OMG, "[RWP] Node type has been set to UE\n");
}
LOG_I(OMG, "[RWP] Number of random waypoint nodes has been set to %d\n", omg_param_list.nodes);
LOG_I (OMG, "# RWP mobility model for %d type %d nodes\n", omg_param_list.nodes,
omg_param_list.nodes_type);
for (id = n_id; id < (omg_param_list.nodes + n_id); id++)
{
for (n_id = 0; n_id< omg_param_list.nodes; n_id++) {
node = create_node ();
mobility = create_mobility ();
node = (NodePtr) create_node();
mobility = (MobilityPtr) create_mobility();
node->mobile = 0; // static for the moment
node->ID = n_id;
node->type = omg_param_list.nodes_type; // UE eNB
node->generator = omg_param_list.mobility_type; // STATIC, RWP...
node->id = id;
node->type = omg_param_list.nodes_type;
node->mob = mobility;
node->generator = RWP;
node->event_num = 0;
place_rwp_node (node); //initial positions
place_rwp_node(node); //initial positions
Pair pair = malloc (sizeof(Pair));
pair = sleep_rwp_node(node, cur_time); //sleep
pair = (pair_struct *) malloc (sizeof (struct pair_struct));
pair->b = node;
sleep_rwp_node (pair, cur_time); //sleep
Job_Vector = add_job(pair, Job_Vector);
Job_Vector_len ++;
job_vector_end[RWP] = add_job (pair, job_vector_end[RWP]);
if (job_vector[RWP] == NULL)
job_vector[RWP] = job_vector_end[RWP];
if (Job_Vector == NULL)
LOG_E(OMG, "[RWP] Job Vector is NULL\n");
// else
// LOG_T(OMG, "\nJob_Vector_Rwp->pair->b->ID %d\n", Job_Vector_Rwp->pair->b->ID);*/
job_vector_len[RWP]++;
}
return(0);
n_id += omg_param_list.nodes;
if (job_vector[RWP] == NULL)
LOG_E (OMG, "[RWP] Job Vector is NULL\n");
return (0);
}
void place_rwp_node(NodePtr node) {
void
place_rwp_node (node_struct * node)
{
int loc_num;
double block_xmin, block_ymin;
if (omg_param_list[node->type].rwp_type == RESTIRICTED_RWP)
{
loc_num = (int) randomgen (0, omg_param_list[node->type].max_vertices);
node->x_pos =
(double) vertice_xpos (loc_num, omg_param_list[node->type]);
node->y_pos =
(double) vertice_ypos (loc_num, omg_param_list[node->type]);
//LOG_D(OMG,"location number %d x pos %.2f y pos %.2f \n\n",loc_num,node->x_pos,node->y_pos);
}
else if (omg_param_list[node->type].rwp_type == CONNECTED_DOMAIN)
{
node->block_num =
(int) randomgen (0, omg_param_list[node->type].max_block_num);
block_xmin = area_minx (node->block_num, omg_param_list[node->type]);
block_ymin = area_miny (node->block_num, omg_param_list[node->type]);
node->X_pos = (double) ((int) (randomGen(omg_param_list.min_X, omg_param_list.max_X)*100))/ 100;
node->mob->X_from = node->X_pos;
node->mob->X_to = node->X_pos;
node->Y_pos = (double) ((int) (randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100;
node->mob->Y_from = node->Y_pos;
node->mob->Y_to = node->Y_pos;
node->x_pos =
(double) ((int) (randomgen (block_xmin, xloc_div + block_xmin) * 100))
/ 100;
node->y_pos =
(double) ((int) (randomgen (block_ymin, yloc_div + block_ymin) * 100))
/ 100;
}
else
{
node->x_pos =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_x,
omg_param_list[node->type].max_x) * 100)) / 100;
node->y_pos =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_y,
omg_param_list[node->type].max_y) * 100)) / 100;
}
node->mob->x_from = node->x_pos;
node->mob->x_to = node->x_pos;
node->mob->y_from = node->y_pos;
node->mob->y_to = node->y_pos;
node->mob->speed = 0.0;
node->mob->journey_time = 0.0;
LOG_I (OMG,
" #[RWP] Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = 0.0\n ",
node->id, node->type, node->x_pos, node->y_pos);
LOG_I(OMG, "[RWP] Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = 0.0\n ", node->ID, node->type, node->X_pos, node->Y_pos);
Node_Vector[RWP] = (Node_list) add_entry(node, Node_Vector[RWP]);
Node_Vector_len[RWP]++;
node_vector_end[node->type] =
(node_list *) add_entry (node, node_vector_end[node->type]);
if (node_vector[node->type] == NULL)
node_vector[node->type] = node_vector_end[node->type];
node_vector_len[node->type]++;
//Initial_Node_Vector_len[RWP]++;
}
Pair sleep_rwp_node(NodePtr node, double cur_time){
void
sleep_rwp_node (pair_struct * pair, double cur_time)
{
node_struct *node;
node = pair->b;
node->mobile = 0;
node->mob->speed = 0.0;
node->mob->X_from = node->mob->X_to;
node->mob->Y_from = node->mob->Y_to;
node->X_pos = node->mob->X_to;
node->Y_pos = node->mob->Y_to;
Pair pair = malloc(sizeof(Pair)) ;
node->mob->sleep_duration = (double) ((int) (randomGen(omg_param_list.min_sleep, omg_param_list.max_sleep)*100))/ 100;
LOG_D(OMG, "[RWP] node: %d \tsleep duration : %.2f\n",node->ID, node->mob->sleep_duration);
node->mob->x_from = node->mob->x_to;
node->mob->y_from = node->mob->y_to;
node->x_pos = node->mob->x_to;
node->y_pos = node->mob->y_to;
node->mob->sleep_duration =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_sleep,
omg_param_list[node->type].max_sleep) * 100)) / 100;
/*LOG_D (OMG, "#[RWP] node: %d \tsleep duration : %.2f\n", node->id,
node->mob->sleep_duration); */
node->mob->start_journey = cur_time;
pair->a = node->mob->start_journey + node->mob->sleep_duration; //when to wake up
LOG_D(OMG, "[RWP] wake up at time: cur_time + sleep_duration : %.2f\n", pair->a);
pair->b = node;
pair->next_event_t = cur_time + node->mob->sleep_duration; //when to wake up
// LOG_D (OMG, "[RWP] wake up at time: cur_time + sleep_duration : %.2f\n",
// pair->a);
return pair;
}
Pair move_rwp_node(NodePtr node, double cur_time) {
}
Pair pair = malloc(sizeof(Pair));
LOG_D(OMG, "[RWP] move node: %d\n",node->ID );
node->mob->X_from = node->X_pos;
node->mob->Y_from = node->Y_pos;
LOG_D(OMG, "[RWP] Current Position: (%.2f, %.2f)\n", node->mob->X_from, node->mob->Y_from);
node->mobile = 0;
double X_next = (double) ((int)(randomGen(omg_param_list.min_X,omg_param_list.max_X)*100))/ 100;
node->mob->X_to = X_next;
double Y_next = (double) ((int)(randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100;
node->mob->Y_to = Y_next;
LOG_D(OMG, "[RWP] destination: (%.2f, %.2f)\n", node->mob->X_to, node->mob->Y_to);
double speed_next = (double) ((int)(randomGen(omg_param_list.min_speed, omg_param_list.max_speed)*100))/ 100;
node->mob->speed = speed_next;
LOG_D(OMG, "[RWP] speed_next %.2f\n", speed_next); //m/s
double distance = (double) ((int)(sqrtf(pow(node->mob->X_from - X_next, 2) + pow(node->mob->Y_from - Y_next, 2))*100))/ 100;
LOG_D(OMG, "[RWP] distance %.2f\n", distance); //m
double journeyTime_next = (double) ((int)(distance/speed_next*100))/ 100; //duration to get to dest
////node->mob->journey_time = journeyTime_next;
void
move_rwp_node (pair_struct * pair, double cur_time)
{
int loc_num;
double distance, journeytime_next;
double pr, block_xmin, block_ymin;
//LOG_D (OMG, "[RWP] move node: %d\n", node->ID);
node_struct *node;
node = pair->b;
node->mob->x_from = node->mob->x_to;
node->mob->y_from = node->mob->y_to;
node->x_pos = node->mob->x_to;
node->y_pos = node->mob->y_to;
node->mobile = 1;
LOG_D(OMG, "[RWP] mob->journey_time_next %.2f\n",journeyTime_next );
node->mob->start_journey = cur_time;
LOG_D(OMG, "[RWP] start_journey %.2f\n", node->mob->start_journey );
pair->a = node->mob->start_journey + journeyTime_next; //when to reach the destination
LOG_D(OMG, "[RWP] reaching the destination at time : start journey + journey_time next =%.2f\n", pair->a);
pair->b = node;
return pair;
}
if (omg_param_list[node->type].rwp_type == RESTIRICTED_RWP)
{
do
{
loc_num =
(int) randomgen (0, omg_param_list[node->type].max_vertices);
node->mob->x_to =
(double) vertice_xpos (loc_num, omg_param_list[node->type]);
node->mob->y_to =
(double) vertice_ypos (loc_num, omg_param_list[node->type]);
void update_rwp_nodes(double cur_time) {
Job_list tmp = Job_Vector;
int done = 0; //
while ((tmp != NULL) && (done == 0)){
// if (tmp->pair == NULL){LOG_E(OMG, "UPDATE RWP : tmp->pair ==NULL\n" );}
// if (tmp->pair != NULL){LOG_E(OMG, "UPDATE RWP : tmp->pair !=NULL\n" );}
LOG_D(OMG, "[RWP] cur_time %f reaching the destination at %f\n", cur_time, tmp->pair->a );
if((tmp->pair !=NULL) && ( (double)tmp->pair->a >= cur_time - eps) && ( (double)tmp->pair->a <= cur_time + eps) ) {
if (tmp->pair->b->generator == RWP){
LOG_D(OMG, "[RWP](first_job_time) %.2f == %.2f (cur_time) \n ",tmp->pair->a, cur_time );
NodePtr my_node = (NodePtr)tmp->pair->b;
if(my_node->mobile == 1) {
LOG_D(OMG, "[RWP] node %d goes to sleep\n", my_node->ID);
my_node->mobile = 0;
Pair pair = malloc(sizeof(Pair));
pair = sleep_rwp_node(my_node, cur_time);
tmp->pair = pair;
tmp = tmp->next;
}
else if (my_node->mobile ==0) {
LOG_D(OMG, "[RWP] node %d starts to move again \n", my_node->ID);
my_node->mobile = 1;
Pair pair = malloc(sizeof(Pair));
pair = move_rwp_node(my_node, cur_time);
tmp->pair = pair;
tmp = tmp->next;
}
else{
LOG_E(OMG,"[RWP] update_generator: unsupported node state - mobile : %d \n", my_node->mobile);
exit(-1);
}
}
else {
LOG_D(OMG, "[RWP](first_job_time) %.2f == %.2f(cur_time) but (generator=%d) != (RWP=%d)\n ",tmp->pair->a, cur_time, tmp->pair->b->generator, RWP );
tmp = tmp->next;
}
while (node->mob->x_to == node->mob->x_from
&& node->mob->y_to == node->mob->y_from);
distance = fabs (node->mob->x_to - node->mob->x_from) +
fabs (node->mob->y_to - node->mob->y_from);
/* LOG_D(OMG,"#location number %d x pos to %.2f y pos to %.2f x pos from %.2f y pos from %.2f\n\n",loc_num,node->mob->x_to,node->mob->y_to,node->mob->x_from,node->mob->y_from); */
}
else if ( (tmp->pair != NULL) && (cur_time < tmp->pair->a ) ){ //&& (tmp->pair->b->generator == RWP)
LOG_D(OMG, "[RWP] Nothing to do as current time %.2f is less than the time to reach the destination %.2f \n",cur_time, tmp->pair->a);
done = 1; //quit the loop
else if (omg_param_list[node->type].rwp_type == CONNECTED_DOMAIN)
{
pr = randomgen (0, 1);
if (pr <= 0.50)
/*node->block_num =
(int) randomgen (0, omg_param_list[node->type].max_block_num); */
node->block_num =
(int) next_block (node->block_num, omg_param_list[node->type]);
block_xmin = area_minx (node->block_num, omg_param_list[node->type]);
block_ymin = area_miny (node->block_num, omg_param_list[node->type]);
node->mob->x_to =
(double) ((int) (randomgen (block_xmin, xloc_div + block_xmin) * 100))
/ 100;
node->mob->y_to =
(double) ((int) (randomgen (block_ymin, yloc_div + block_ymin) * 100))
/ 100;
distance =
(double) ((int) (sqrtf
(pow (node->mob->x_from - node->mob->x_to, 2) +
pow (node->mob->y_from - node->mob->y_to,
2)) * 100)) / 100;
node->mob->azimuth = atan2 (node->mob->y_to - node->mob->y_from, node->mob->x_to - node->mob->x_from); //radian
}
else {
LOG_E(OMG,"[RWP] current time %.2f is %f greater than the time to reach the destination %.2f\n", cur_time, eps, tmp->pair->a );
done = 1; //quit the loop
// exit(-1);
else
{
node->mob->x_to =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_x,
omg_param_list[node->type].max_x) * 100)) / 100;
node->mob->y_to =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_y,
omg_param_list[node->type].max_y) * 100)) / 100;
distance =
(double) ((int) (sqrtf (pow (node->mob->x_from - node->mob->x_to, 2) +
pow (node->mob->y_from - node->mob->y_to,
2)) * 100)) / 100;
node->mob->azimuth = atan2 (node->mob->y_to - node->mob->y_from, node->mob->x_to - node->mob->x_from); //radian
}
node->mob->speed =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_speed,
omg_param_list[node->type].max_speed) * 100)) / 100;
journeytime_next = (double) ((int) (distance / node->mob->speed * 100)) / 100; //duration to get to dest
/* LOG_D (OMG, "#[RWP] %d mob->journey_time_next %.2f distance %.2f speed %.2f\n \n",node->id, journeytime_next, distance,node->mob->speed);
*/
node->mob->start_journey = cur_time;
//LOG_D (OMG, "[RWP] start_journey %.2f\n", node->mob->start_journey);
pair->next_event_t = cur_time + journeytime_next; //when to reach the destination
// LOG_D (OMG,
// "[RWP] reaching the destination at time : start journey + journey_time next =%.2f\n",
// pair->a);
/*
if (node->event_num < 100)
{
event_sum[node->event_num] += node->mob->speed;
events[node->event_num]++;
node->event_num++;
}
//sorting the new entries
LOG_D(OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
display_job_list(Job_Vector);
Job_Vector = quick_sort (Job_Vector);///////////
LOG_D(OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
display_job_list(Job_Vector);
*/
}
void get_rwp_positions_updated(double cur_time){
double X_now=0.0;
double Y_now=0.0;
LOG_D(OMG, "--------GET RWP POSITIONS--------\n");
/*update RWP nodes position*/
Pair my_pair = Job_Vector->pair;
if ( (my_pair !=NULL) && (cur_time <= my_pair->a +eps)){
LOG_D(OMG, "[RWP] current time %.2f <= time when reaching the destination %.2f\n ",cur_time, my_pair->a);
Job_list tmp = Job_Vector;
while (tmp != NULL){
if (tmp->pair->b->generator == RWP){
if (tmp->pair->b->mobile == 0){ //node is sleeping
LOG_D(OMG, "[RWP] node number %d is sleeping at location: (%.2f, %.2f)\n", tmp->pair->b->ID, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
}
else if (tmp->pair->b->mobile == 1){ //node is moving
LOG_D(OMG, "[RWP] destination not yet reached for node %d from (%.2f, %.2f)\tto (%.2f, %.2f)\tspeed %.2f\t(X_pos %.2f\tY_pos %.2f)\n",
tmp->pair->b->ID, tmp->pair->b->mob->X_from, tmp->pair->b->mob->Y_from,tmp->pair->b->mob->X_to,
tmp->pair->b->mob->Y_to,tmp->pair->b->mob->speed, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
double len = sqrtf(pow(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to,2)+pow(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to,2));
double dx = fabs(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to) / len;
double dy = fabs(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to) / len;
//LOG_D(OMG, "len %f\tdx %f\tdy %f\n", len, dx, dy);
if (tmp->pair->b->mob->X_from < tmp->pair->b->mob->X_to ){
X_now = tmp->pair->b->mob->X_from + (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey) ) );
}
else{
X_now = tmp->pair->b->mob->X_from - (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
}
void
update_rwp_nodes (double cur_time)
{
int done = 0;
job_list *tmp = job_vector[RWP];
node_struct *my_node;
while (tmp != NULL && done == 0)
{
my_node = (node_struct *) tmp->pair->b;
//case1:time to next event equals to current time
if (tmp->pair != NULL
&& ((double) tmp->pair->next_event_t >= cur_time - eps)
&& ((double) tmp->pair->next_event_t <= cur_time + eps))
{
if (my_node->mobile == 1)
sleep_rwp_node (tmp->pair, cur_time);
else
move_rwp_node (tmp->pair, cur_time);
if (tmp->pair->b->mob->Y_from < tmp->pair->b->mob->Y_to ){
Y_now = tmp->pair->b->mob->Y_from + (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
}
else{
Y_now = tmp->pair->b->mob->Y_from - (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
}
//case2: current time is greater than the time to next event
else if (tmp->pair != NULL
&& (cur_time - eps) > tmp->pair->next_event_t)
{
while (cur_time >= tmp->pair->next_event_t)
{
if (my_node->mobile == 1)
sleep_rwp_node (tmp->pair, cur_time);
else
move_rwp_node (tmp->pair, cur_time);
tmp->pair->b->X_pos = (double) ((int) (X_now*100))/ 100;
tmp->pair->b->Y_pos = (double) ((int) (Y_now*100))/ 100;
//tmp->pair->b->mob->X_from = tmp->pair->b->X_pos;
//tmp->pair->b->mob->Y_from = tmp->pair->b->Y_pos;
//tmp->pair->b->mob->start_journey = cur_time;
LOG_D(OMG, "[RWP] Updated_position of node number %d is :(%.2f, %.2f)\n", tmp->pair->b->ID, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
}
else{
LOG_E(OMG, "[RWP] Update_generator: unsupported node state - mobile : %d \n", tmp->pair->b->mobile);
return;
}
//case3: current time less than the time to next event
else
{
done = 1; //quit the loop
}
tmp = tmp->next;
}
}
else {
LOG_E(OMG, "ERROR (current time) %f > %f (first job_time) \n", cur_time ,my_pair->a );
}
}
//sorting the new entries
//LOG_D (OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
// display_job_list (job_vector);
job_vector[RWP] = quick_sort (job_vector[RWP]); ///////////
// LOG_D (OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
//display_job_list (job_vector[RWP]);
}
/*void update_rwp_nodes(double cur_time) {
LOG_D(OMG, "--------UPDATE--------\n");
int l = 0;
Job_list tmp = Job_Vector;
void
get_rwp_positions_updated (double cur_time)
{
while (l < Job_Vector_len){
LOG_D(OMG, "l == %d \n", l);
double x_now = 0.0, y_now = 0.0;
double len, dx, dy;
job_list *tmp = job_vector[RWP];
//Pair my_pair = malloc (sizeof(Pair));
//my_pair = tmp->pair;
while (tmp != NULL)
{
if (tmp->pair == NULL){LOG_E(OMG, "UPDATE RWP : tmp->pair ==NULL\n" );}
if (tmp->pair != NULL){LOG_E(OMG, "UPDATE RWP : tmp->pair ==NULL\n" );}
if (tmp->pair->b->mobile == 1 && tmp->pair->next_event_t >= cur_time)
{
LOG_D(OMG, "cur_time %f\n", cur_time );
LOG_D(OMG, "tmp->pair->a %f\n", tmp->pair->a );
if (omg_param_list[tmp->pair->b->type].rwp_type == RESTIRICTED_RWP)
{
len =
tmp->pair->b->mob->speed * (cur_time -
tmp->pair->b->mob->start_journey);
dx = fabs (tmp->pair->b->mob->x_from - tmp->pair->b->mob->x_to);
if((tmp->pair !=NULL) && ( (double)tmp->pair->a >= cur_time - eps) && ( (double)tmp->pair->a <= cur_time + eps) ) {
if (tmp->pair->b->generator == RWP){
LOG_D(OMG, " (first_job_time) %.2f == %.2f (cur_time) \n ",tmp->pair->a, cur_time );
LOG_D(OMG, " UPDATE RWP \n ");
NodePtr my_node = (NodePtr)tmp->pair->b;
if(my_node->mobile == 1) {
LOG_D(OMG, " stop node and let it sleep \n" );
my_node->mobile = 0;
Pair pair = malloc(sizeof(Pair));
pair = sleep_rwp_node(my_node, cur_time);
tmp->pair = pair;
}
else if (my_node->mobile ==0) {
LOG_D(OMG, " node %d slept enough...let's move again \n", my_node->ID);
my_node->mobile = 1;
Pair pair = malloc(sizeof(Pair));
pair = move_rwp_node(my_node, cur_time);
tmp->pair = pair;
if (dx < len)
{
tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
tmp->pair->b->y_pos =
tmp->pair->b->mob->y_from + (len -
dx) *
((tmp->pair->b->mob->y_to -
tmp->pair->b->mob->y_from) /
fabs (tmp->pair->b->mob->y_to -
tmp->pair->b->mob->y_from));
}
else
{
LOG_D(OMG, "update_generator: unsupported node state - mobile : %d \n", my_node->mobile);
tmp->pair->b->y_pos = tmp->pair->b->mob->y_from;
tmp->pair->b->x_pos = tmp->pair->b->mob->x_from + len *
((tmp->pair->b->mob->x_to - tmp->pair->b->mob->x_from)
/ fabs (tmp->pair->b->mob->x_to -
tmp->pair->b->mob->x_from));
}
//sorting the new entries
LOG_D(OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
display_job_list(Job_Vector);
Job_Vector = quick_sort (Job_Vector);///////////
LOG_D(OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
display_job_list(Job_Vector);
LOG_D(OMG, "lgggggggggggggggggggggggggggggggggggggggggg\n");
if (tmp != NULL){LOG_E(OMG, "UPDATE RWP : tmp !=NULL\n" );}
tmp = tmp->next;
if (tmp->pair == NULL){LOG_E(OMG, "UPDATE RWP : tmp->pair ==NULL\n" );}
l++;
}
else {
LOG_D(OMG, " (first_job_time) %.2f == %.2f(cur_time) but (generator=%d) != (RWP=%d)\n ",tmp->pair->a, cur_time, tmp->pair->b->generator, RWP );
tmp = tmp->next;
if (tmp->pair == NULL){LOG_E(OMG, "UPDATE RWP : tmp->pair ==NULL\n" );}
l++;
}
}
else if ( (tmp->pair != NULL) && (cur_time < tmp->pair->a ) ){ //&& (tmp->pair->b->generator == RWP)
LOG_D(OMG, " %.2f < %.2f \n",cur_time, tmp->pair->a);
LOG_N(OMG, "Nothing to do\n");
l = Job_Vector_len;
}
else {
LOG_E(OMG, "\n %.2f > %.2f", cur_time,tmp->pair->a ); //LOG_D(OMG, " (generator=%d) != (RWP=%d) \n", tmp->pair->b->generator, RWP );
l = Job_Vector_len;
}
}
}*/
else
{
len =
tmp->pair->b->mob->speed * (cur_time -
tmp->pair->b->mob->start_journey);
dx = len * cos (tmp->pair->b->mob->azimuth);
dy = len * sin (tmp->pair->b->mob->azimuth);
x_now = tmp->pair->b->mob->x_from + dx;
y_now = tmp->pair->b->mob->y_from + dy;
tmp->pair->b->x_pos = (double) ((int) (x_now * 100)) / 100;
tmp->pair->b->y_pos = (double) ((int) (y_now * 100)) / 100;
} //grid
}
else
{
tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
tmp->pair->b->y_pos = tmp->pair->b->mob->y_to;
}
/*if(tmp->pair->b->id==2 && ((int)(cur_time*1000)% 100)==0)
LOG_D (OMG, "# %d %.2f %.2f \n\n",tmp->pair->b->id,tmp->pair->b->x_pos,tmp->pair->b->y_pos); */
tmp = tmp->next;
}
}
......@@ -37,7 +37,7 @@
#define RWP_H_
#include "omg.h"
#include "grid.h"
/**
* \fn void start_rwp_generator(omg_global_param omg_param_list)
......@@ -51,7 +51,7 @@ int start_rwp_generator(omg_global_param omg_param_list) ;
* \brief Called by the function start_rwp_generator(), it generates a random position ((X,Y) coordinates) for a node and add it to the Node_Vector_Rwp
* \param node a pointer of type NodePtr that represents the node to which the random position is assigned
*/
void place_rwp_node(NodePtr node);
void place_rwp_node(node_struct* node);
/**
* \fn Pair sleep_rwp_node(NodePtr node, double cur_time)
......@@ -61,7 +61,7 @@ void place_rwp_node(NodePtr node);
* \param cur_time a variable of type double that represents the current time
* \return A Pair structure containing the node and the time when it is reaching the destination
*/
Pair sleep_rwp_node(NodePtr node, double cur_time) ;
void sleep_rwp_node(pair_struct* pair, double cur_time) ;
/**
* \fn Pair move_rwp_node(NodePtr node, double cur_time)
......@@ -71,7 +71,7 @@ Pair sleep_rwp_node(NodePtr node, double cur_time) ;
* \param cur_time a variable of type double that represents the current time
* \return A Pair structure containing the node structure and the arrival time at the destination
*/
Pair move_rwp_node(NodePtr node, double cur_time) ;
void move_rwp_node(pair_struct* pair, double cur_time);
/**
* \fn void update_rwp_nodes(double cur_time)
......
......@@ -77,17 +77,17 @@ int connection_(char *, int);
void sendExact(int);
/**
* \fn recieveExact();
* \fn recieveExact(void);
* \brief Pack the data to storage from buf after reading from socket
* Returns storage pointer
*/
storage* receiveExact();
storage* receiveExact(void);
/**
* \fn close_connection();
* \fn close_connection(void);
* \brief close socket connection
*/
void close_connection();
void close_connection(void);
#endif
......@@ -29,11 +29,11 @@
/*! \file rwalk.c
* \brief static mobility generator
* \author M. Mahersi, J. Harri, N. Nikaein, Andre Gomes (One source)
* \author M. Mahersi, N. Nikaein, J. Harri
* \date 2011
* \version 0.1
* \company Eurecom
* \email: openair_tech@eurecom.fr
* \email:
* \note
* \warning
*/
......@@ -41,79 +41,103 @@
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "static.h"
#include "omg.h"
void place_static_node(NodePtr node);
void start_static_generator(omg_global_param omg_param_list) {
void
start_static_generator (omg_global_param omg_param_list)
{
int n_id=0;
// double cur_time = 1.0;
NodePtr node = NULL;
MobilityPtr mobility = NULL;
int id;
static int n_id = 0;
node_struct *node = NULL;
mobility_struct *mobility = NULL;
srand (omg_param_list.seed + STATIC);
if (omg_param_list.nodes <= 0){
LOG_W(OMG, "Number of static nodes has not been set\n");
return;
}
srand(omg_param_list.seed + STATIC);
// for (n_id = omg_param_list.first_ix; n_id< omg_param_list.first_ix + omg_param_list.nodes; n_id++){
if (omg_param_list.nodes_type == eNB) {
LOG_I(OMG, "Static mobility model for %d eNBs \n", omg_param_list.nodes);
} else if (omg_param_list.nodes_type == UE) {
LOG_I(OMG, "Static mobility model for %d UE\n",omg_param_list.nodes);
}
for (n_id = 0; n_id< omg_param_list.nodes; n_id++) {
LOG_I (OMG, "Static mobility model for %d %d nodes\n", omg_param_list.nodes,
omg_param_list.nodes_type);
for (id = n_id; id < (omg_param_list.nodes + n_id); id++)
{
node = (NodePtr) create_node();
mobility = (MobilityPtr) create_mobility();
node = create_node ();
mobility = create_mobility ();
node->ID = n_id;
node->generator = omg_param_list.mobility_type;
node->id = id;
node->type = omg_param_list.nodes_type;
node->mob = mobility;
node->generator = STATIC;
place_static_node(node); //initial positions
place_static_node (node); //initial positions
}
n_id += omg_param_list.nodes;
}
void place_static_node(NodePtr node) {
if (omg_param_list.user_fixed && node->type == eNB) {
if (omg_param_list.fixed_X <= omg_param_list.max_X && omg_param_list.fixed_X >= omg_param_list.min_X)
node->X_pos = omg_param_list.fixed_X;
void
place_static_node (node_struct * node)
{
if (omg_param_list[node->type].user_fixed && node->type == eNB)
{
if (omg_param_list[node->type].fixed_x <=
omg_param_list[node->type].max_x
&& omg_param_list[node->type].fixed_x >=
omg_param_list[node->type].min_x)
node->x_pos = omg_param_list[node->type].fixed_x;
else
node->X_pos = (double) ((int) (randomGen(omg_param_list.min_X, omg_param_list.max_X)*100))/ 100;
node->mob->X_from = node->X_pos;
node->mob->X_to = node->X_pos;
if (omg_param_list.fixed_Y <= omg_param_list.max_Y && omg_param_list.fixed_Y >= omg_param_list.min_Y)
node->Y_pos = omg_param_list.fixed_Y;
node->x_pos =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_x,
omg_param_list[node->type].max_x) * 100)) / 100;
node->mob->x_from = node->x_pos;
node->mob->x_to = node->x_pos;
if (omg_param_list[node->type].fixed_y <=
omg_param_list[node->type].max_y
&& omg_param_list[node->type].fixed_y >=
omg_param_list[node->type].min_y)
node->y_pos = omg_param_list[node->type].fixed_y;
else
node->Y_pos = (double) ((int) (randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100;
node->mob->Y_from = node->Y_pos;
node->mob->Y_to = node->Y_pos;
node->y_pos =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_y,
omg_param_list[node->type].max_y) * 100)) / 100;
node->mob->y_from = node->y_pos;
node->mob->y_to = node->y_pos;
}
else {
node->X_pos = (double) ((int) (randomGen(omg_param_list.min_X, omg_param_list.max_X)*100))/ 100;
node->mob->X_from = node->X_pos;
node->mob->X_to = node->X_pos;
node->Y_pos = (double) ((int) (randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100;
node->mob->Y_from = node->Y_pos;
node->mob->Y_to = node->Y_pos;
else
{
node->x_pos =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_x,
omg_param_list[node->type].max_x) * 100)) / 100;
node->mob->x_from = node->x_pos;
node->mob->x_to = node->x_pos;
node->y_pos =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_y,
omg_param_list[node->type].max_y) * 100)) / 100;
node->mob->y_from = node->y_pos;
node->mob->y_to = node->y_pos;
}
node->mob->speed = 0.0;
node->mob->journey_time = 0.0;
LOG_I(OMG, "[STATIC] Initial position of node ID: %d type(UE, eNB): %d (X = %.2f, Y = %.2f) speed = 0.0\n", node->ID, node->type, node->X_pos, node->Y_pos);
Node_Vector[STATIC] = (Node_list) add_entry(node, Node_Vector[STATIC]);
Node_Vector_len[STATIC]++;
//Initial_Node_Vector_len[STATIC]++;
LOG_I (OMG,
"[STATIC] Initial position of node ID: %d type(%d): (X = %.2f, Y = %.2f) speed = 0.0\n",
node->id, node->type, node->x_pos, node->y_pos);
node_vector_end[node->type] =
(node_list *) add_entry (node, node_vector_end[node->type]);
}
if (node_vector[node->type] == NULL)
node_vector[node->type] = node_vector_end[node->type];
node_vector_len[node->type]++;
}
......@@ -51,6 +51,6 @@ void start_static_generator(omg_global_param omg_param_list);
* \brief Generates a random position ((X,Y) coordinates) and assign it to the node passed as argument. This latter node is then added to the Node_Vector[STATIC]
* \param node a pointer of type NodePtr that represents the node to which the random position is assigned
*/
void place_static_node(NodePtr node);
void place_static_node(node_struct* node);
#endif /* STATIC_H_ */
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2011 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fsr/openairinterface
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
*******************************************************************************/
/*! \file steadystaterwp.c
* \brief random waypoint mobility generator
* \author S. Gashaw, J. Harri, N. Nikaein,
* \date 2014
* \version 0.1
* \company Eurecom
* \email:
* \note
* \warning
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include "omg.h"
#include "steadystaterwp.h"
#include "rwp.h"
#define RESTIRICTED_RWP 1
#define CONNECTED_DOMAIN 2
int
start_steadystaterwp_generator (omg_global_param omg_param_list)
{
static int n_id = 0;
int id;
double cur_time = 0.0, pause_p;
node_struct *node = NULL;
mobility_struct *mobility = NULL;
pair_struct *pair = NULL;
pause_p = pause_probability (omg_param_list);
srand (omg_param_list.seed + RWP);
LOG_I (OMG, "STEADY_RWP mobility model for %d %d nodes\n",
omg_param_list.nodes, omg_param_list.nodes_type);
for (id = n_id; id < (omg_param_list.nodes + n_id); id++)
{
node = create_node ();
mobility = create_mobility ();
node->id = id;
node->type = omg_param_list.nodes_type;
node->mob = mobility;
node->generator = STEADY_RWP;
node->event_num = 0;
place_rwp_node (node); //initial positions
pair = (pair_struct *) malloc (sizeof (struct pair_struct));
pair->b = node;
//pause probability...some of the nodes start at pause & the other on move
if (randomgen (0, 1) < pause_p)
sleep_steadystaterwp_node (pair, cur_time); //sleep
else
move_steadystaterwp_node (pair, cur_time);
job_vector_end[STEADY_RWP] = add_job (pair, job_vector_end[STEADY_RWP]);
if (job_vector[STEADY_RWP] == NULL)
job_vector[STEADY_RWP] = job_vector_end[STEADY_RWP];
job_vector_len[STEADY_RWP]++;
}
n_id += omg_param_list.nodes;
if (job_vector[STEADY_RWP] == NULL)
LOG_E (OMG, "[STEADY_RWP] Job Vector is NULL\n");
return (0);
}
/*********************************xxxxxx************************************/
void
place_steadystaterwp_node (node_struct * node)
{
int loc_num;
double block_xmin, block_ymin;
if (grid == RESTIRICTED_RWP)
{
loc_num = (int) randomgen (0, omg_param_list[node->type].max_vertices);
node->x_pos =
(double) vertice_xpos (loc_num, omg_param_list[node->type]);
node->y_pos =
(double) vertice_ypos (loc_num, omg_param_list[node->type]);
//LOG_D(OMG,"location number %d x pos %.2f y pos %.2f \n\n",loc_num,node->x_pos,node->y_pos);
}
else if (grid == CONNECTED_DOMAIN)
{
node->block_num =
(int) randomgen (0, omg_param_list[node->type].max_block_num);
block_xmin = area_minx (node->block_num, omg_param_list[node->type]);
block_ymin = area_miny (node->block_num, omg_param_list[node->type]);
node->x_pos =
(double) ((int) (randomgen (block_xmin, xloc_div + block_xmin) * 100))
/ 100;
node->y_pos =
(double) ((int) (randomgen (block_ymin, yloc_div + block_ymin) * 100))
/ 100;
}
else
{
node->x_pos =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_x,
omg_param_list[node->type].max_x) * 100)) / 100;
node->y_pos =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_y,
omg_param_list[node->type].max_y) * 100)) / 100;
}
node->mob->x_from = node->x_pos;
node->mob->x_to = node->x_pos;
node->mob->y_from = node->y_pos;
node->mob->speed = 0.0;
node->mob->journey_time = 0.0;
LOG_I (OMG,
"#[STEADY_RWP] Initial position of node ID: %d type: %d X = %.2f, Y = %.2f\n ",
node->id, node->type, node->x_pos, node->y_pos);
node_vector_end[node->type] =
(node_list *) add_entry (node, node_vector_end[node->type]);
if (node_vector[node->type] == NULL)
node_vector[node->type] = node_vector_end[node->type];
node_vector_len[node->type]++;
//Initial_Node_Vector_len[RWP]++;
}
/*********************************xxxxxx************************************/
void
sleep_steadystaterwp_node (pair_struct * pair, double cur_time)
{
static int initial = 1;
node_struct *node;
node = pair->b;
node->mobile = 0;
node->mob->speed = 0.0;
node->mob->x_from = node->mob->x_to;
node->mob->y_from = node->mob->y_to;
node->x_pos = node->mob->x_to;
node->y_pos = node->mob->y_to;
if (node->event_num == 0)
{
node->mob->sleep_duration = initial_pause (omg_param_list[node->type]);
node->event_num++;
}
else
{
node->mob->sleep_duration =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_sleep,
omg_param_list[node->type].max_sleep) * 100)) / 100;
}
// LOG_D (OMG, "[STEADY_RWP] node: %d \tsleep duration : %.2f\n", node->ID,
// node->mob->sleep_duration);
node->mob->start_journey = cur_time;
pair->next_event_t = cur_time + node->mob->sleep_duration; //when to wake up
// LOG_D (OMG, "[STEADY_RWP] wake up at time: cur_time + sleep_duration : %.2f\n",
// pair->a);
}
void
move_steadystaterwp_node (pair_struct * pair, double cur_time)
{
static int initial = 1;
double distance, journeytime_next, max_distance;
double temp_x, temp_y, u1, u2;
int loc_num;
double pr, block_xmin, block_ymin;
//LOG_D (OMG, "[STEADY_RWP] move node: %d\n", node->ID);
node_struct *node;
node = pair->b;
node->mob->x_from = node->mob->x_to;
node->mob->y_from = node->mob->y_to;
node->x_pos = node->mob->x_to;
node->y_pos = node->mob->y_to;
node->mobile = 1;
//initial move
if (node->event_num == 0)
{
if (grid == CONNECTED_DOMAIN)
{
max_distance = 2 * yloc_div;
/* sqrtf (pow
(omg_param_list[node->type].max_x -
omg_param_list[node->type].min_x,
2) + pow (omg_param_list[node->type].max_y -
omg_param_list[node->type].min_y, 2)); */
while (true)
{
pr = randomgen (0, 1);
if (pr <= 0.50)
/*node->block_num =
(int) randomgen (0,
omg_param_list[node->type].max_block_num); */
node->block_num =
(int) next_block (node->block_num,
omg_param_list[node->type]);
block_xmin =
area_minx (node->block_num, omg_param_list[node->type]);
block_ymin =
area_miny (node->block_num, omg_param_list[node->type]);
node->mob->x_to =
(double) ((int)
(randomgen (block_xmin, xloc_div + block_xmin) *
100)) / 100;
node->mob->y_to =
(double) ((int)
(randomgen (block_ymin, yloc_div + block_ymin) *
100)) / 100;
pr = randomgen (0, 1);
if (pr <= 0.50)
/*node->block_num =
(int) randomgen (0,
omg_param_list[node->type].max_block_num); */
node->block_num =
(int) next_block (node->block_num,
omg_param_list[node->type]);
block_xmin =
area_minx (node->block_num, omg_param_list[node->type]);
block_ymin =
area_miny (node->block_num, omg_param_list[node->type]);
temp_x =
(double) ((int)
(randomgen (block_xmin, xloc_div + block_xmin) *
100)) / 100;
temp_y =
(double) ((int)
(randomgen (block_ymin, yloc_div + block_ymin) *
100)) / 100;
u1 = randomgen (0, 1);
if (u1 <
(sqrtf
(pow (node->mob->x_to - temp_x, 2) +
pow (node->mob->y_to - temp_y, 2)) / max_distance))
{
u2 = randomgen (0, 1);
distance =
(double) ((int)
(sqrtf (pow (temp_x - node->mob->x_to, 2) +
pow (temp_y - node->mob->y_to,
2)) * 100)) / 100;
node->mob->azimuth = atan2 (node->mob->y_to - node->mob->y_from, node->mob->x_to - node->mob->x_from); //radian
node->mob->x_from =
temp_x + u2 * distance * cos (node->mob->azimuth);
node->mob->y_from =
temp_y + u2 * distance * sin (node->mob->azimuth);
break;
}
}
}
else
{
max_distance =
sqrtf (pow
(omg_param_list[node->type].max_x -
omg_param_list[node->type].min_x,
2) + pow (omg_param_list[node->type].max_y -
omg_param_list[node->type].min_y, 2));
while (true)
{
node->mob->x_to =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_x,
omg_param_list[node->type].max_x) * 100)) / 100;
node->mob->y_to =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_y,
omg_param_list[node->type].max_y) * 100)) / 100;
temp_x = (double) ((int)
(randomgen
(omg_param_list[node->type].min_x,
omg_param_list[node->type].max_x) * 100)) /
100;
temp_y = (double) ((int)
(randomgen
(omg_param_list[node->type].min_y,
omg_param_list[node->type].max_y) * 100)) /
100;
u1 = randomgen (0, 1);
if (u1 <
(sqrtf
(pow (node->mob->x_to - temp_x, 2) +
pow (node->mob->y_to - temp_y, 2)) / max_distance))
{
u2 = randomgen (0, 1);
node->mob->x_from =
u2 * temp_x + (1 - u2) * node->mob->x_to;
node->mob->y_from =
u2 * temp_y + (1 - u2) * node->mob->y_to;
break;
}
}
}
node->mob->speed = initial_speed (omg_param_list[node->type]);
node->event_num++;
distance =
(double) ((int)
(sqrtf (pow (node->mob->x_from - node->mob->x_to, 2) +
pow (node->mob->y_from - node->mob->y_to,
2)) * 100)) / 100;
}
//for the next move
else
{
if (grid == CONNECTED_DOMAIN)
{
pr = randomgen (0, 1);
if (pr <= 0.50)
/* node->block_num =
(int) randomgen (0, omg_param_list[node->type].max_block_num); */
node->block_num =
(int) next_block (node->block_num, omg_param_list[node->type]);
block_xmin =
area_minx (node->block_num, omg_param_list[node->type]);
block_ymin =
area_miny (node->block_num, omg_param_list[node->type]);
node->mob->x_to =
(double) ((int)
(randomgen (block_xmin, xloc_div + block_xmin) * 100)) /
100;
node->mob->y_to =
(double) ((int)
(randomgen (block_ymin, yloc_div + block_ymin) * 100)) /
100;
distance =
(double) ((int) (sqrtf
(pow (node->mob->x_from - node->mob->x_to, 2) +
pow (node->mob->y_from - node->mob->y_to,
2)) * 100)) / 100;
node->mob->azimuth =
atan2 (node->mob->y_to - node->mob->y_from,
node->mob->x_to - node->mob->x_from);
}
else
{
node->mob->x_to =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_x,
omg_param_list[node->type].max_x) * 100)) / 100;
node->mob->y_to =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_y,
omg_param_list[node->type].max_y) * 100)) / 100;
distance =
(double) ((int)
(sqrtf (pow (node->mob->x_from - node->mob->x_to, 2) +
pow (node->mob->y_from - node->mob->y_to,
2)) * 100)) / 100;
}
node->mob->speed =
(double) ((int)
(randomgen
(omg_param_list[node->type].min_speed,
omg_param_list[node->type].max_speed) * 100)) / 100;
node->event_num++;
}
journeytime_next = (double) ((int) (distance / node->mob->speed * 100)) / 100; //duration to get to dest
//LOG_D (OMG, "[STEADY_RWP] mob->journey_time_next %.2f\n", journeyTime_next);
node->mob->start_journey = cur_time;
//LOG_D (OMG, "[STEADY_RWP] start_journey %.2f\n", node->mob->start_journey);
pair->next_event_t = cur_time + journeytime_next; //when to reach the destination
// LOG_D (OMG,
// "[STEADY_RWP] reaching the destination at time : start journey + journey_time next =%.2f\n",
// pair->a);
if (node->event_num < 100)
{
event_sum[node->event_num] += node->mob->speed;
events[node->event_num]++;
node->event_num++;
}
}
double
pause_probability (omg_global_param omg_param)
{
double alpha, delta;
alpha =
(omg_param.max_sleep + omg_param.min_sleep) * (omg_param.max_speed -
omg_param.min_speed) / (2 *
log
(omg_param.
max_speed
/
omg_param.
min_speed));
delta =
sqrtf (pow (omg_param.max_x - omg_param.min_x, 2) +
pow (omg_param.max_y - omg_param.min_y, 2));
return alpha / (alpha + delta);
}
double
initial_pause (omg_global_param omg_param)
{
double u;
u = randomgen (0, 1);
if (u <
(2 * omg_param.min_sleep / (omg_param.max_sleep + omg_param.min_sleep)))
return u * (omg_param.max_sleep + omg_param.min_sleep) / 2;
else
return omg_param.max_sleep -
sqrtf ((1 - u) * (pow (omg_param.max_sleep, 2) -
pow (omg_param.min_sleep, 2)));
}
double
initial_speed (omg_global_param omg_param)
{
double u;
u = randomgen (0, 1);
return pow (omg_param.max_speed, u) / pow (omg_param.min_speed, u - 1);
}
/*update RWP nodes position*/
void
update_steadystaterwp_nodes (double cur_time)
{
int done = 0;
job_list *tmp = job_vector[STEADY_RWP];
node_struct *my_node;
while (tmp != NULL && done == 0)
{
my_node = (node_struct *) tmp->pair->b;
//case1:time to next event equals to current time
if (tmp->pair != NULL
&& ((double) tmp->pair->next_event_t >= cur_time - eps)
&& ((double) tmp->pair->next_event_t <= cur_time + eps))
{
if (my_node->mobile == 1)
sleep_rwp_node (tmp->pair, cur_time);
else
move_rwp_node (tmp->pair, cur_time);
}
//case2: current time is greater than the time to next event
else if (tmp->pair != NULL
&& (cur_time - eps) > tmp->pair->next_event_t)
{
while (cur_time >= tmp->pair->next_event_t)
{
if (my_node->mobile == 1)
sleep_rwp_node (tmp->pair, cur_time);
else
move_rwp_node (tmp->pair, cur_time);
}
}
//case3: current time less than the time to next event
else
{
done = 1; //quit the loop
}
tmp = tmp->next;
}
//sorting the new entries
//LOG_D (OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
// display_job_list (job_vector);
job_vector[STEADY_RWP] = quick_sort (job_vector[STEADY_RWP]); ///////////
// LOG_D (OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
// display_job_list (job_vector[STEADY_RWP]);
}
void
get_steadystaterwp_positions_updated (double cur_time)
{
double x_now = 0.0, y_now = 0.0;
double len, dx, dy;
job_list *tmp = job_vector[STEADY_RWP];
while (tmp != NULL)
{
if (tmp->pair->b->mobile == 1 && tmp->pair->next_event_t >= cur_time)
{
len =
sqrtf (pow
(tmp->pair->b->mob->x_from -
tmp->pair->b->mob->x_to,
2) + pow (tmp->pair->b->mob->y_from -
tmp->pair->b->mob->y_to, 2));
if (len != 0)
{
dx =
fabs (tmp->pair->b->mob->x_from -
tmp->pair->b->mob->x_to) / len;
dy =
fabs (tmp->pair->b->mob->y_from -
tmp->pair->b->mob->y_to) / len;
//x coordinate
if (tmp->pair->b->mob->x_from < tmp->pair->b->mob->x_to)
{
x_now =
tmp->pair->b->mob->x_from +
(dx *
(tmp->pair->b->mob->speed *
(cur_time - tmp->pair->b->mob->start_journey)));
}
else
{
x_now =
tmp->pair->b->mob->x_from -
(dx *
(tmp->pair->b->mob->speed *
(cur_time - tmp->pair->b->mob->start_journey)));
}
//y coordinate
if (tmp->pair->b->mob->y_from < tmp->pair->b->mob->y_to)
{
y_now =
tmp->pair->b->mob->y_from +
(dy *
(tmp->pair->b->mob->speed *
(cur_time - tmp->pair->b->mob->start_journey)));
}
else
{
y_now =
tmp->pair->b->mob->y_from -
(dy *
(tmp->pair->b->mob->speed *
(cur_time - tmp->pair->b->mob->start_journey)));
}
tmp->pair->b->x_pos = (double) ((int) (x_now * 100)) / 100;
tmp->pair->b->y_pos = (double) ((int) (y_now * 100)) / 100;
//len
}
}
else
{
tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
tmp->pair->b->y_pos = tmp->pair->b->mob->y_to;
}
tmp = tmp->next;
}
}
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2011 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fsr/openairinterface
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
*******************************************************************************/
/*! \file steadystaterwp.h
* \brief random waypoint mobility generator
* \date 2014
* \version 0.1
* \company Eurecom
* \email:
* \note
* \warning
*/
#ifndef STEADYSTATERWP_H_
#define STEADYSTATERWP_H_
int start_steadystaterwp_generator (omg_global_param omg_param_list);
void place_steadystaterwp_node (node_struct* node);
void sleep_steadystaterwp_node (pair_struct* pair, double cur_time);
void move_steadystaterwp_node (pair_struct* pair, double cur_time);
double pause_probability(omg_global_param omg_param);
double initial_pause(omg_global_param omg_param);
double initial_speed(omg_global_param omg_param);
void update_steadystaterwp_nodes (double cur_time);
void get_steadystaterwp_positions_updated (double cur_time);
#endif
......@@ -204,12 +204,12 @@ void writeString(char *s){
}
String_list readStringList(String_list vector){
string_list* readStringList(string_list* vector){
int i=0;
int len = readInt();
descLen = len;
String_list entry = NULL;
string_list* entry = NULL;
for (; i < len; i++) {
if (vector->string == NULL) {
......@@ -218,14 +218,14 @@ String_list readStringList(String_list vector){
vector->string = tmp;//readString();
}
else {
entry = (String_list)malloc(sizeof(String_list));
entry = (string_list*) malloc(sizeof(string_list));
char *tmp = readString();
//printf("OMG - SUMO ID: %s \n",tmp);
entry->string = tmp;//readString();
entry->next = NULL;
if(vector !=NULL) {
String_list tmp = vector;
string_list* tmp = vector;
while (tmp->next != NULL){
tmp = tmp->next;
}
......@@ -238,11 +238,11 @@ String_list readStringList(String_list vector){
}
void writeStringList(String_list vector){
void writeStringList(string_list* vector){
int count=0;
String_list tmp = vector;
string_list* tmp = vector;
// JHNote: a better solution would be to save the pointer to the reference of this Int and replace the value with count at the end....
if (tmp->string !=NULL)
count++;
......@@ -463,9 +463,9 @@ void freeStorage(storage * freePtr){
freePtr = NULL; // finally, mark as empty list.
}
void reset_String_list(String_list vector) {
String_list entry = vector;
String_list tmp;
void reset_String_list(string_list* vector) {
string_list* entry = vector;
string_list* tmp;
while (entry->next != NULL) {
tmp = entry;
......
......@@ -58,7 +58,7 @@ union n{
} un ;
void check_endianness();
void check_endianness(void);
//----------------STORAGE------------------------------------
struct Storage {
......@@ -78,36 +78,36 @@ int descLen;
extern int msgLength;
void reset();
void reset(void);
int storageLength(storage *);
void rearange();
unsigned char readChar();
void rearange(void);
unsigned char readChar(void);
void writeChar(unsigned char);
int readByte() ;
int readByte(void) ;
void writeByte(int) ;
int readUnsignedByte();
int readUnsignedByte(void);
void writeUnsignedByte(int);
char * readString() ;
char * readString(void) ;
void writeString(char *);
String_list readStringList(String_list) ;
void writeStringList(String_list);
string_list* readStringList(string_list*) ;
void writeStringList(string_list*);
int readShort() ;
int readShort(void) ;
void writeShort(int);
int readInt() ;
int readInt(void) ;
void writeInt(int);
float readFloat() ;
float readFloat(void) ;
void writeFloat( float );
double readDouble() ;
double readDouble(void) ;
void writeDouble( double );
storage* writePacket(unsigned char*, int);
......
......@@ -52,19 +52,25 @@
#include "client_traci_OMG.h"
int start_sumo_generator(omg_global_param omg_param_list) {
int
start_sumo_generator (omg_global_param omg_param_list)
{
char sumo_line[300];
int n_id;
static int id = 0;
// sprintf(sumo_line, "%s -c %s -b %d -e %d --remote-port %d --step-length %d -v ",omg_param_list.sumo_command, omg_param_list.sumo_config, omg_param_list.sumo_start, omg_param_list.sumo_end, omg_param_list.sumo_port, omg_param_list.sumo_step);
sprintf(sumo_line, "%s -c %s ",omg_param_list.sumo_command, omg_param_list.sumo_config);
sprintf (sumo_line, "%s -c %s ", omg_param_list.sumo_command,
omg_param_list.sumo_config);
printf("%s\n",sumo_line);
if ( (pid = fork()) == 0)
printf ("%s\n", sumo_line);
if ((pid = fork ()) == 0)
{
// Start SUMO in the child process
system(sumo_line);
system (sumo_line);
//childs addresss space
}
......@@ -78,119 +84,141 @@ sprintf(sumo_line, "%s -c %s ",omg_param_list.sumo_command, omg_param_list.sumo_
arrived = NULL;
// switch on error to return to OAI
handshake(omg_param_list.sumo_host,omg_param_list.sumo_port);
handshake (omg_param_list.sumo_host, omg_param_list.sumo_port);
init(omg_param_list.sumo_end - omg_param_list.sumo_start);
init (omg_param_list.sumo_end - omg_param_list.sumo_start);
int max_node_SUMO = 100; //commandGetMaxSUMONodesVariable(); TODO method not implemented in TraCI server..must find another solution
// printf("received Number of nodes %d\n", max_node_SUMO);
// create the OAI/SUMO ID manager
id_manager = create_IDManager();
id_manager = create_IDManager ();
NodePtr node = NULL;
MobilityPtr mobility = NULL;
node_struct *node = NULL;
mobility_struct *mobility = NULL;
active_nodes = NULL; // container to return a subset of only ACTIVE OAI nodes in SUMO
last_update_time = 0.0;
// just check for faulty values
if (omg_param_list.nodes <= 0){
#ifdef STANDALONE
printf("Number of nodes has not been set\n");
#else
LOG_W(OMG, "Number of nodes has not been set\n");
#endif
return(-1);
if (omg_param_list.nodes <= 0)
{
#ifdef STANDALONE
printf ("Number of nodes has not been set\n");
#else
LOG_W (OMG, "Number of nodes has not been set\n");
#endif
return (-1);
}
#ifdef STANDALONE
printf("Number of OAI-equipped nodes in SUMO has been set to %d\n", omg_param_list.nodes);
printf("Number of SUMO simulated nodes has been set to %d\n", max_node_SUMO);
#else
LOG_I(OMG, "Number of OAI-equipped nodes in SUMO has been set to %d\n", omg_param_list.nodes);
LOG_I(OMG, "Number of SUMO simulated nodes has been set to %d\n", max_node_SUMO);
#endif
#ifdef STANDALONE
printf ("Number of OAI-equipped nodes in SUMO has been set to %d\n",
omg_param_list.nodes);
printf ("Number of SUMO simulated nodes has been set to %d\n",
max_node_SUMO);
#else
LOG_I (OMG, "Number of OAI-equipped nodes in SUMO has been set to %d\n",
omg_param_list.nodes);
LOG_I (OMG, "Number of SUMO simulated nodes has been set to %d\n",
max_node_SUMO);
#endif
// check and match number of nodes in mobility file provided
if (omg_param_list.nodes > max_node_SUMO){
#ifdef STANDALONE
printf("Not all OAI nodes will be moving according to SUMO.\n");
#else
LOG_I(OMG, "Not all OAI nodes will be moving according to SUMO.\n");
#endif
if (omg_param_list.nodes > max_node_SUMO)
{
#ifdef STANDALONE
printf ("Not all OAI nodes will be moving according to SUMO.\n");
#else
LOG_I (OMG, "Not all OAI nodes will be moving according to SUMO.\n");
#endif
}
else {
#ifdef STANDALONE
printf("OAI nodes will be mapped to a subset of SUMO nodes\n");
#else
LOG_I(OMG, "OAI nodes will be mapped to a subset of SUMO nodes\n");
#endif
else
{
#ifdef STANDALONE
printf ("OAI nodes will be mapped to a subset of SUMO nodes\n");
#else
LOG_I (OMG, "OAI nodes will be mapped to a subset of SUMO nodes\n");
#endif
}
if (omg_param_list.nodes_type == eNB) {
#ifdef STANDALONE
printf("Node type has been set to eNB\n");
#else
LOG_I(OMG, "Node type has been set to eNB\n");
#endif
if (omg_param_list.nodes_type == eNB)
{
#ifdef STANDALONE
printf ("Node type has been set to eNB\n");
#else
LOG_I (OMG, "Node type has been set to eNB\n");
#endif
}
else if (omg_param_list.nodes_type == UE) {
else if (omg_param_list.nodes_type == UE)
{
#ifdef STANDALONE
printf("Node type has been set to UE\n");
#else
LOG_I(OMG, "Node type has been set to UE\n");
#endif
#ifdef STANDALONE
printf ("Node type has been set to UE\n");
#else
LOG_I (OMG, "Node type has been set to UE\n");
#endif
}
int n_id = 0;
for ( n_id = 0; n_id< omg_param_list.nodes; n_id++) {
for (n_id = id; n_id < omg_param_list.nodes + id; n_id++)
{
node = (NodePtr) create_node();
mobility = (MobilityPtr) create_mobility();
node = create_node ();
mobility = create_mobility ();
node->mobile = 0; // 0 means inactive in SUMO; 1 means active in SUMO; as long as a mapping between OAI-SUMO has not been created, nodes are inactive and do not move
node->ID = n_id; // this is OAI ID, not SUMO
node->id = n_id; // this is OAI ID, not SUMO
node->type = omg_param_list.nodes_type; // UE eNB...
node->generator = omg_param_list.mobility_type; // SUMO
node->generator = SUMO; // SUMO
node->mob = mobility;
Node_Vector[SUMO] = (Node_list) add_entry(node, Node_Vector[SUMO]);
node_vector_end[SUMO] =
(node_list *) add_entry (node, node_vector_end[SUMO]);
if (node_vector[SUMO] == NULL)
node_vector[SUMO] = node_vector_end[SUMO];
}
update_IDs(); // update the mapping between departed and arrived nodes in SUMO.
id += omg_param_list.nodes;
return(0);
}
update_IDs (); // update the mapping between departed and arrived nodes in SUMO.
void update_IDs() {
#ifdef STANDALONE
printf("Updating the ID mapping between SUMO and OAI\n");
#else
LOG_D(OMG, "Updating the ID mapping between SUMO and OAI\n");
#endif
String_list tmp_arrived, tmp_departed;
return (0);
}
if(arrived == NULL) {
printf("arrived vehicles is NULL \n");
void
update_IDs (void)
{
#ifdef STANDALONE
printf ("Updating the ID mapping between SUMO and OAI\n");
#else
LOG_D (OMG, "Updating the ID mapping between SUMO and OAI\n");
#endif
string_list *tmp_arrived, *tmp_departed;
if (arrived == NULL)
{
printf ("arrived vehicles is NULL \n");
return;
}
tmp_arrived = arrived;
tmp_departed = departed;
if(departed == NULL) {
printf("departed vehicles is NULL \n");
if (departed == NULL)
{
printf ("departed vehicles is NULL \n");
return;
}
if(tmp_departed->string !=NULL) {
char * tmp_string = malloc(sizeof(strlen(tmp_departed->string)));
strcpy(tmp_string, tmp_departed->string);
if (tmp_departed->string != NULL)
{
char *tmp_string = malloc (sizeof (strlen (tmp_departed->string)));
strcpy (tmp_string, tmp_departed->string);
//printf("OMG - 2 head is not null and value is: %s\n",tmp_string);
int OAI_ID = get_oaiID_by_SUMO(tmp_string, id_manager);
if (OAI_ID ==-1) {
if (!activate_and_map(tmp_string)) {
int OAI_ID = get_oaiID_by_SUMO (tmp_string, id_manager);
if (OAI_ID == -1)
{
if (!activate_and_map (tmp_string))
{
// printf("Reached the Maximum of OAI nodes to be mapped to SUMO\n");
// LOG_I(OMG, "Reached the Maximum of OAI nodes to be mapped to SUMO\n");
return; // stopping mapping as the maximum of OAI nodes has been reached;
......@@ -198,15 +226,18 @@ void update_IDs() {
}
}
while (tmp_departed->next != NULL) {
while (tmp_departed->next != NULL)
{
// printf("OMG - 2 main is not null \n");
//char tmp_string [strlen(tmp_departed->string)];
char * tmp_string = malloc(sizeof(strlen(tmp_departed->string)));
strcpy(tmp_string, tmp_departed->string);
char *tmp_string = malloc (sizeof (strlen (tmp_departed->string)));
strcpy (tmp_string, tmp_departed->string);
//char *tmp_string = tmp_departed->string;
int OAI_ID = get_oaiID_by_SUMO(tmp_string, id_manager);
if (OAI_ID ==-1) {
if (!activate_and_map(tmp_string)) {
int OAI_ID = get_oaiID_by_SUMO (tmp_string, id_manager);
if (OAI_ID == -1)
{
if (!activate_and_map (tmp_string))
{
//printf("Reached the Maximum of OAI nodes to be mapped to SUMO\n");
//LOG_I(OMG, "Reached the Maximum of OAI nodes to be mapped to SUMO\n");
return; // stopping mapping as the maximum of OAI nodes has been reached;
......@@ -215,109 +246,134 @@ void update_IDs() {
tmp_departed = tmp_departed->next;
}
departed = clear_String_list(departed);
departed = clear_string_list (departed);
if(tmp_arrived->string !=NULL) {
if (tmp_arrived->string != NULL)
{
char *tmp_string = tmp_arrived->string;
//printf("OMG - 3 head is not null and value is: %s\n",tmp_arrived->string);
if(!desactivate_and_unmap(tmp_string)) {
printf("Could not locate the OAI node ID %s \n", tmp_string);
if (!desactivate_and_unmap (tmp_string))
{
printf ("Could not locate the OAI node ID %s \n", tmp_string);
//LOG_I(OMG, "Could not locate the OAI node ID %s \n", tmp_string);
}
}
while (tmp_arrived->next != NULL) {
while (tmp_arrived->next != NULL)
{
char *tmp_string = tmp_arrived->string;
if(!desactivate_and_unmap(tmp_string)) {
printf("Could not locate the OAI node\n");
if (!desactivate_and_unmap (tmp_string))
{
printf ("Could not locate the OAI node\n");
// LOG_I(OMG, "Could not locate the OAI node\n");
}
tmp_arrived = tmp_arrived->next;
}
arrived = clear_String_list(arrived);
arrived = clear_string_list (arrived);
}
bool desactivate_and_unmap(char *sumo_id) {
#ifdef STANDALONE
printf("desactivating node %s \n",sumo_id);
#else
LOG_I(OMG, "desactivating node %s \n",sumo_id);
#endif
int OAI_ID = get_oaiID_by_SUMO(sumo_id, id_manager);
remove_oaiID_by_SUMO(sumo_id, id_manager);
if (OAI_ID !=-1) {
bool
desactivate_and_unmap (char *sumo_id)
{
#ifdef STANDALONE
printf ("desactivating node %s \n", sumo_id);
#else
LOG_I (OMG, "desactivating node %s \n", sumo_id);
#endif
int OAI_ID = get_oaiID_by_SUMO (sumo_id, id_manager);
remove_oaiID_by_SUMO (sumo_id, id_manager);
if (OAI_ID != -1)
{
//TODO generalize to UE and eNB (must change the method)
NodePtr node = find_node(Node_Vector[SUMO], OAI_ID, UE);
node_struct *node = find_node (node_vector[SUMO], OAI_ID, UE);
if (node == NULL)
node = find_node(Node_Vector[SUMO], OAI_ID, eNB);
node = find_node (node_vector[SUMO], OAI_ID, eNB);
if(node !=NULL) {
if (node != NULL)
{
node->mobile = 0; // this node is now inactive;
active_nodes = remove_node_entry(node, active_nodes);
active_nodes = remove_node_entry (node, active_nodes);
return true;
}
}
#ifdef STANDALONE
printf("Could not desactive an OAI node, as the SUMO-OAI mapping could not be found for the SUMO node ID %s \n", sumo_id);
#else
LOG_I(OMG, "Could not desactive an OAI node, as the SUMO-OAI mapping could not be found for the SUMO node ID %s \n", sumo_id);
#endif
#ifdef STANDALONE
printf
("Could not desactive an OAI node, as the SUMO-OAI mapping could not be found for the SUMO node ID %s \n",
sumo_id);
#else
LOG_I (OMG,
"Could not desactive an OAI node, as the SUMO-OAI mapping could not be found for the SUMO node ID %s \n",
sumo_id);
#endif
return false;
}
bool activate_and_map(char *sumo_id) {
MapPtr map = create_map();
#ifdef STANDALONE
printf("activating node %s \n",sumo_id);
#else
LOG_I(OMG, "activating node %s \n",sumo_id);
#endif
bool
activate_and_map (char *sumo_id)
{
MapPtr map = create_map ();
#ifdef STANDALONE
printf ("activating node %s \n", sumo_id);
#else
LOG_I (OMG, "activating node %s \n", sumo_id);
#endif
// TODO: So far, only UE can be SUMO mobile, but could change
NodePtr active_node = get_first_inactive_OAI_node(Node_Vector[SUMO], UE);
if(active_node != NULL) { // found an inactive OAI node; will be mapped to SUMO
node_struct *active_node =
get_first_inactive_OAI_node (node_vector[SUMO], UE);
if (active_node != NULL)
{ // found an inactive OAI node; will be mapped to SUMO
active_node->mobile = 1; // now node is active in SUMO
active_nodes = add_entry(active_node, active_nodes);
active_nodes = add_entry (active_node, active_nodes);
map->oai_id = active_node->ID;
map->sumo_id = malloc(sizeof((int)strlen(sumo_id)));
strcpy(map->sumo_id, sumo_id);
map->oai_id = active_node->id;
map->sumo_id = malloc (sizeof ((int) strlen (sumo_id)));
strcpy (map->sumo_id, sumo_id);
#ifdef STANDALONE
printf("added a mapping between oai ID: %d and SUMO ID: %s \n",map->oai_id, map->sumo_id);
#else
LOG_I(OMG, "added a mapping between oai ID: %d and SUMO ID: %s \n",map->oai_id, map->sumo_id);
#endif
#ifdef STANDALONE
printf ("added a mapping between oai ID: %d and SUMO ID: %s \n",
map->oai_id, map->sumo_id);
#else
LOG_I (OMG, "added a mapping between oai ID: %d and SUMO ID: %s \n",
map->oai_id, map->sumo_id);
#endif
// TODO fusion the two lists...leads to data inconsistency
id_manager->map_sumo2oai = add_map_entry(map, id_manager->map_sumo2oai);
id_manager->map_sumo2oai =
add_map_entry (map, id_manager->map_sumo2oai);
id_manager->map_oai2sumo = add_map_entry(map, id_manager->map_oai2sumo); //map_sumo2oai
id_manager->map_oai2sumo = add_map_entry (map, id_manager->map_oai2sumo); //map_sumo2oai
return true;
}
else {
#ifdef STANDALONE
printf("All OAI Nodes are already active in SUMO; cannot control this SUMO node in OAI\n");
#else
LOG_I(OMG, "All OAI Nodes are already active in SUMO; cannot control this SUMO node in OAI\n");
#endif
else
{
#ifdef STANDALONE
printf
("All OAI Nodes are already active in SUMO; cannot control this SUMO node in OAI\n");
#else
LOG_I (OMG,
"All OAI Nodes are already active in SUMO; cannot control this SUMO node in OAI\n");
#endif
return false;
}
}
void update_sumo_nodes(double cur_time) {
if((cur_time - last_update_time) < MIN_SUMO_STEP) { // the min time interval for SUMO must be 100ms or more
printf("--------Update Step too small--------\n");
void
update_sumo_nodes (double cur_time)
{
if ((cur_time - last_update_time) < MIN_SUMO_STEP)
{ // the min time interval for SUMO must be 100ms or more
printf ("--------Update Step too small--------\n");
return;
}
......@@ -326,57 +382,73 @@ void update_sumo_nodes(double cur_time) {
// commandSimulationStep(1.0);// Advance the SUMO simulation by cur_time units
commandSimulationStep(cur_time);// Advance the SUMO simulation by cur_time units
commandSimulationStep (cur_time); // Advance the SUMO simulation by cur_time units
LOG_I(OMG, "--------Updated SUMO positions by %f [ms]--------\n",cur_time);
update_IDs(); // both are in the traCI client
LOG_I (OMG, "--------Updated SUMO positions by %f [ms]--------\n",
cur_time);
update_IDs (); // both are in the traCI client
}
void update_sumo_positions(NodePtr node){
void
update_sumo_positions (node_struct * node)
{
#ifdef STANDALONE
printf("--------GET SUMO Mobility for a single node--------\n");
#else
LOG_D(OMG, "--------GET SUMO Mobility for a single node--------\n");
#endif
#ifdef STANDALONE
printf ("--------GET SUMO Mobility for a single node--------\n");
#else
LOG_D (OMG, "--------GET SUMO Mobility for a single node--------\n");
#endif
Map_list tmp = id_manager->map_oai2sumo;
char *sumo_id = get_sumo_entry(node->ID, tmp);
char *sumo_id = get_sumo_entry (node->id, tmp);
if(sumo_id !=NULL) {
if (sumo_id != NULL)
{
//printf(" OAI ID is: %d and SUMO ID is %s \n",node->ID, sumo_id);
GetPosition(node, sumo_id);
GetSpeed(node, sumo_id);
GetPosition (node, sumo_id);
GetSpeed (node, sumo_id);
}
}
Node_list get_sumo_positions_updated(double cur_time) {
node_list *
get_sumo_positions_updated (double cur_time)
{
#ifdef STANDALONE
printf("--------GET SUMO Mobility for a group of ACTIVE OAI nodes--------\n");
#else
LOG_I(OMG, "--------GET SUMO Mobility for a group of ACTIVE OAI nodes--------\n");
#endif
#ifdef STANDALONE
printf
("--------GET SUMO Mobility for a group of ACTIVE OAI nodes--------\n");
#else
LOG_I (OMG,
"--------GET SUMO Mobility for a group of ACTIVE OAI nodes--------\n");
#endif
if (Node_Vector[SUMO] != NULL){
Node_list tmp = Node_Vector[SUMO];
while (tmp != NULL){
if ((tmp->node->generator == SUMO) && (tmp->node->mobile == 1)) { // OAI node MUST be active
LOG_I(OMG, "found an active node with id %d \n", tmp->node->ID);
LOG_I(OMG, "Old Positions \n");
if (node_vector[SUMO] != NULL)
{
node_list *tmp = node_vector[SUMO];
while (tmp != NULL)
{
if ((tmp->node->generator == SUMO) && (tmp->node->mobile == 1))
{ // OAI node MUST be active
LOG_I (OMG, "found an active node with id %d \n",
tmp->node->id);
LOG_I (OMG, "Old Positions \n");
//printf("Old Positions \n");
display_node_position(tmp->node->ID, tmp->node->generator, tmp->node->type ,tmp->node->mobile, tmp->node->X_pos, tmp->node->Y_pos );
display_node_position (tmp->node->id, tmp->node->generator,
tmp->node->type, tmp->node->mobile,
tmp->node->x_pos, tmp->node->y_pos);
update_sumo_positions(tmp->node);
update_sumo_positions (tmp->node);
//printf("New Positions \n");
LOG_I(OMG, "New Positions \n");
display_node_position(tmp->node->ID, tmp->node->generator, tmp->node->type ,tmp->node->mobile, tmp->node->X_pos, tmp->node->Y_pos );
LOG_I (OMG, "New Positions \n");
display_node_position (tmp->node->id, tmp->node->generator,
tmp->node->type, tmp->node->mobile,
tmp->node->x_pos, tmp->node->y_pos);
}
tmp = tmp->next;
}
......@@ -384,13 +456,19 @@ Node_list get_sumo_positions_updated(double cur_time) {
return active_nodes;
}
NodePtr get_first_inactive_OAI_node(Node_list list, int node_type) {
Node_list current;
node_struct *
get_first_inactive_OAI_node (node_list * list, int node_type)
{
node_list *current;
if (list !=NULL) { //start search
if (list != NULL)
{ //start search
current = list;
while (current->next != NULL) {
if((current->node->mobile == 0) && (current->node->type == node_type)) {
while (current->next != NULL)
{
if ((current->node->mobile == 0)
&& (current->node->type == node_type))
{
return current->node;
}
current = current->next;
......@@ -399,14 +477,18 @@ NodePtr get_first_inactive_OAI_node(Node_list list, int node_type) {
return NULL; // all nodes are active already..reached the maximum number of OAI nodes
}
bool stop_sumo_generator() {
#ifdef STANDALONE
printf(" --------Destructor for SUMO: closing the TraCI socket and killing SUMO ---- \n");
#else
LOG_I(OMG, " --------Destructor for SUMO: closing the TraCI socket and killing SUMO ---- \n");
#endif
commandClose(); // closing the connection with SUMO via TraCI
close_connection(); // closing the socket connection
kill(pid,SIGKILL); // killing SUMO in case it could not close by itself
bool
stop_sumo_generator (void)
{
#ifdef STANDALONE
printf
(" --------Destructor for SUMO: closing the TraCI socket and killing SUMO ---- \n");
#else
LOG_I (OMG,
" --------Destructor for SUMO: closing the TraCI socket and killing SUMO ---- \n");
#endif
commandClose (); // closing the connection with SUMO via TraCI
close_connection (); // closing the socket connection
kill (pid, SIGKILL); // killing SUMO in case it could not close by itself
return true;
}
......@@ -50,11 +50,11 @@
/*! A global variable used to store the SUMO process ID to later kill it smoothly when OAI askes OMG to stop SUMO*/
pid_t pid;
/*! A sumo global variable representing the OMG-SUMO ID manager. It is created at the start_sumo_generator() and keep a mapping between SUMO and OAI IDs. */
/*! A sumo global variable representing the OMG-SUMO ID manager. It is created at the start_sumo_generator(void) and keep a mapping between SUMO and OAI IDs. */
IDManagerPtr id_manager;
/*! A Node_list intended to contain the list of OAI 'active' nodes in SUMO. replaces the return of the full Node_Vector when OAI requests the new positions of its nodes. The list is reset at each use, but the pointer to the respective nodes is just set to NULL*/
Node_list active_nodes;
node_list* active_nodes;
/*! A global variable keeping track of the last update time of SUMO, to be used to get the update interval when update_sumo_nodes(cur_time) is called */
double last_update_time;
......@@ -79,7 +79,7 @@ void update_sumo_nodes(double cur_time) ;
* \brief Get the current position and speed of a node from SUMO. Invokes TraCI
* \param node the pointer to a node we want to synch with SUMO.
*/
void update_sumo_positions(NodePtr node);
void update_sumo_positions(node_struct* node);
/**
* \fn Node_list get_sumo_positions_updated(double cur_time);
......@@ -87,7 +87,7 @@ void update_sumo_positions(NodePtr node);
* \param cur_time a variable of type double that represents the current time
* \return the list of ACTIVE OAI nodes, which positions have been updated by SUMO
*/
Node_list get_sumo_positions_updated(double cur_time);
node_list* get_sumo_positions_updated(double cur_time);
/**
* \fn NodePtr get_first_inactive_OAI_node(Node_list list, int node_type)
......@@ -96,13 +96,13 @@ Node_list get_sumo_positions_updated(double cur_time);
* \param node_type the type of node we would like to locate (here: SUMO)
* \return the reference to the first inactive OAI node; returns NULL is none could be found (all OAI nodes are currently active)
*/
NodePtr get_first_inactive_OAI_node(Node_list list, int node_type);
node_struct* get_first_inactive_OAI_node(node_list* list, int node_type);
/**
* \fn void update_IDs(String_list *departed, String_list *arrived)
* \brief Updates the mapping between SUMO and OAI nodes; Once a node departs in SUMO, it is mapped to a inactive OAI node. If none are found, the SUMO node will not have any mapping. Once a node arrives, the mapping is removed and the OAI node becomes inactive again. When an OAI node is inactive, it mobility parameters are invalid and MUST NOT be used/requested by OAI.
*/
void update_IDs();
void update_IDs(void);
/**
* \fn bool desactive_and_unmap(char *sumo_id)
......@@ -122,10 +122,10 @@ bool desactivate_and_unmap(char *sumo_id);
bool activate_and_map(char *sumo_id);
/**
* \fn int stop_sumo_generator()
* \fn int stop_sumo_generator(void)
* \brief stops SUMO, stop the socket and kills SUMO process in the child domain.
* \return true in case of success; false otherwise
*/
bool stop_sumo_generator();
bool stop_sumo_generator(void);
#endif /* SUMO_H_ */
......@@ -29,11 +29,11 @@
/*! \file trace.c
* \brief The trace-based mobility model for OMG/OAI (mobility is statically imported from a file)
* \author S. Uppoor and Navid Nikaein
* \date 2011
* \author S. Gashaw, N. Nikaein, J. Harri
* \date 2014
* \version 0.1
* \company INRIA
* \email: sandesh.uppoor@inria.fr
* \company EURECOM
* \email:
* \note
* \warning
*/
......@@ -43,441 +43,513 @@
#include <time.h>
#include <math.h>
#include "trace.h"
#include "omg.h"
#define FIXED 1
#define MOVING 0
extern node_info* head_node_info;
extern hash_table_t* table;
extern hash_table_t **table;
extern node_info **list_head;
//check if the next input data is the same as the previous
int start_trace_generator(omg_global_param omg_param_list) {
// MobilityPtr mobility = NULL;
//read the mobility file here
read_mobility_file(omg_param_list.mobility_file); // JHNOTE: in order to debug, please give and change name here...
LOG_I(OMG, "mobility file %s put in the table %p\n",omg_param_list.mobility_file, table );
int
start_trace_generator (omg_global_param omg_param_list)
{
double cur_time = 0.0;
int immobile = 0;
int node_number;
node_struct *node = NULL;
mobility_struct *mobility = NULL;
pair_struct *pair = NULL;
node_info *temp;
sort_veh_movement(table);
parse_data (omg_param_list.mobility_file, omg_param_list.nodes_type); //read mobility file
if (omg_param_list.nodes <= 0){
LOG_W(OMG, "Number of nodes has not been set\n");
return(-1);
}
//LOG_I (OMG, "mobility file %s put in the table %p\n",omg_param_list.mobility_file, table);
// check and match number of nodes in mobility file provided
if (omg_param_list.nodes != get_num_nodes()){
LOG_W(OMG, "Make sure all nodes have mobility description in mobility file (%d,%d)\n",
omg_param_list.nodes, get_num_nodes());
//return(-1);
}
node_number = get_number_of_nodes (omg_param_list.nodes_type);
if (omg_param_list.nodes_type == eNB) {
LOG_I(OMG, "Start trace driven mobility gen for %d eNBs\n",omg_param_list.nodes);
} else if (omg_param_list.nodes_type == UE) {
LOG_I(OMG, "Start trace driven mobility gen for %d UEs\n",omg_param_list.nodes);
}
if (node_number == 0)
LOG_E (OMG, "[TRACE] empty input file \n");
LOG_I (OMG, "TRACE mobility model for %d %d nodes\n", node_number,
omg_param_list.nodes_type);
temp = list_head[omg_param_list.nodes_type];
while (temp != NULL)
{
node_data *this_node =
get_next_data (table[omg_param_list.nodes_type], temp->g_id, DATA_AND_STATUS_CHANGE);
deploy_nodes();
return(0);
if (this_node == NULL)
{
LOG_E (OMG, "[TRACE] Unexpected empty data entry\n");
exit (-1);
}
int deploy_nodes() {
NodePtr node = NULL;
node = create_node ();
mobility = create_mobility ();
node->id = temp->vid;
node->gid = temp->g_id;
// int count = 0;
node_info * head_node = head_node_info;
while (head_node!=NULL){
/* if(this_node->type == -1) //if node type is given in the file set the defualt type UE
node->type = UE; */
node->type = omg_param_list.nodes_type;
node->generator = TRACE;
node->mob = mobility;
//if (count<omg_param_list.nodes){
create_trace_node(node,head_node);
//count++;
head_node=head_node->next;
//}else
// break;
place_trace_node (node, this_node); //initial positions
}
//if (count!=omg_param_list.nodes)
// create_trace_node(node,head_node);
return(0);
}
int create_trace_node(NodePtr node,node_info *head_node){
if (this_node->visit == 1)
{
double cur_time = 0.0;
MobilityPtr mobility = NULL;
node = (NodePtr) create_node();
mobility = (MobilityPtr) create_mobility();
node->mobile = 0; // static for the moment
node->ID = head_node->vid;
node->type = omg_param_list.nodes_type; // UE eNB
node->generator = omg_param_list.mobility_type; // STATIC, RWP...
node->mob = mobility;
pair = (pair_struct *) malloc (sizeof (struct pair_struct));
pair->b = node;
place_trace_node(node); //initial positions
if (this_node->time > cur_time)
{
schedule_trace_node (pair, this_node, cur_time);
}
else
{
if (this_node->x_pos == this_node->next->x_pos &&
this_node->y_pos == this_node->next->y_pos)
Pair pair = malloc (sizeof(Pair));
Exnode* next_loc=NULL;
next_loc=get_next_position(table,node->ID);
sleep_trace_node (pair, this_node, cur_time);
// put to awake node is initial position is given if not till the next given time
if (next_loc->time == 0)
pair = keep_awake_trace_node(node,cur_time,(0.11-eps),1);
else
pair = keep_awake_trace_node(node,cur_time,(next_loc->time-cur_time),1);
//just to fetch the target time and speed
next_loc=NULL;
next_loc=get_next_position(table,node->ID);
if (next_loc != NULL){
node->mob->target_time=next_loc->time;
node->mob->target_speed=next_loc->speed;
reset_visit_status(table,next_loc->time,node->ID);
LOG_D(OMG, "reset %d \n",node->ID);
}else{ // if only few discriptions are available
node->mob->target_time=9999.0;
node->mob->target_speed=0.0;
move_trace_node (pair, this_node, cur_time); //move
}
Job_Vector = add_job(pair, Job_Vector);
Job_Vector_len ++;
//LOG_I (OMG,
//"[TRACE] position of node ID: %d %d\n ",node->id, node->type);
}
else
{
temp = temp->next;
continue;
}
if (Job_Vector == NULL)
LOG_E(OMG, "Job Vector is NULL\n");
return 0;
}
job_vector_end[TRACE] = add_job (pair, job_vector_end[TRACE]);
void place_trace_node(NodePtr node) {
Exnode* next_loc=NULL ;
next_loc=get_next_position(table,node->ID);
if (job_vector[TRACE] == NULL)
job_vector[TRACE] = job_vector_end[TRACE];
node->X_pos = next_loc->x;
node->mob->X_from = node->X_pos;
node->mob->X_to = node->X_pos;
node->Y_pos = next_loc->y;
node->mob->Y_from = node->Y_pos;
node->mob->Y_to = node->Y_pos;
job_vector_len[TRACE]++;
node->mob->speed = next_loc->speed;
node->mob->journey_time = 0.0;
reset_visit_status(table,next_loc->time,node->ID);
temp = temp->next;
}
LOG_D(OMG,"--------INITIALIZE TRACE NODE-------- \n ");
LOG_I(OMG,"Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = %d\n ", node->ID, node->type, node->X_pos, node->Y_pos, node->mob->speed);
Node_Vector[TRACE] = (Node_list) add_entry(node, Node_Vector[TRACE]);
Node_Vector_len[TRACE]++;
if (job_vector[TRACE] == NULL)
LOG_I (OMG, "[TRACE] Job Vector is NULL\n");
return 0;
}
// [NO MORE USED] sleep just after creation and after mobility description is over
Pair sleep_trace_node(NodePtr node, double cur_time,float sleep_duration){
void
place_trace_node (node_struct * node, node_data * n)
{
node_data *n_ptr = n;
node->x_pos = (double) n_ptr->x_pos;
node->mob->x_from = node->x_pos;
node->mob->x_to = node->x_pos;
node->mobile = 0;
node->mob->speed = 0.0;
node->mob->X_from = node->mob->X_to;
node->mob->Y_from = node->mob->Y_to;
node->X_pos = node->mob->X_to;
node->Y_pos = node->mob->Y_to;
Pair pair = malloc(sizeof(Pair)) ;
node->y_pos = (double) n_ptr->y_pos;
node->mob->y_from = node->y_pos;
node->mob->y_to = node->y_pos;
node->mob->sleep_duration = sleep_duration ;
LOG_D(OMG, "node: %d \tsleep duration : %.2f\n",node->ID, node->mob->sleep_duration);
node->mob->speed = n_ptr->speed;
node->mob->journey_time = 0.0;
// node->start_journey=(double) n_ptr->time; //time of initial position
// node->mob->target_time=(double) n_ptr->next->time; //time of next destination
LOG_I (OMG,
"[TRACE] Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = %.2f \n ",
node->id, node->type, node->x_pos, node->y_pos, node->mob->speed);
node->mob->start_journey = cur_time;
node_vector_end[node->type] =
(node_list *) add_entry (node, node_vector_end[node->type]);
pair->a =(node->mob->start_journey + node->mob->sleep_duration);
if (node_vector[node->type] == NULL)
node_vector[node->type] = node_vector_end[node->type];
LOG_D(OMG, "to wake up at time: cur_time %f + sleep_duration : %.2f\n", cur_time,pair->a);
pair->b = node;
node_vector_len[node->type]++;
return pair;
}
Pair keep_awake_trace_node(NodePtr node, double cur_time,float duration,int jump){
void
move_trace_node (pair_struct * pair, node_data * n_data, double cur_time)
{
node_struct *node;
node = pair->b;
double cdistance, journeytime, speed;
double journeytime_next, distance;
node->mob->x_from = node->mob->x_to;
node->mob->y_from = node->mob->y_to;
node->mobile = 1;
node->mob->speed = n_data->speed;
node->mob->x_to = (double) n_data->next->x_pos;
node->mob->y_to = (double) n_data->next->y_pos;
node->mob->target_time = (double) n_data->next->time;
node->mob->speed = 0.0;
//if speed equals to zero compute the speed(i.e node was on sleep move it)
if (node->mob->speed == 0)
{
cdistance =
(double)
sqrtf
(pow (node->mob->x_from - node->mob->x_to, 2) +
pow (node->mob->y_from - node->mob->y_to, 2));
journeytime = node->mob->target_time - n_data->time;
speed = (double) cdistance / journeytime;
node->mob->speed = speed;
}
distance =
(double)
sqrtf
(pow (node->mob->x_from - node->mob->x_to, 2) +
pow (node->mob->y_from - node->mob->y_to, 2));
journeytime_next = (double) distance / node->mob->speed; //time to get to destination
/* LOG_D (OMG,
"[TRACE] mob->journey_time_next %.2f target time %.2f next time %.2f speed %.2f\n",
journeytime_next, node->mob->target_time, n_data->time,
node->mob->speed);*/
// jump is used to displace node to strictly follow mobility discription
if (jump== 1){
node->X_pos = node->mob->X_to;
node->Y_pos = node->mob->Y_to;
}else{
node->mob->X_to = node->X_pos;
node->mob->Y_to = node->Y_pos;
}
node->mob->X_from = node->mob->X_to;
node->mob->Y_from = node->mob->Y_to;
Pair pair = malloc(sizeof(Pair)) ;
LOG_D(OMG, "Node: %d \tawake duration : %.2f\n",node->ID, duration);
node->mob->start_journey = cur_time;
pair->next_event_t = cur_time + journeytime_next; //when to reach the destination
//node->mob->target_time= 9999.;
pair->a = node->mob->start_journey + duration;
LOG_D(OMG, "To start up at time: cur_time + awake_duration : %.2f\n", pair->a);
pair->b = node;
LOG_D(OMG, "Current Position in awake : (%.2f, %.2f)\n", node->mob->X_from, node->mob->Y_from);
return pair;
}
void
schedule_trace_node (pair_struct * pair, node_data * n_data, double cur_time)
{
node_struct *node = pair->b;
node->mobile = 3;
node->mob->start_journey = cur_time;
pair->next_event_t = n_data->time; //when to move this node
//LOG_D (OMG, "[TRACE] Node will wake up at time: %.2f\n", pair->next_event_t);
}
Pair move_trace_node(NodePtr node, double cur_time) {
Exnode* next_loc=NULL;
next_loc=get_next_position(table,node->ID);
void
sleep_trace_node (pair_struct * pair, node_data * n_data, double cur_time)
{
double journeytime, distance;
node_struct *node = pair->b;
node->mobile = 0;
node->mob->speed = 0.0;
node->mob->x_from = node->mob->x_to;
node->mob->y_from = node->mob->y_to;
node->x_pos = node->mob->x_to;
node->y_pos = node->mob->y_to;
//sleep duration
if (n_data->x_pos == n_data->next->x_pos &&
n_data->y_pos == n_data->next->y_pos)
{
node->mob->sleep_duration = n_data->next->time - n_data->time;
if (next_loc==NULL) {//Option 1 : no job, I am awake
LOG_D(OMG, "NULL detected\n");
return keep_awake_trace_node(node,cur_time,9999,1);
}
else{ // location discription available
// Job_list tmp1 = Job_Vector;
LOG_D(OMG, "Location fetch : (%.2f, %.2f)\n", next_loc->x, next_loc->y);
else
{ //sleep case 2
node->mob->target_time - (journeytime + node->mob->start_journey);
double X_next;
double Y_next;
double journeyTime_next;
}
// This was used to remove duplicate entries, vehicle stays in the same position
//while((next_loc->x==tmp1->pair->b->mob->X_to && next_loc->y==tmp1->pair->b->mob->Y_to) )//|| next_loc->speed==0)
// next_loc=get_next_position(table,node->ID);
node->mob->start_journey = cur_time;
pair->next_event_t = cur_time + node->mob->sleep_duration; //when to wake up
/*LOG_D (OMG, "#[TRACE] node: %d \tsleep duration : %.2f\n", node->id,
node->mob->sleep_duration);*/
//Trace defined time varies with current time so keep the node awake till the next trip discription time.
if (( node->mob->target_time - cur_time) >= eps && node->mob->speed !=0.0){
reset_visit_status(table,next_loc->time,node->ID);
float awake_duration=(node->mob->target_time-cur_time);
return keep_awake_trace_node(node,cur_time,awake_duration,1);
}
void
update_trace_nodes (double cur_time)
{
job_list *tmp;
int done = 0;
node_data *node_n;
node_struct *my_node;
tmp = job_vector[TRACE];
if (tmp == NULL)
LOG_D (OMG, "[TRACE] last data for all nodes\n");
while (tmp != NULL && done != 1)
{ //1
my_node = tmp->pair->b;
node_n = get_next_data (table[my_node->type], my_node->gid, DATA_ONLY);
if (node_n->next->next == NULL)
{
tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
tmp->pair->b->mob->x_from = tmp->pair->b->x_pos;
tmp->pair->b->y_pos = tmp->pair->b->mob->y_to;
tmp->pair->b->mob->y_from = tmp->pair->b->y_pos;
tmp->pair->b->mobile = 0;
tmp->pair->b->mob->speed = 0.0;
// LOG_D (OMG, "[TRACE] last data for all nodes\n");
tmp = tmp->next;
continue;
}
Pair pair = malloc(sizeof(Pair));
LOG_D(OMG, "MOVE TRACE NODE\n");
LOG_D(OMG, "node: %d\n",node->ID );
node->mob->X_from = node->X_pos;
node->mob->Y_from = node->Y_pos;
LOG_D(OMG, "Current Position: (%.2f, %.2f)\n", node->mob->X_from, node->mob->Y_from);
if (!(next_loc->x==node->X_pos && next_loc->y==node->Y_pos) && (next_loc->speed==0. && node->mob->speed==0.0) ){
node->mob->X_to = node->X_pos;
node->mob->Y_to = node->Y_pos;
node->mob->speed = next_loc->speed;
journeyTime_next = next_loc->time-cur_time;
reset_visit_status(table,next_loc->time,node->ID);
LOG_D(OMG, "Location fetch reset: (%.2f, %.2f)\n", next_loc->x, next_loc->y);
}else{
X_next = next_loc->x;
node->mob->X_to = X_next;
Y_next = next_loc->y;
node->mob->Y_to = Y_next;
LOG_I(OMG, "destination: (%.2f, %.2f)\n", node->mob->X_to, node->mob->Y_to);
double target_time;
target_time = next_loc->time;
node->mob->target_time= target_time;
//case1:time to next event equals to current time
if (tmp->pair != NULL && tmp->pair->next_event_t >= cur_time - eps
&& tmp->pair->next_event_t <= cur_time + eps)
{
//LOG_D (OMG, "[TRACE] last data for all nodes\n");
if (my_node->mobile == 1)
{
if (my_node->mob->target_time > tmp->pair->next_event_t) //sleep node
{
sleep_trace_node (tmp->pair, node_n, cur_time);
}
else
{
node_n =
get_next_data (table[my_node->type], my_node->gid,
DATA_AND_STATUS_CHANGE);
double speed_next;
speed_next = next_loc->speed;
node->mob->speed = speed_next;
LOG_D(OMG, "speed_next %.2f\n", speed_next); //m/s
if (node_n->x_pos == node_n->next->x_pos &&
node_n->y_pos == node_n->next->y_pos)
double distance = (double) ((int)(sqrtf(pow(node->mob->X_from - X_next, 2) + pow(node->mob->Y_from - Y_next, 2))*100))/ 100;
LOG_D(OMG, "distance %.2f\n", distance); //m
sleep_trace_node (tmp->pair, node_n, cur_time);
else
move_trace_node (tmp->pair, node_n, cur_time);
}
LOG_D(OMG,"next_loc->time %f",next_loc->time);
}
else if (my_node->mobile == 0)
{
node_n =
get_next_data (table[my_node->type], my_node->gid, DATA_AND_STATUS_CHANGE);
journeyTime_next = (double) ((int)(distance/speed_next*100))/ 100;
} //duration to get to dest ;
if (node_n->x_pos == node_n->next->x_pos &&
node_n->y_pos == node_n->next->y_pos)
node->mobile = 1;
LOG_D(OMG, "mob->journey_time_next %.2f\n",journeyTime_next );
sleep_trace_node (tmp->pair, node_n, cur_time);
node->mob->start_journey = cur_time;
LOG_D(OMG, "start_journey %.2f\n", node->mob->start_journey );
else
move_trace_node (tmp->pair, node_n, cur_time);
pair->a = node->mob->start_journey + journeyTime_next; //when to reach the destination
LOG_D(OMG, "when to reach the destination: pair->a= start journey + journey_time next =%.2f\n", pair->a);
}
else
{
node_n = get_next_data (table[my_node->type], my_node->gid, DATA_ONLY);
if (node_n->x_pos == node_n->next->x_pos &&
node_n->y_pos == node_n->next->y_pos)
pair->b = node;
sleep_trace_node (tmp->pair, node_n, cur_time);
else
move_trace_node (tmp->pair, node_n, cur_time);
return pair;
}
}
void update_trace_nodes(double cur_time) {
LOG_D(OMG, "--------UPDATE--------\n");
Job_list tmp = Job_Vector;
int done = 0; //
}
display_job_list(Job_Vector);
while ((tmp != NULL) && (done == 0)){
// if (tmp->pair == NULL){LOG_E(OMG, "UPDATE TRACE : tmp->pair ==NULL\n" );}
// if (tmp->pair != NULL){LOG_E(OMG, "UPDATE TRACE : tmp->pair !=NULL\n" );}
LOG_D(OMG, "cur_time %f\n", cur_time );
LOG_D(OMG, "tmp->pair->a %f %f %f\n", tmp->pair->a , cur_time - eps,cur_time + eps);
//case2: current time is greater than the time to next event
else if (tmp->pair != NULL && cur_time - eps > tmp->pair->next_event_t)
{
while (cur_time >= tmp->pair->next_event_t)
{
if((tmp->pair !=NULL) && ( (double)tmp->pair->a >= cur_time - eps) && ( (double)tmp->pair->a <= cur_time + eps) ) {
if (tmp->pair->b->generator == TRACE){
LOG_D(OMG, " (first_job_time) %.2f == %.2f (cur_time) \n ",tmp->pair->a, cur_time );
// update to a new location
/*if((tmp->pair->b->mob->speed == 0.0) && (tmp->pair->b->mobile == 1) && (tmp->pair->b->mob->target_speed==0.0)){
Exnode* next_loc=NULL;
if (node_n->next->next == NULL)
{
tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
tmp->pair->b->mob->x_from = tmp->pair->b->x_pos;
tmp->pair->b->y_pos = tmp->pair->b->mob->y_to;
tmp->pair->b->mob->y_from = tmp->pair->b->y_pos;
break;
}
next_loc=get_next_position(table,tmp->pair->b->ID);
if (next_loc !=NULL){
tmp->pair->b->X_pos = next_loc->x ;
tmp->pair->b->Y_pos = next_loc->y ;
if (my_node->mobile == 1)
{
if (my_node->mob->target_time > tmp->pair->next_event_t) //sleep node
{
sleep_trace_node (tmp->pair, node_n, cur_time);
}
} */
LOG_D(OMG, " UPDATE TRACE \n ");
NodePtr my_node = (NodePtr)tmp->pair->b;
else
{
node_n =
get_next_data (table[my_node->type], my_node->gid,
DATA_AND_STATUS_CHANGE);
if (my_node->mobile == 1 || my_node->mobile == 0) { //only move no stop , put to sleep in move_trace_node() only for disconnected mobility
LOG_D(OMG, " node %d ready to move to next destination \n", my_node->ID);
//my_node->mobile = 1;
Pair pair = malloc(sizeof(Pair));
pair = move_trace_node(my_node, cur_time);
if (node_n->x_pos == node_n->next->x_pos &&
node_n->y_pos == node_n->next->y_pos)
tmp->pair = pair;
tmp = tmp->next;
}
else{
LOG_E(OMG, "update_generator: unsupported node state - mobile : %d \n", my_node->mobile);
exit(-1);
}
}
else {
LOG_D(OMG, " (first_job_time) %.2f == %.2f(cur_time) but (generator=%d) != (TRACE=%d)\n ",tmp->pair->a, cur_time, tmp->pair->b->generator, TRACE );
tmp = tmp->next;
}
sleep_trace_node (tmp->pair, node_n, cur_time);
else
move_trace_node (tmp->pair, node_n, cur_time);
}
else if ( (tmp->pair != NULL) && (cur_time < tmp->pair->a ) ){ //&& (tmp->pair->b->generator == RWP)
LOG_D(OMG, "%.2f < %.2f \n",cur_time, tmp->pair->a);
if ((cur_time >= tmp->pair->b->mob->target_time-eps) && (cur_time<=tmp->pair->b->mob->target_time + eps)){
tmp->pair->b->X_pos = tmp->pair->b->mob->X_to;
tmp->pair->b->Y_pos = tmp->pair->b->mob->Y_to;
Pair pair = malloc(sizeof(Pair));
//pair = keep_awake_trace_node(tmp->pair->b,cur_time,awake_duration,1);
pair = move_trace_node(tmp->pair->b, cur_time);
tmp->pair = pair;
}
tmp = tmp->next;
}
else {
LOG_E(OMG, "%.2f > %.2f\n", cur_time,tmp->pair->a ); //LOG_D(OMG, " (generator=%d) != (RWP=%d) \n", tmp->pair->b->generator, RWP );
done = 1; //quit the loop
exit(-1);
}
}
//sorting the new entries
LOG_D(OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
display_job_list(Job_Vector);
Job_Vector = quick_sort (Job_Vector);///////////
LOG_D(OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
display_job_list(Job_Vector);
else if (my_node->mobile == 0)
{
node_n =
get_next_data (table[my_node->type], my_node->gid,
DATA_AND_STATUS_CHANGE);
}
if (node_n->x_pos == node_n->next->x_pos &&
node_n->y_pos == node_n->next->y_pos)
void get_trace_positions_updated(double cur_time){
sleep_trace_node (tmp->pair, node_n, cur_time);
double X_now=0.0;
double Y_now=0.0;
//LOG_D(OMG, "--------GET TRACE POSITIONS--------\n");
else
move_trace_node (tmp->pair, node_n, cur_time);
Pair my_pair = Job_Vector->pair;
}
else
{
node_n = get_next_data (table[my_node->type], my_node->gid, DATA_ONLY);
if (node_n->x_pos == node_n->next->x_pos &&
node_n->y_pos == node_n->next->y_pos)
if ( (my_pair !=NULL) && (cur_time <= my_pair->a )){
// LOG_D(OMG, "%.2f <= %.2f\n ",cur_time, my_pair->a);
Job_list tmp = Job_Vector;
sleep_trace_node (tmp->pair, node_n, cur_time);
else
move_trace_node (tmp->pair, node_n, cur_time);
while (tmp != NULL){
if (tmp->pair->b->generator == TRACE){
}
node_n = get_next_data (table[my_node->type], my_node->gid, DATA_ONLY);
if (node_n == NULL || node_n->next == NULL)
{
break;
}
if (tmp->pair->b->mobile == 0){ //node is sleeping
LOG_T(OMG, "node number %d is sleeping at location: (%.2f, %.2f)\n", tmp->pair->b->ID, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
LOG_T(OMG, "nothing to do\n");
} //2
}
//case3: current time less than the time to next event
else
{
done = 1; //quit the loop
}
else if (tmp->pair->b->mobile == 1){ //node is moving
LOG_D(OMG,"Node %d is mobile at %f\n", tmp->pair->b->ID,cur_time);
LOG_T(OMG, "Node_number %d\n", tmp->pair->b->ID);
LOG_D(OMG, "destination not yet reached\tfrom (%.2f, %.2f)\tto (%.2f, %.2f)\tspeed %.2f\t(X_pos %.2f\tY_pos %.2f)\n", tmp->pair->b->mob->X_from, tmp->pair->b->mob->Y_from,tmp->pair->b->mob->X_to, tmp->pair->b->mob->Y_to,tmp->pair->b->mob->speed, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
double step=0.10;
if (tmp->pair->b->mob->speed == 0.0 ){
tmp = tmp->next;
if (tmp->pair->b->mob->target_speed == 0.0 ){
} //1
if ((cur_time >= (tmp->pair->b->mob->target_time-step)-eps) && (cur_time<=(tmp->pair->b->mob->target_time + step)+eps)) {
//sorting the new entries
//LOG_D (OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
// display_job_list (Job_Vector);
job_vector[TRACE] = quick_sort (job_vector[TRACE]); ///////////
//LOG_D (OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
// display_job_list( job_vector[TRACE]);
}
Exnode* next_loc=NULL;
next_loc=get_next_position(table,tmp->pair->b->ID);
if (next_loc !=NULL){
tmp->pair->b->X_pos = next_loc->x ;
tmp->pair->b->Y_pos = next_loc->y ;
//tmp->pair->b->X_pos = tmp->pair->b->mob->X_to;
//tmp->pair->b->Y_pos = tmp->pair->b->mob->Y_to;
void
get_trace_positions_updated (double cur_time)
{
double x_now = 0.0, y_now = 0.0;
double len, dx, dy;
job_list *tmp = job_vector[TRACE];
while (tmp != NULL)
{
if (tmp->pair->b->mobile == 1 && tmp->pair->next_event_t >= cur_time)
{
//printf("hiiiiiiiiiii \n");
len =
sqrtf (pow
(tmp->pair->b->mob->x_from -
tmp->pair->b->mob->x_to,
2) + pow (tmp->pair->b->mob->y_from -
tmp->pair->b->mob->y_to, 2));
if (len != 0)
{
dx =
fabs (tmp->pair->b->mob->x_from -
tmp->pair->b->mob->x_to) / len;
dy =
fabs (tmp->pair->b->mob->y_from -
tmp->pair->b->mob->y_to) / len;
//x coordinate
if (tmp->pair->b->mob->x_from < tmp->pair->b->mob->x_to)
{
x_now =
tmp->pair->b->mob->x_from +
(dx *
(tmp->pair->b->mob->speed *
(cur_time - tmp->pair->b->mob->start_journey)));
}
else
{
x_now =
tmp->pair->b->mob->x_from -
(dx *
(tmp->pair->b->mob->speed *
(cur_time - tmp->pair->b->mob->start_journey)));
}
//y coordinate
if (tmp->pair->b->mob->y_from < tmp->pair->b->mob->y_to)
{
y_now =
tmp->pair->b->mob->y_from +
(dy *
(tmp->pair->b->mob->speed *
(cur_time - tmp->pair->b->mob->start_journey)));
}
else
{
y_now =
tmp->pair->b->mob->y_from -
(dy *
(tmp->pair->b->mob->speed *
(cur_time - tmp->pair->b->mob->start_journey)));
}
// needed ?
//tmp->pair->b->X_pos = tmp->pair->b->mob->X_from + 0.0;
//tmp->pair->b->Y_pos = tmp->pair->b->mob->Y_from + 0.0;
}
else {
tmp->pair->b->x_pos = (double) ((int) (x_now * 100)) / 100;
tmp->pair->b->y_pos = (double) ((int) (y_now * 100)) / 100;
double len = sqrtf(pow(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to,2)+pow(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to,2));
double dx = fabs(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to) / len;
double dy = fabs(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to) / len;
if (tmp->pair->b->mob->X_from < tmp->pair->b->mob->X_to ){
X_now = tmp->pair->b->mob->X_from + (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey) ) );
}
else{
X_now = tmp->pair->b->mob->X_from - (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
}
if (tmp->pair->b->mob->Y_from < tmp->pair->b->mob->Y_to ){
Y_now = tmp->pair->b->mob->Y_from + (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
}
else{
Y_now = tmp->pair->b->mob->Y_from - (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
else
{
tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
tmp->pair->b->y_pos = tmp->pair->b->mob->y_to;
}
LOG_D(OMG, "X_now %f\tY_now %f\n", X_now, Y_now);
tmp->pair->b->X_pos = (double) ((int) (X_now*100))/ 100;
tmp->pair->b->Y_pos = (double) ((int) (Y_now*100))/ 100;
//tmp->pair->b->mob->X_from = tmp->pair->b->X_pos;
//tmp->pair->b->mob->Y_from = tmp->pair->b->Y_pos;
//tmp->pair->b->mob->start_journey = cur_time;
}
LOG_D(OMG, "Updated_position of %s id %d to :(%.2f, %.2f)\n", (tmp->pair->b->type == 0) ? "eNB" : "UE", tmp->pair->b->ID, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
}
else{
LOG_E(OMG, "Update_generator: unsupported node state - mobile : %d \n", tmp->pair->b->mobile);
return;
}
}
tmp = tmp->next;
}
}
else {
LOG_E(OMG, "ERROR (current time) %f > %f (first job_time) \n", cur_time ,my_pair->a );
}
}
void
clear_list (void)
{
}
......@@ -42,65 +42,22 @@
#define TRACE_H_
//#include "defs.h"
#include "omg.h"
#include "hashtable.h"
#include "trace_hashtable.h"
#include "mobility_parser.h"
int start_trace_generator (omg_global_param omg_param_list);
/**
* \fn void start_trace_generator(omg_global_param omg_param_list)
* \brief Start the TRACE model by setting the initial positions of each node then letting it sleep for a random duration and adding this job to the Job_Vector
* \param omg_param_list a structure that contains the main parameters needed to establish the random positions distribution
*/
int start_trace_generator(omg_global_param omg_param_list) ;
/**
* \fn int create_trace_node(node_info *head_node)
* \brief Called by the function start_trace_generator(), it assigns position ((X,Y) coordinates) for a node from mobility file and add it to the Node_Vector_Rwp
* \param node a pointer of type NodePtr that represents the node to which the random position is assigned
*/
int create_trace_node(NodePtr node,node_info *head_node) ;
/**
* \fn void place_rwp_node(NodePtr node)
* \brief Called by the function start_rwp_generator(), it generates a random position ((X,Y) coordinates) for a node and add it to the Node_Vector_Rwp
* \param node a pointer of type NodePtr that represents the node to which the random position is assigned
*/
void place_trace_node(NodePtr node) ;
int deploy_nodes();
/**
* \fn Pair sleep_rwp_node(NodePtr node, double cur_time)
* \brief Called by the function start_rwp_generator(omg_global_param omg_param_list) and update_rwp_nodes(double cur_time), it allows the node to sleep for a random duration starting
* from the current time
* \param node a pointer of type NodePtr that represents the node to which the random sleep duration is assigned
* \param cur_time a variable of type double that represents the current time
* \return A Pair structure containing the node and the time when it is reaching the destination
*/
Pair sleep_trace_node(NodePtr node, double cur_time,float sleep_duration) ;
Pair keep_awake_trace_node(NodePtr node, double cur_time,float duration,int jump);
/**
* \fn Pair move_rwp_node(NodePtr node, double cur_time)
* \brief Called by the function update_rwp_nodes(double cur_time), it computes the next destination of a node ((X,Y) coordinates and the arrival
* time at the destination)
* \param node a variable of type NodePtr that represents the node that has to move
* \param cur_time a variable of type double that represents the current time
* \return A Pair structure containing the node structure and the arrival time at the destination
*/
Pair move_trace_node(NodePtr node, double cur_time) ;
/**
* \fn void update_rwp_nodes(double cur_time)
* \brief Update the positions of the nodes. After comparing the current time to the first job_time, it is decided wether to start
* \ a new job or to keep the current job
* \param cur_time a variable of type double that represents the current time
*/
void update_trace_nodes(double cur_time) ;
/**
* \fn void get_rwp_positions_updated(double cur_time)
* \brief Compute the positions of the nodes at a given time in case they are moving (intermediate positions). Otherwise, generate a message saying that
* the nodes are still sleeping
* \param cur_time a variable of type double that represents the current time
*/
void get_trace_positions_updated(double cur_time);
void place_trace_node (node_struct* node, node_data* n);
void move_trace_node (pair_struct* pair, node_data* n_data, double cur_time);
void schedule_trace_node ( pair_struct* pair, node_data* n_data, double cur_time);
void sleep_trace_node ( pair_struct* pair, node_data* n_data, double cur_time);
void update_trace_nodes (double cur_time);
void get_trace_positions_updated (double cur_time);
void clear_list (void);
#endif /* TRACE_H_ */
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2011 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fsr/openairinterface
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
*******************************************************************************/
/*! \file hashtable.c
* \brief A 'C' implementation of a hashtable
* \author S. Gashaw, N. Nikaein, J. Harri
* \date 2014
* \version 0.1
* \company EURECOM
* \email:
* \note
* \warning
*/
#include <stdio.h>
#include "trace_hashtable.h"
#include <stdlib.h>
#include <string.h>
#include "omg.h"
/*Global variables*/
node_info **list_head;
hash_table_t **table;
// hash table operations
/**
* Fuction to create a new hash table
* @param mode hash_table_mode which the hash table should follow
* @returns hash_table_t object which references the hash table
* @returns NULL when no memory
*/
void
create_new_table (int node_type)
{
int i;
if(table==NULL)
table = (hash_table_t **) calloc (MAX_NUM_NODE_TYPES, sizeof (hash_table_t*));
table[node_type]=(hash_table_t *) calloc (MAX_NUM_NODE_TYPES, sizeof (hash_table_t));
if (table == NULL || table[node_type]==NULL)
{
LOG_E (OMG, "--------table creation failed--------\n");
exit (-1);
}
table[node_type]->key_len = LEN;
table[node_type]->key_count = 0;
table[node_type]->ratio = RATIO;
table[node_type]->data_store =
(node_container **) calloc (LEN, sizeof (node_container *));
if (table[node_type]->data_store == NULL)
{
free (table[node_type]);
LOG_E (OMG, "table creation failed \n");
exit (-1);
}
//for (i = 0; i < LEN; i++)
// table->data_store[i] = NULL;
}
/**
* Function to add a key - value pair to the hash table, use HT_ADD macro
* @param table hash table to add element to
* @param key pointer to the key for the hash table
* @param key_len length of the key in bytes
* @param value pointer to the value to be added against the key
* @param value_len length of the value in bytes
* @returns 0 on sucess
* @returns -1 when no memory
*/
void
hash_table_add (hash_table_t * t_table, node_data * node,
node_container * value)
{
hash_table_t *my_table = t_table;
node_data *new_node = node;
int key = new_node->gid;
int hash_val = hash (&key, my_table->key_len);
//resize check
if (value == NULL)
{ //create new container for this node
my_table->key_count++;
node_container *new_c =
(node_container *) calloc (1, sizeof (node_container));
if (!new_c)
{
LOG_E (OMG, "node block creation failed\n");
exit (-1);
}
new_c->gid = new_node->gid;
new_c->next = new_node;
new_c->end = new_c->next;
new_c->next_c = NULL;
if (my_table->data_store[hash_val] == NULL)
my_table->data_store[hash_val] = new_c;
else
{
node_container *temp1, *save;
temp1 = my_table->data_store[hash_val];
while (temp1 != NULL)
{
save = temp1;
temp1 = temp1->next_c;
}
save->next_c = new_c;
}
}
else
{
node_container *my_c = value;
//put node data according to time
if (my_c->gid == new_node->gid)
{
if (my_c->next->time > new_node->time)
{
new_node->next = my_c->next;
my_c->next = new_node;
return;
}
if (my_c->end->time <= new_node->time)
{
my_c->end->next = new_node;
my_c->end = new_node;
return;
}
node_data *temp = my_c->next;
node_data *ptr = temp->next;
while (ptr != NULL && ptr->time <= new_node->time)
{
temp = ptr;
ptr = ptr->next;
}
temp->next = new_node;
new_node->next = ptr;
}
}
}
/**
* Function to lookup a key in a particular table
* @param table table to look key in
* @param key pointer to key to be looked for
* @param key_len size of the key to be searched
* @returns NULL when key is not found in the hash table
* @returns void* pointer to the value in the table
*/
node_container *
hash_table_lookup (hash_table_t * table, int id)
{
hash_table_t *my_table = table;
int key = id;
int hash_value_of_id = hash (&key, my_table->key_len);
if (my_table->data_store[hash_value_of_id] == NULL)
return NULL;
node_container *temp = my_table->data_store[hash_value_of_id];
while (temp != NULL)
{
if (temp->gid == id)
break;
temp = temp->next_c;
}
return temp;
}
/**
* Function that returns a hash value for a given key and key_len
* @param key pointer to the key
* @param key_len length of the key
* @param max_key max value of the hash to be returned by the function
* @returns hash value belonging to [0, max_key)
*/
uint16_t
hash (int *key, int len)
{
uint16_t *ptr = (uint16_t *) key;
uint16_t hash = 0xbabe; // WHY NOT
size_t i = 0;
for (; i < (sizeof (key) / 2); i++)
{
hash ^= (i << 4 ^ *ptr << 8 ^ *ptr);
ptr++;
}
hash = hash % len;
return hash;
}
/**
* Function to resize the hash table store house
* @param table hash table to be resized
* @param len new length of the hash table
* @returns -1 when no elements in hash table
* @returns -2 when no emmory for new store house
* @returns 0 when sucess
*/
int
hash_table_resize ()
{
}
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2011 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fsr/openairinterface
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
*******************************************************************************/
/*! \file trace_hashtable.h
* \brief A 'C' implementation of a hashtable
* \author S. Uppoor
* \date 2011
* \version 0.1
* \company INRIA
* \email: sandesh.uppor@inria.fr
* \note
* \warning
*/
#ifndef _TRACE_HASHTABLE_H
#define _TRACE_HASHTABLE_H
#define LEN 1
#define RATIO 4
#include<sys/types.h>
#include<stdint.h>
#define DATA_ONLY 0
#define DATA_AND_STATUS_CHANGE 1
/**
* @struct Simple struct to hold only few information
* @brief The entry in each node is a line from the external mobility file
*/
typedef struct parsed_data
{
int vid;
int gid;
int type;
double time;
double x_pos;
double y_pos;
double speed;
int visit;
struct parsed_data* next;
}node_data;
/**
* @struct hash_table_element "hashtable.h"
* @brief stores an hash table element for use in the hash table
*/
typedef struct container
{
int flag;
int gid;
node_data* next;
node_data* end;
struct container* next_c;
}node_container;
/**
* @struct hash_table "hashtable.h"
* @brief identifies the hashtable for which operations are to be performed
*/
typedef struct hash_table
{
int key_len;
int key_count;
int ratio;
node_container **data_store;
}hash_table_t;
/**
* @struct struct acts as gateway to hashtable
* @brief holds vehicle id and initial pointer to the head of the linked list in hastable
*/
typedef struct nodeinfo
{
int vid;
int g_id;
struct nodeinfo* next;
}node_info;
/**
* Function that returns a hash value for a given key and key_len
* @param key pointer to the key
* @param key_len length of the key
*f @param max_key max value of the hash to be returned by the function
* @returns hash value belonging to [0, max_key)
*/
uint16_t hash (int *key, int len);
// hash table operations
/**
* Fuction to create a new hash table
* @param mode hash_table_mode which the hash table should follow
* @returns hash_table_t object which references the hash table
* @returns NULL when no memory
*/
void create_new_table (int node_type);
/**
* Function to add a key - value pair to the hash table, use HT_ADD macro
* @param table hash table to add element to
* @param key pointer to the key for the hash table
* @param key_len length of the key in bytes
* @param value pointer to the value to be added against the key
* @param value_len length of the value in bytes
* @returns 0 on sucess
* @returns -1 when no memory
*/
void hash_table_add (hash_table_t* t_table, node_data* node, node_container* value);
/**
* Function to lookup a key in a particular table
* @note use this macro when size of key and/or value can be given by sizeof
* @param table table to look key in
* @param key pointer to key to be looked for
* @param key_len size of the key to be searched
* @returns NULL when key is not found in the hash table
* @returns void* pointer to the value in the table
*/
node_container* hash_table_lookup (hash_table_t* table, int id);
/**
* Function to resize the hash table store house
* @param table hash table to be resized
* @param len new length of the hash table
* @returns -1 when no elements in hash table
* @returns -2 when no emmory for new store house
* @returns 0 when sucess
*/
int hash_table_resize (void);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment