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 { ...@@ -53,6 +53,8 @@ typedef enum {
/* decomposition of node functions into jobs for a given event */ /* 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 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 { typedef struct Job_s {
enum Job_type_e type; enum Job_type_e type;
int exe_time; /* execution time at the worker*/ int exe_time; /* execution time at the worker*/
...@@ -87,9 +89,12 @@ typedef struct Packet_otg_s { ...@@ -87,9 +89,12 @@ typedef struct Packet_otg_s {
typedef struct { typedef struct {
Event_Type_t type; Event_Type_t type;
enum Operation_Type_e optype; //op
char *key; char *key;
void *value; void *value;
frame_t frame; frame_t frame;
int ue;
int lcid;
} Event_t; } Event_t;
/*typedef struct Global_Time { /*typedef struct Global_Time {
...@@ -101,6 +106,8 @@ typedef struct { ...@@ -101,6 +106,8 @@ typedef struct {
double time_ms; double time_ms;
};*/ };*/
typedef struct Packet_otg_elt_s { typedef struct Packet_otg_elt_s {
struct Packet_otg_elt_s *next; struct Packet_otg_elt_s *next;
struct Packet_otg_elt_s *previous; struct Packet_otg_elt_s *previous;
......
...@@ -178,7 +178,7 @@ int logInit (void) ...@@ -178,7 +178,7 @@ int logInit (void)
g_log->log_component[OMG].interval = 1; g_log->log_component[OMG].interval = 1;
g_log->log_component[OMG].fd = 0; g_log->log_component[OMG].fd = 0;
g_log->log_component[OMG].filelog = 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].name = "OTG";
g_log->log_component[OTG].level = LOG_EMERG; g_log->log_component[OTG].level = LOG_EMERG;
......
...@@ -50,7 +50,7 @@ OMG_OBJS += $(OMG_DIR)/job.o ...@@ -50,7 +50,7 @@ OMG_OBJS += $(OMG_DIR)/job.o
OMG_OBJS += $(OMG_DIR)/static.o OMG_OBJS += $(OMG_DIR)/static.o
OMG_OBJS += $(OMG_DIR)/rwp.o OMG_OBJS += $(OMG_DIR)/rwp.o
OMG_OBJS += $(OMG_DIR)/rwalk.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)/mobility_parser.o
OMG_OBJS += $(OMG_DIR)/trace.o OMG_OBJS += $(OMG_DIR)/trace.o
OMG_OBJS += $(OMG_DIR)/sumo.o OMG_OBJS += $(OMG_DIR)/sumo.o
...@@ -58,6 +58,10 @@ OMG_OBJS += $(OMG_DIR)/id_manager.o ...@@ -58,6 +58,10 @@ OMG_OBJS += $(OMG_DIR)/id_manager.o
OMG_OBJS += $(OMG_DIR)/client_traci_OMG.o OMG_OBJS += $(OMG_DIR)/client_traci_OMG.o
OMG_OBJS += $(OMG_DIR)/storage_traci_OMG.o OMG_OBJS += $(OMG_DIR)/storage_traci_OMG.o
OMG_OBJS += $(OMG_DIR)/socket_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_tx.o
OTG_OBJS += $(OTG_DIR)/otg.o OTG_OBJS += $(OTG_DIR)/otg.o
......
...@@ -295,6 +295,7 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need ...@@ -295,6 +295,7 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need
////// options of UE_Mobility_Type ////// options of UE_Mobility_Type
typedef struct typedef struct
{ {
char *selected_option;
int horizontal_grid; int horizontal_grid;
int vertical_grid; int vertical_grid;
} Grid_Map; } Grid_Map;
...@@ -464,6 +465,32 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need ...@@ -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 /** @defgroup _Predefined_traffic Configuration
* @ingroup _OSD_basic * @ingroup _OSD_basic
* @brief Including Application type, Source, destination, background, etc * @brief Including Application type, Source, destination, background, etc
...@@ -684,7 +711,8 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need ...@@ -684,7 +711,8 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need
unsigned char otg_bg_traffic_enabled; unsigned char otg_bg_traffic_enabled;
unsigned char omg_model_rn; unsigned char omg_model_rn;
unsigned char omg_model_enb; unsigned char omg_model_enb;
unsigned char omg_model_ue; unsigned char omg_model_ue;
unsigned char omg_rwp_type;
unsigned char omg_model_ue_current; // when mixed mbility is used unsigned char omg_model_ue_current; // when mixed mbility is used
// control eNB/UE instance through CLI // control eNB/UE instance through CLI
unsigned char cli_enabled; unsigned char cli_enabled;
...@@ -733,6 +761,7 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need ...@@ -733,6 +761,7 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need
* @{*/ * @{*/
typedef struct typedef struct
{ {
Mac_config mac_config[NUMBER_OF_UE_MAX];
Environment_System_Config environment_system_config; /*!< \brief Evironment configuration */ Environment_System_Config environment_system_config; /*!< \brief Evironment configuration */
Topology_Config topology_config; /*!< \brief Topology configuration */ Topology_Config topology_config; /*!< \brief Topology configuration */
Application_Config application_config; /*!< \brief Applications configuration */ Application_Config application_config; /*!< \brief Applications configuration */
......
...@@ -1015,14 +1015,18 @@ void characters(void *user_data, const xmlChar *xmlch, int xmllen) { // called o ...@@ -1015,14 +1015,18 @@ void characters(void *user_data, const xmlChar *xmlch, int xmllen) { // called o
} else if (mobility_) { } else if (mobility_) {
if (UE_mobility_) { if (UE_mobility_) {
if (UE_mobility_type_) { if (UE_mobility_type_) {
oai_emulation.topology_config.mobility.UE_mobility.UE_mobility_type.selected_option = strndup(ch, len); 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_) { if (grid_map_) {
oai_emulation.topology_config.mobility.UE_mobility.grid_walk.grid_map.selected_option = strndup(ch, len);
/*
if (horizontal_grid_) { if (horizontal_grid_) {
oai_emulation.topology_config.mobility.UE_mobility.grid_walk.grid_map.horizontal_grid = atoi(ch); oai_emulation.topology_config.mobility.UE_mobility.grid_walk.grid_map.horizontal_grid = atoi(ch);
} else if (vertical_grid_) { } else if (vertical_grid_) {
oai_emulation.topology_config.mobility.UE_mobility.grid_walk.grid_map.vertical_grid = atoi(ch); oai_emulation.topology_config.mobility.UE_mobility.grid_walk.grid_map.vertical_grid = atoi(ch);
} }
*/
} else if (grid_trip_type_) { } else if (grid_trip_type_) {
oai_emulation.topology_config.mobility.UE_mobility.grid_walk.grid_trip_type.selected_option = strndup(ch, len); 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 ...@@ -1087,6 +1091,7 @@ void characters(void *user_data, const xmlChar *xmlch, int xmllen) { // called o
} else if (eNB_mobility_) { } else if (eNB_mobility_) {
if (eNB_mobility_type_) { if (eNB_mobility_type_) {
oai_emulation.topology_config.mobility.eNB_mobility.eNB_mobility_type.selected_option = strndup(ch, len); oai_emulation.topology_config.mobility.eNB_mobility.eNB_mobility_type.selected_option = strndup(ch, len);
} else if (eNB_initial_distribution_) { } else if (eNB_initial_distribution_) {
oai_emulation.topology_config.mobility.eNB_mobility.eNB_initial_distribution.selected_option = strndup(ch, len); oai_emulation.topology_config.mobility.eNB_mobility.eNB_initial_distribution.selected_option = strndup(ch, len);
} else if (eNB_initial_coordinates_) { } else if (eNB_initial_coordinates_) {
......
1 0 2050 1500 0 1 0 2050 1500 0
1 1 2150 1500 0 1 1 2150 1500 0
...@@ -105,12 +105,12 @@ void init(int max_sim_time) { ...@@ -105,12 +105,12 @@ void init(int max_sim_time) {
sendExact(storageLength(storageStart)); sendExact(storageLength(storageStart));
extractCommandStatus(receiveExact(), CMD_SUBSCRIBE_SIM_VARIABLE, description); extractCommandStatus(receiveExact(), CMD_SUBSCRIBE_SIM_VARIABLE, description);
if (departed == NULL) { 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->string = NULL;
departed->next = NULL; departed->next = NULL;
} }
if (arrived == 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->string = NULL;
arrived->next = NULL; arrived->next = NULL;
} }
...@@ -123,8 +123,8 @@ void init(int max_sim_time) { ...@@ -123,8 +123,8 @@ void init(int max_sim_time) {
void processSubscriptions() { void processSubscriptions() {
int noSubscriptions = readInt(); int noSubscriptions = readInt();
String_list tmp_departed = departed; string_list* tmp_departed = departed;
String_list tmp_arrived = arrived; string_list* tmp_arrived = arrived;
int s; int s;
for (s = 0; s<noSubscriptions; ++s) { for (s = 0; s<noSubscriptions; ++s) {
...@@ -240,12 +240,12 @@ void commandSimulationStep(double time) ...@@ -240,12 +240,12 @@ void commandSimulationStep(double time)
extractCommandStatus(receiveExact(), CMD_SIMSTEP2, description); extractCommandStatus(receiveExact(), CMD_SIMSTEP2, description);
if (departed == NULL) { 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->string = NULL;
departed->next = NULL; departed->next = NULL;
} }
if (arrived == 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->string = NULL;
arrived->next = NULL; arrived->next = NULL;
} }
...@@ -402,14 +402,14 @@ int commandGetMaxSUMONodesVariable() ...@@ -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); commandGetVehicleVariable(sumo_id, VAR_SPEED);
double speed_double = readDouble(); double speed_double = readDouble();
node->mob->speed = speed_double; 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); commandGetVehicleVariable(sumo_id, VAR_POSITION);
double x_double = readDouble(); double x_double = readDouble();
...@@ -420,6 +420,6 @@ void GetPosition(NodePtr node, char * sumo_id) ...@@ -420,6 +420,6 @@ void GetPosition(NodePtr node, char * sumo_id)
if (y_double < 0.0) if (y_double < 0.0)
y_double = 0.0; y_double = 0.0;
node->X_pos = x_double; node->x_pos = x_double;
node->Y_pos = y_double; node->y_pos = y_double;
} }
...@@ -56,8 +56,8 @@ int targetTime; ...@@ -56,8 +56,8 @@ int targetTime;
char *description; char *description;
String_list departed; // string list of all vehicles appearing in 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 string_list* arrived; // string list of all vehicles leaving SUMO at the current time step
/** /**
* Global parameters defined in storage_traci_OMG.h * Global parameters defined in storage_traci_OMG.h
...@@ -89,10 +89,10 @@ int extractCommandStatus(storage *, unsigned char , char *); ...@@ -89,10 +89,10 @@ int extractCommandStatus(storage *, unsigned char , char *);
void commandSimulationStep(double); void commandSimulationStep(double);
/** /**
* \fn commandClose(); * \fn commandClose(void);
* \brief Send termination command to SUMO * \brief Send termination command to SUMO
*/ */
void commandClose(); void commandClose(void);
/** /**
* \fn commandGetVehicleVariable(char *vehID, int varID) * \fn commandGetVehicleVariable(char *vehID, int varID)
...@@ -103,10 +103,10 @@ void 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 * \brief Return the total number of nodes to be simulated in SUMO
*/ */
int commandGetMaxSUMONodesVariable(); int commandGetMaxSUMONodesVariable(void);
/** /**
* \fn init(int max_sim_time) * \fn init(int max_sim_time)
...@@ -126,7 +126,7 @@ void processSubscriptions(void); ...@@ -126,7 +126,7 @@ void processSubscriptions(void);
* \param NodePtr node the pointer to the OAISim node * \param NodePtr node the pointer to the OAISim node
* \param char *sumo_id the SUMO ID of the target 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); * \fn void Position(NodePtr node, char * sumo_id);
...@@ -134,7 +134,7 @@ void GetSpeed(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 NodePtr node the pointer to the OAISim node
* \param char *sumo_id the SUMO ID of the target 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 #endif
......
...@@ -47,297 +47,392 @@ ...@@ -47,297 +47,392 @@
#define frand() ((double) rand() / (RAND_MAX+1)) #define frand() ((double) rand() / (RAND_MAX+1))
//#ifndef STANDALONE //#ifndef STANDALONE
mapping nodes_type[] = mapping nodes_type[] = {
{ {"eNB", eNB}
{"eNB", eNB}, ,
{"UE", UE}, {"UE", UE}
{NULL, -1} ,
{NULL, -1}
}; };
mapping nodes_status[] = mapping nodes_status[] = {
{ {"sleeping", 0}
{"sleeping", 0}, ,
{"moving", 1}, {"moving", 1}
{NULL, -1} ,
{NULL, -1}
}; };
mapping mob_type[] = mapping mob_type[] = {
{ {"STATIC", STATIC}
{"STATIC", STATIC}, ,
{"RWP", RWP}, {"RWP", RWP}
{"RWALK", RWALK}, ,
{"TRACE", TRACE}, {"RWALK", RWALK}
{"SUMO", SUMO}, ,
{NULL, -1} {"TRACE", TRACE}
,
{"SUMO", SUMO}
,
{NULL, -1}
}; };
//#endif //#endif
NodePtr create_node(void) {
NodePtr ptr; node_struct *
ptr = calloc(1, sizeof(node_struct)); create_node (void)
return ptr; {
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; 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) { mobility_struct *
MobilityPtr ptr; create_mobility (void)
ptr = calloc(1, sizeof(mobility_struct)); {
return ptr; mobility_struct *ptr;
ptr = calloc (1, sizeof (mobility_struct));
return ptr;
} }
Node_list add_entry(NodePtr node, Node_list Node_Vector){ node_list *
Node_list entry = malloc(sizeof(node_list_struct)); add_entry (node_struct * node, node_list * node_vector_end)
entry->node = node; {
entry->next = NULL; node_list *entry = malloc (sizeof (struct node_list_struct));
if (Node_Vector == NULL) { entry->node = node;
// LOG_D(OMG, "\nempty Node_list"); entry->next = NULL;
//LOG_D(OMG, "\nadded elmt ID %d\n", entry->node->ID); if (node_vector_end == NULL)
return entry; {
return entry;
} }
else { else
Node_list tmp = Node_Vector; {
while (tmp->next != NULL){ node_list *tmp = node_vector_end;
tmp = tmp->next; tmp->next = entry;
}
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 *
Node_list tmp, toRemove; remove_node_entry (node_struct * node, node_list * node_vector)
if (list == NULL){ {
return NULL; node_list *list = node_vector;
} node_list *tmp, *toremove;
if(list->node->ID == node->ID) { if (list == NULL)
// TODO delete the entry {
toRemove = list; return NULL;
LOG_D(OMG,"removed entry for node %d \n",list->node->ID);
if(list->next ==NULL) {
Node_Vector = NULL;
return NULL;
} }
else { if (list->node->id == node->id)
Node_Vector = list->next; {
// 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;
return NULL;
}
else
{
node_vector = list->next;
}
}
else
{
while (list->next != NULL)
{
tmp = list;
if (list->next->node->id == node->id)
{
toremove = tmp; // TODO delete the entry
tmp = list->next->next;
if (tmp != NULL)
{
list->next = tmp;
}
else
{
list->next = NULL;
}
}
}
} }
} return node_vector;
else{
while (list->next !=NULL) {
tmp = list;
if(list->next->node->ID == node->ID) {
toRemove = tmp; // TODO delete the entry
tmp = list->next->next;
if(tmp !=NULL) {
list->next = tmp;
}
else{
list->next = NULL;
}
}
}
}
return Node_Vector;
} }
// display list of nodes // display list of nodes
void display_node_list(Node_list Node_Vector){ void
Node_list tmp = Node_Vector; display_node_list (node_list * node_vector)
{
while ((tmp != NULL) && node_list *tmp = node_vector;
(tmp->node != NULL)){ if (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), #ifdef STANDALONE
map_int_to_str(nodes_type, tmp->node->type), printf ("Empty Node_list\n");
tmp->node->ID, #else
map_int_to_str(nodes_status, tmp->node->mobile), LOG_I (OMG, "Empty Node_list\n");
tmp->node->X_pos, #endif
tmp->node->Y_pos ); }
while (tmp != NULL)
//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_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 ); */
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 ); //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 );
tmp = tmp->next; tmp = tmp->next;
} }
} }
void display_node_position(int ID, int generator, int type, int mobile, double X, double Y){ void
LOG_I(OMG,"[%s][%s] Node of ID %d is %s. Now, it is at location (%.2f, %.2f) \n", display_node_position (int id, int generator, int type, int mobile, double x,
map_int_to_str(mob_type, generator), double y)
map_int_to_str(nodes_type, type), {
ID, LOG_I (OMG,
map_int_to_str(nodes_status, mobile), "[%s][%s] Node of ID %d is %s. Now, it is at location (%.2f, %.2f) \n",
X, map_int_to_str (mob_type, generator), map_int_to_str (nodes_type,
Y type), id,
); map_int_to_str (nodes_status, mobile), x, y);
} }
Node_list filter(Node_list Vector, int node_type){ node_list *
Node_list tmp1, tmp2; filter (node_list * vector, int node_type)
tmp1 = Vector; {
node_list *tmp1, *tmp2;
tmp1 = vector;
tmp2 = NULL; tmp2 = NULL;
while (tmp1 != NULL){ while (tmp1 != NULL)
if (tmp1->node->type == node_type){ {
tmp2 = add_entry(tmp1->node, tmp2); if (tmp1->node->type == node_type)
{
tmp2 = add_entry (tmp1->node, tmp2);
}
tmp1 = tmp1->next;
} }
tmp1 = tmp1->next;
}
return tmp2; return tmp2;
} }
void delete_node_entry(Node_list entry) {
NodePtr node = entry->node; void
delete_node(node); delete_node_entry (node_list * entry)
entry->node = NULL; {
free(entry); node_struct *node = entry->node;
delete_node (node);
entry->node = NULL;
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; int found;
Node_list current, previous; node_list *current, *previous;
//int cond=0; //int cond=0;
//int i=0; //int i=0;
if (list == NULL){ if (list == NULL)
found = 1; //false {
return NULL; found = 1; //false
}
else{ //start search
current = list;
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 ");
return NULL; return NULL;
} //value not found
else{
found = 0; // true value found
if (current == list) {
list = current->next;
LOG_D(OMG,"Element to remove is found at beginning\n");
}
else {
previous->next = current->next;
}
delete_node_entry(current); // freeing memory
current = NULL;
} }
return list; else
} { //start search
} current = list;
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 ");
return NULL;
} //value not found
else
{
found = 0; // true value found
if (current == list)
{
list = current->next;
LOG_D (OMG, "Element to remove is found at beginning\n");
}
else
{
previous->next = current->next;
}
delete_node_entry (current); // freeing memory
current = NULL;
int length(char* s){
int count = 0;
while(s[count] != '\0'){
++count;
} }
return count; return list;
}
} }
NodePtr find_node(Node_list list, int nID, int node_type){ int
length (char *s)
{
int count = 0;
while (s[count] != '\0')
{
++count;
}
return count;
}
node_struct *
find_node (node_list * list, int nid, int node_type)
{
int found; int found;
Node_list current; node_list *current;
if (list == NULL){ if (list == NULL)
printf(" Node_LIST for nodeID %d is NULL \n ",nID); {
return NULL; printf (" Node_LIST for nodeID %d is NULL \n ", nid);
} return NULL;
else{ //start search
current = list;
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 else
if (current ==NULL) { { //start search
found= 1 ; current = list;
LOG_D(OMG," Element to find in Node_Vector with ID: %d could not be found\n ",nID); 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);
return NULL;
} //value not found
else
{
//printf(" found a node for nodeID %d \n ",nID);
return current->node;
}
return NULL; return NULL;
} //value not found
else{
//printf(" found a node for nodeID %d \n ",nID);
return current->node;
} }
return NULL;
}
} }
Node_list clear_node_list(Node_list list) { node_list *
Node_list tmp; clear_node_list (node_list * list)
{
if (list == NULL){ node_list *tmp;
return NULL;
} if (list == NULL)
else{ {
while (list->next !=NULL) { return NULL;
tmp = list; }
list = list->next; else
delete_node_entry(tmp); {
} while (list->next != NULL)
delete_node_entry(list); // clearing the last one {
} tmp = list;
list = list->next;
delete_node_entry (tmp);
}
delete_node_entry (list); // clearing the last one
}
return NULL; return NULL;
} }
// TODO rewrite this part...not working correctly // TODO rewrite this part...not working correctly
Node_list reset_node_list(Node_list list) { node_list *
Node_list tmp; reset_node_list (node_list * list)
Node_list last = list; {
if (list == NULL){ node_list *tmp;
//printf("Node_list is NULL\n"); node_list *last = list;
return NULL; if (list == NULL)
} {
else{ //printf("Node_list is NULL\n");
while (list->next !=NULL) { return NULL;
tmp = list; }
list = list->next; else
tmp->node = NULL; {
//free(tmp); while (list->next != NULL)
} {
list->node = NULL; // clearing the last one | JHNOTE: dangerous here: the pointer is not NULL, but node is...that leads to segfault... tmp = list;
//free(last); list = list->next;
} tmp->node = NULL;
//free(tmp);
}
list->node = NULL; // clearing the last one | JHNOTE: dangerous here: the pointer is not NULL, but node is...that leads to segfault...
//free(last);
}
return list; return list;
} }
// TODO rewrite this part...not working correctly // TODO rewrite this part...not working correctly
String_list clear_String_list(String_list list) { string_list *
String_list tmp; clear_string_list (string_list * list)
{
if (list == NULL){ string_list *tmp;
return NULL;
} if (list == NULL)
else{ {
while (list->next !=NULL) { return NULL;
tmp = list; }
list = list->next; else
free(tmp->string); {
tmp->string = NULL; while (list->next != NULL)
free(tmp); {
} tmp = list;
list->string = NULL; // clearing the last one | JHNOTE: dangerous here: the pointer is not NULL, but node is...that leads to segfault... list = list->next;
} free (tmp->string);
tmp->string = NULL;
free (tmp);
}
list->string = NULL; // clearing the last one | JHNOTE: dangerous here: the pointer is not NULL, but node is...that leads to segfault...
}
return list; return list;
} }
...@@ -347,32 +442,43 @@ String_list clear_String_list(String_list list) { ...@@ -347,32 +442,43 @@ String_list clear_String_list(String_list list) {
* with string value NULL * with string value NULL
*/ */
/* map a string to an int. Takes a mapping array and a string as arg */ /* 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){ int
while (1) { map_str_to_int (mapping * map, const char *str)
if (map->name == NULL) { {
return(-1); while (1)
} {
if (!strcmp(map->name, str)) { if (map->name == NULL)
return(map->value); {
} return (-1);
map++; }
if (!strcmp (map->name, str))
{
return (map->value);
}
map++;
} }
} }
/* map an int to a string. Takes a mapping array and a value */ /* map an int to a string. Takes a mapping array and a value */
char *map_int_to_str(mapping *map, int val) { char *
while (1) { map_int_to_str (mapping * map, int val)
if (map->name == NULL) { {
return NULL; while (1)
} {
if (map->value == val) { if (map->name == NULL)
return map->name; {
} return NULL;
map++; }
if (map->value == val)
{
return map->name;
}
map++;
} }
} }
#endif
#endif
/******************************************************************************* /*******************************************************************************
Eurecom OpenAirInterface 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 This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -28,16 +28,9 @@ ...@@ -28,16 +28,9 @@
*******************************************************************************/ *******************************************************************************/
/** /**
* \file defs.h * \file defs.h
* \brief Typedefs & Prototypes of OMG functions * \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
*/
#ifndef __DEFS_H__ #ifndef __DEFS_H__
#define __DEFS_H__ #define __DEFS_H__
...@@ -61,69 +54,90 @@ int map_str_to_int(mapping *map, const char *str); ...@@ -61,69 +54,90 @@ int map_str_to_int(mapping *map, const char *str);
char *map_int_to_str(mapping *map, int val); char *map_int_to_str(mapping *map, int val);
#endif #endif
/*!A sructure that includes all the characteristic mobility elements of a node */ /****************************************************************************
typedef struct mobility_struct { !A sructure that includes all the characteristic mobility elements of a node
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 */ struct mobility_struct {
double X_to; /*!< The X coordinate of the destination location of the node */ double x_from; /*!< The X coordinate of the previous location of the node */
double Y_to; /*!< The Y coordinate of the destination 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 speed; /*!< The speed of the node */
double sleep_duration; /*!< The sleep duration of the node (Used with the RWP model) */ 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 azimuth; /*!< The direction in which the node moves (Used with RWALK model) */
double journey_time; /*!< The duration of the node trip */ double journey_time; /*!< The duration of the node trip */
double start_journey; /*!< The instant on which the node trip starts*/ 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>*/ double target_time;/*!<The time instant before the node should complete>*/
}mobility_struct; 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 { !A sructure that defines a node and its associated informaion
int ID; /*!< The identifier of the node in question */ *******************************************************************************/
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 type; /*!< The node's type, it is one of types enumarated in #node_types */
int mobile; /*!< The node status: static or mobile */ int mobile; /*!< The node status: static or mobile */
double X_pos; /*!< The X coordinate of the current location of 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 */ 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*/ 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*/ 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 { 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 */ 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 */ node_struct *b; /*!< A variable of type #NodePtr. It represents a node */
double a; /*!< The corresponding time of job execution */ double next_event_t; /*!< The corresponding time of job execution */
}pair_struct; };
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 { 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 */ 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 */ 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 */ //int number_of_nodes[MAX_NUM_NODE_TYPES];
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_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 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_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 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 */ 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 */
bool user_fixed; /*!< Sets if the coordinates are user defined*/ 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 */
double fixed_X; /*!< The user defined x value*/ bool user_fixed; /*!< Sets if the coordinates are user defined*/
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 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 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 */ 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{ ...@@ -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 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*/ 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 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_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*/ 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* 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 */ 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{ ...@@ -145,13 +164,15 @@ typedef struct omg_global_param{
int sumo_port; /*!< The port number attached to SUMO on the host DEFAULT: TBC */ int sumo_port; /*!< The port number attached to SUMO on the host DEFAULT: TBC */
}omg_global_param; }omg_global_param;
/*!A string List structure */ /******************************************************************************
!A string List structure
*******************************************************************************/
struct string_list_struct { struct string_list_struct {
char* string; /*! a string */ char* string; /*! a string */
struct string_list_struct *next; /*!< A pointer to the next string in the list */ 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 */ /* PROTOTYPES */
...@@ -171,7 +192,7 @@ void update_node_vector(int mobility_type, double cur_time); ...@@ -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 * \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.) * \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); ...@@ -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 * \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 * \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) * \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); ...@@ -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 * \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 * \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) * \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) * \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 * \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); ...@@ -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 * \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 * \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) * \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); ...@@ -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 * \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 * \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) * \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 * \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 * \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) * \fn void delete_entry(NodePtr node)
* \brief Delete a node, and all subsequent data in its structure; free the memory * \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 * \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) * \fn void clear node_List(Node_list list)
...@@ -241,7 +262,7 @@ void delete_node(NodePtr node); ...@@ -241,7 +262,7 @@ void delete_node(NodePtr node);
* \param list a pointer of type Node_list that represents the list to be cleared * \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 * \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) * \fn void init_node_list(Node_list list)
...@@ -249,7 +270,7 @@ Node_list clear_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 * \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 * \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) * \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); ...@@ -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 X the node's current location according to the X axis
* \param Y the node's current location according to the Y 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 ...@@ -271,7 +292,7 @@ void display_node_position(int ID, int generator, int type, int mobile, double X
* \param node_type the desired type * \param node_type the desired type
* \return a pointer to a new Node_list which is the input Node_list after filtering * \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); ...@@ -281,7 +302,7 @@ Node_list filter(Node_list Vector, int node_type);
* \param b upper limit * \param b upper limit
* \return double: the generated random number * \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); ...@@ -289,7 +310,7 @@ double randomGen(double a, double b);
* \brief Creates a new #NodePtr by allocating the needed memory space for it * \brief Creates a new #NodePtr by allocating the needed memory space for it
* \return the created node structure * \return the created node structure
*/ */
NodePtr create_node(void); node_struct* create_node(void);
/** /**
...@@ -297,7 +318,7 @@ NodePtr create_node(void); ...@@ -297,7 +318,7 @@ NodePtr create_node(void);
* \brief Creates a new #MobilityPtr by allocating the needed memory space for it * \brief Creates a new #MobilityPtr by allocating the needed memory space for it
* \return the created mobility structure * \return the created mobility structure
*/ */
MobilityPtr create_mobility(void); mobility_struct* create_mobility(void);
/** /**
...@@ -307,7 +328,8 @@ MobilityPtr 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 * \param Job_Vector a variable #Job_list that represents the Job_list that stores all the scheduled jobs
* \return the created mobility structure * \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); ...@@ -315,9 +337,11 @@ Job_list add_job(Pair job, Job_list Job_Vector);
* \brief Traverse the Job_Vector to diplay its contents * \brief Traverse the Job_Vector to diplay its contents
* \param Job_Vector the structure that stoks all the jobs * \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) * \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 * \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); ...@@ -325,7 +349,7 @@ void display_job_list(Job_list Job_Vector);
* \param end Job_list needed for intermediate computation * \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 * \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); ...@@ -334,7 +358,7 @@ Job_list job_list_sort (Job_list list, Job_list end);
* \param list the structure that stoks all the jobs * \param list the structure that stoks all the jobs
* \return the sorted list * \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); ...@@ -345,7 +369,7 @@ Job_list quick_sort (Job_list list);
* \param node_type the type of the node whose job should be removed * \param node_type the type of the node whose job should be removed
* \return the updated Job_list after removing the job in question * \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) * \fn int length(char* s)
...@@ -361,7 +385,7 @@ int length(char* s); ...@@ -361,7 +385,7 @@ int length(char* s);
* \param list the String_list to be cleared; * \param list the String_list to be cleared;
* \return reference to the HEAD of the cleared String_list * \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() * \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 @@ ...@@ -29,8 +29,8 @@
/*! \file job.c /*! \file job.c
* \brief handle jobs for future nodes' update * \brief handle jobs for future nodes' update
* \author M. Mahersi, J. Harri, N. Nikaein, * \author S. Gashaw, M. Mahersi, J. Harri, N. Nikaein,
* \date 2011 * \date 2014
* \version 0.1 * \version 0.1
* \company Eurecom * \company Eurecom
* \email: * \email:
...@@ -44,127 +44,172 @@ ...@@ -44,127 +44,172 @@
#include "omg.h" #include "omg.h"
Job_list add_job(Pair job, Job_list Job_Vector){ job_list *
Job_list entry = malloc(sizeof(Job_list)); add_job (pair_struct * job, job_list * job_vector)
entry->pair = job; {
//LOG_D(OMG, " Job_Vector_len %d", Job_Vector_len); job_list *tmp;
entry->next = NULL; job_list *entry = (job_list *) malloc (sizeof (struct job_list_struct));
entry->pair = job;
if (Job_Vector == NULL) { entry->next = 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 { tmp = job_vector;
Job_list tmp = Job_Vector; tmp->next = entry;
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;
} }
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)
{
return entry;
}
else
{
tmp = job_vector;
while (tmp->next != NULL)
{
tmp = tmp->next;
}
tmp->next = entry;
}
return job_vector;
}
// display list of jobs // 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
{
//LOG_D(OMG, "first_Job_time in Job_Vector %f\n", Job_Vector->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);
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);
tmp = tmp->next; tmp = tmp->next;
}
} }
} }
//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 // 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;
pivot = list; if (list != end && list->next != end)
before = pivot; {
after = end;
for ( tmp=list->next; tmp != end; tmp=next ) pivot = list;
{ before = pivot;
next = tmp->next; after = end;
if (tmp->pair->a > pivot->pair->a) for (tmp = list->next; tmp != end; tmp = next)
tmp->next = after, after = tmp; {
else next = tmp->next;
tmp->next = before, before = tmp; if (tmp->pair->next_event_t > pivot->pair->next_event_t)
} tmp->next = after, after = tmp;
else
before = job_list_sort (before, pivot); tmp->next = before, before = tmp;
after = job_list_sort (after, end); }
pivot->next = after; before = job_list_sort (before, pivot);
return before; after = job_list_sort (after, end);
pivot->next = after;
return before;
} }
return list; 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 *
remove_job (job_list * list, int nid, int node_type)
Job_list current, previous; {
//int cond=0;
int i=0; job_list *current, *previous;
if (list == NULL){
return NULL; current = list;
} previous = NULL;
else{ //start search while (current != NULL)
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 ");} if (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); if (current == list || previous == NULL)
LOG_D(OMG, "nID %d",nID); list = current->next;
LOG_D(OMG, "current->pair->b->type %d",current->pair->b->type ); // UE, eNB 1 else
LOG_D(OMG, "node_type %d",node_type ); //UE, eNB 0 previous->next = current->next;
LOG_D(OMG, "current->pair->b->generator %d",current->pair->b->generator ); //static
free (current);
LOG_D(OMG, "i = %d", i); break;
previous = current; // previous hobbles after
}
previous = current;
current = current->next; current = current->next;
i++;
if (current ==NULL){LOG_D(OMG, "current ==NULL");}
} }
return list;
//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");}
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;
}
}
return list;
}
}
}
CC= gcc CC= gcc
OBJstatic = omg.c common.c static.c 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 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 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 .PHONY: help staticOMG rwpOMG clean
......
...@@ -29,11 +29,11 @@ ...@@ -29,11 +29,11 @@
/*! \file mobility_parser.c /*! \file mobility_parser.c
* \brief A parser for trace-based mobility information (parsed from a file) * \brief A parser for trace-based mobility information (parsed from a file)
* \author S. Uppoor * \author S. Gashaw, N. Nikaein, J. Harri
* \date 2011 * \date 2014
* \version 0.1 * \version 0.1
* \company INRIA * \company EURECOM
* \email: sandesh.uppoor@inria.fr * \email:
* \note * \note
* \warning * \warning
*/ */
...@@ -42,442 +42,226 @@ ...@@ -42,442 +42,226 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "mobility_parser.h" #include "mobility_parser.h"
#include "omg_hashtable.h"
#include "omg.h" #include "omg.h"
#include <math.h>
extern hash_table_t **table;
extern node_info **list_head;
node_info* head_node_info =NULL; //read the mobility file and generates a hashtable of linked list
omg_hash_table_t* table=NULL; 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) //if(table==NULL)
struct Exnode* gen_list(){ create_new_table (node_type);
struct Exnode* head = NULL;
return head;
}
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 if (list_head == NULL )
void read_mobility_file(char* mobility_file[]){ {
FILE *fp; LOG_E (OMG, "-------node list table creation failed--------\n");
char str[128],*p; exit (-1);
if (table == NULL){
table = hash_table_new(MODE_ALLREF);
}
if((fp=fopen(mobility_file, "r"))==NULL) {
LOG_D(OMG,"Cannot open file %s\n", mobility_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){
case 0:
node->time=(atof(pch));
break;
case 1:
node->vid =atoi(pch);
break;
case 2:
node->x=atof(pch);
break;
case 3:
node->y=atof(pch);
break;
case 4:
node->speed=atof(pch);
break;
default:
//need a log statement here
break;
}
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));
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();
}
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);
}
}
} }
}
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) { if ((fp = fopen (trace_file, "r")) == NULL)
{
while(headRef->next!=NULL){ LOG_E (OMG, "[OMG]:Cannot open file %s\n", trace_file);
headRef = headRef->next; exit (1);
} }
if (headRef->next==NULL ){
headRef->next = newNode;
} 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:
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);
LOG_D (OMG, "%d \n",node->vid);
break;
case 2:
node->x_pos = atof (pch);
LOG_D (OMG, "%.2f \n",node->x_pos);
break;
case 3:
node->y_pos = atof (pch);
LOG_D (OMG, "%.2f \n",node->y_pos);
break;
case 4:
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:
LOG_E (OMG,
"[Error in trance file]:incorrect data format \n");
break;
}
fmt += 1;
pch = strtok (NULL, " ");
}
node->next = NULL;
node->visit = 0;
// 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
{
node->gid = gid;
value = hash_table_lookup (table[node_type], node->gid);
hash_table_add (table[node_type], node, value);
}
}
}
}
fclose (fp);
//Just used for testing, it prints a linked list given the head pointer
void print_list(struct Exnode* head){
while(head->next !=NULL)
head=head->next;
} }
Exnode* get_next_position(omg_hash_table_t *table,int node_id){ //search for node given id if exist
node_info* head_node=head_node_info;
while(head_node->next!=NULL){ int
find_node_info (int vid, int node_type)
if(head_node->vid==node_id){ {
int *value1 = NULL; node_info *search;
value1 = (int *) HT_LOOKUP(table, head_node->vid_addr); if (list_head[node_type] != NULL)
if (value1!=NULL){ {
Exnode* value2=(Exnode *)value1; search = list_head[node_type];
while(value2->next!=NULL){ while (search != NULL)
if (value2->visit==1) value2=value2->next; {
else { if (search->vid == vid)
value2->visit=1; return search->g_id;
return value2; search = search->next;
}
}
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; return -1;
} }
//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;
void reset_visit_status(omg_hash_table_t *table,float time, int node_id){ if (list_head[node_type] == NULL)
node_info* head_node=head_node_info; list_head[node_type] = new;
while(head_node->next!=NULL){ else
{
if(head_node->vid==node_id){ node_info *temp, *save;
int *value1 = NULL; temp = list_head[node_type];
value1 = (int *) HT_LOOKUP(table, head_node->vid_addr); while (temp != NULL)
if (value1!=NULL){ {
Exnode* value2=(Exnode *)value1; save = temp;
while(value2->next!=NULL){ temp = temp->next;
if (value2->time == time) { }
value2->visit=0;
} save->next = new;
value2=value2->next;
}
if (value2->time == time){
value2->visit=0;
} }
}
} }
head_node=head_node->next; else
} {
// not to leave the last node with ->next=NULL LOG_E (OMG, "node info list creation failed\n");
if(head_node->vid==node_id){ exit (-1);
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 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;
}
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){ int
Exnode *pStart; get_number_of_nodes (int node_type)
Exnode *pCurrent; {
double swp_time; return table[node_type]->key_count;
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);
} }
void clear_llist(){ node_data *
get_next_data (hash_table_t * table, int vid, int flag)
node_info* TempNode=NULL; {
node_info* tmp=NULL; node_container *block = hash_table_lookup (table, vid);
TempNode=head_node_info; node_data *links = NULL, *save = NULL;
while(TempNode->next!=NULL){ if (block != NULL)
int *value1 = NULL; links = block->next;
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",
while (TempMob->next!=NULL){ vid);
Exnode* tmp=NULL;
tmp=TempMob; while (links != NULL)
TempMob=TempMob->next; {
free(tmp); if (links->visit == 0)
tmp=NULL; break;
} save = links;
if (TempMob->next == NULL){ links = links->next;
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;
}
printf("checking reset %d\n",value->visit);
} if (links != NULL)
head_node=head_node->next; {
if (flag == DATA_AND_STATUS_CHANGE)
{
if (block->next != block->end)
links->visit = 1;
return links;
} }
int *value1 = NULL; else if (flag == DATA_ONLY)
value1 = (int *) HT_LOOKUP(table, head_node->vid_addr); {
Exnode *value=(Exnode *)value1; return save;
while(value->next!=NULL){ }
printf("checking reset %d %d\n",value->visit,value->vid); }
value=value->next; else
} return links;
printf("checking reset %d %d\n",value->visit,value->vid); }
return 0;
}*/
...@@ -41,62 +41,16 @@ ...@@ -41,62 +41,16 @@
#ifndef MOBILITY_PARSER_H_ #ifndef MOBILITY_PARSER_H_
#define 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, * 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. * if so append append is called else a new linked list to the vehicle is created.
* @param need mobility file to be given * @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 * 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 ...@@ -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 vid is the vehicle id
* @param pointer to the head of the linked list to the vehicle entry in the hash table * @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 * 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) * 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); ...@@ -129,10 +76,8 @@ void quicksortlist(Exnode *pLeft, Exnode *pRight);
* @param hashtable from which the node is to be looked * @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 * @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_ */ #endif /* MOBILITY_PARSER_H_ */
...@@ -29,8 +29,8 @@ ...@@ -29,8 +29,8 @@
/*! \file OMG.c /*! \file OMG.c
* \brief Main function containing the OMG interface * \brief Main function containing the OMG interface
* \author M. Mahersi, N. Nikaein, J. Harri * \author S. Gashaw, N. Nikaein, J. Harri
* \date 2011 * \date 2011 - 2014
* \version 0.1 * \version 0.1
* \company Eurecom * \company Eurecom
* \email: * \email:
...@@ -51,738 +51,934 @@ ...@@ -51,738 +51,934 @@
#include "rwp.h" #include "rwp.h"
#include "rwalk.h" #include "rwalk.h"
#include "trace.h" #include "trace.h"
#include "grid.h"
#include "steadystaterwp.h"
#include "sumo.h" #include "sumo.h"
#include "../OMV/structures.h" #include "../OMV/structures.h"
//#define STANDALONE //#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); void omv_end (int pfd, Data_Flow_Unit omv_data);
int omv_enabled; int omv_enabled;
void init_omg_global_params(void){ //if we want to re initialize all /*initialze global parameters*/
int i = 0; void
Job_Vector_len=0; init_omg_global_params (void)
Job_Vector = NULL; {
for (i=0; i<MAX_NUM_MOB_TYPES; i++){ int mob_t, node_t, i;
Node_Vector[i] = NULL; xloc_div = 10.0;
Node_Vector_len[i] = 0; yloc_div = 10.0;
//Initial_Node_Vector_len[i] = 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) /*initiate mobility generator*/
// of course, add 'stop_OMG(), which calls recursively void
// stop_XX_generator(); init_mobility_generator (omg_global_param omg_param_list[])
// {
void init_mobility_generator(omg_global_param omg_param_list) { int node_t, mobility_t;
switch (omg_param_list.mobility_type) {
for (node_t = eNB; node_t < MAX_NUM_NODE_TYPES; node_t++)
{
mobility_t = omg_param_list[node_t].mobility_type;
switch (mobility_t)
{
case STATIC:
start_static_generator (omg_param_list[node_t]);
break;
case RWP:
start_rwp_generator (omg_param_list[node_t]);
break;
case RWALK:
start_rwalk_generator (omg_param_list[node_t]);
break;
case TRACE:
start_trace_generator (omg_param_list[node_t]);
break;
case SUMO:
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\n");
}
}
case STATIC:
start_static_generator(omg_param_list);
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);
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);
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");
break;
case SUMO:
start_sumo_generator(omg_param_list);
//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);
}
} }
void stop_mobility_generator(int mobility_type) { /**************************************************************************************/
switch (mobility_type) { /*stop sumo mobiity generator*/
void
case STATIC: stop_mobility_generator (omg_global_param * omg_param_list)
break; {
case RWP: int i;
break; for (i = 0; i < MAX_NUM_NODE_TYPES; i++)
case RWALK: {
break; switch (omg_param_list[i].mobility_type)
case TRACE: {
clear_llist();
break; case STATIC:
break;
case SUMO: case RWP:
stop_sumo_generator(); break;
//LOG_D(OMG," --------OMG will interface with SUMO for mobility generation-------- \n"); case RWALK:
break; break;
case TRACE:
default: clear_list ();
LOG_N(OMG, "Unsupported generator %d \n", omg_param_list.mobility_type); break;
} case STEADY_RWP:
break;
case SUMO:
stop_sumo_generator ();
//LOG_D(OMG," --------OMG will interface with SUMO for mobility generation-------- \n");
break;
default:
LOG_N (OMG, "Unsupported generator\n");
}
}
} }
void update_nodes(double cur_time){ /*****************************************************************************/
void
update_nodes (double cur_time)
{
//LOG_D(OMG, "UPDATE NODES" ); //LOG_D(OMG, "UPDATE NODES" );
int i = 0; int i = 0;
for (i=(STATIC+1); i<MAX_NUM_MOB_TYPES; i++){ for (i = (STATIC + 1); i < MAX_NUM_MOB_TYPES; i++)
if (Node_Vector[i] != NULL){ {
//printf(" Mob model to update is: %d \n ", i); if (job_vector[i] != NULL)
LOG_I(OMG, " Mob model to update is: %d \n ", i); {
update_node_vector(i, cur_time); 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); //set_time(cur_time);
switch (mobility_type) { switch (mobility_type)
case RWP: {
update_rwp_nodes(cur_time); case RWP:
break; update_rwp_nodes (cur_time);
case RWALK:
update_rwalk_nodes(cur_time);
break;
case TRACE:
update_trace_nodes(cur_time);
break;
case SUMO:
// printf("in SUMO case \n");
update_sumo_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);
}
}
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) {
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];
break; break;
case RWALK: case RWALK:
get_rwalk_positions_updated(cur_time); update_rwalk_nodes (cur_time);
Vector = Node_Vector[RWALK];
break; break;
case TRACE: case TRACE:
get_trace_positions_updated(cur_time); update_trace_nodes (cur_time);
Vector = Node_Vector[TRACE]; break;
break;
case SUMO: case SUMO:
LOG_I(OMG,"getting positions from SUMO\n"); // printf("in SUMO case \n");
//printf("getting positions from SUMO\n"); update_sumo_nodes (cur_time);
Vector = get_sumo_positions_updated(cur_time); break;
// Vector = Node_Vector[SUMO]; case STEADY_RWP:
update_steadystaterwp_nodes (cur_time);
break; break;
default: default:
Vector = NULL; //printf("STATIC or Unsupported generator %d \n", omg_param_list.mobility_type);
LOG_N(OMG, " Unsupported generator %c \n", omg_param_list.mobility_type); LOG_N (OMG, "STATIC or Unsupported generator\n");
} }
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;
}
} }
/*********************************************************************************/
// get the position for a specific node /*return updated node position for a given node type*/
NodePtr get_node_position(int node_type, int nID){ node_list *
int found = 0; //not found get_current_positions (int mobility_type, int node_type, double cur_time)
int i=0; {
while ((i<MAX_NUM_MOB_TYPES) && (found == 0)){
if (Node_Vector[i] != NULL){
Node_list tmp = Node_Vector[i]; get_nodes_positions (mobility_type, cur_time);
while ((tmp != NULL) && (found == 0)){ return node_vector[node_type];
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 );
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){ /*update current position of nodes for specific mobility type*/
if (Node_Vector[mobility_type] != NULL){ void
Node_list Vector = NULL; get_nodes_positions (int mobility_type, double cur_time)
int done =1; {
switch (mobility_type) { //printf("%d \n",mobility_type);
case RWP:
Vector = Node_Vector[RWP]; switch (mobility_type)
{
case STATIC:
break; break;
case STATIC: case RWP:
Vector = Node_Vector[STATIC]; get_rwp_positions_updated (cur_time);
break; break;
case RWALK: case RWALK:
Vector = Node_Vector[RWALK]; get_rwalk_positions_updated (cur_time);
break;
case TRACE:
get_trace_positions_updated (cur_time);
break;
case 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; break;
default: default:
Vector = NULL; LOG_E (OMG, " Unsupported generator \n");
LOG_E(OMG, "Static or Unsupported generator %c \n", omg_param_list.mobility_type);
} }
if (Vector == NULL){
LOG_D(OMG, "\n Vector == NULL"); }
}
while (Vector != NULL){ /***************************************************************/
if (Vector->node->ID == nID && Vector->node->type == node_type){
done =0; // get the position for a specific node
display_node_position(Vector->node->ID, Vector->node->generator, Vector->node->type ,Vector->node->mobile, Vector->node->X_pos, Vector->node->Y_pos ); node_struct *
// 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); get_node_position (int node_type, int nid)
return Vector->node; {
} node_list *tmp;
Vector = Vector->next;
tmp = node_vector[node_type];
while (tmp != NULL)
{
if (tmp->node->id == nid)
return tmp->node;
tmp = tmp->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; 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() { /*set new mobility for a node*/
return m_time; void
}*/ set_new_mob_type (int id, int node_t, int mob_t, double cur_time)
{
int prev_mob;
node_list *tmp;
job_list *tmp2, *prev_job;
pair_struct *pair;
double pause_p;
//find previous mobility type
tmp = node_vector[node_t];
while (tmp != NULL)
{
if (tmp->node->id == id && tmp->node->type == node_t)
{
prev_mob = tmp->node->generator;
break;
}
tmp = tmp->next;
}
//end
if (tmp != NULL && prev_mob != mob_t)
{
//initialize node position
if (mob_t == STATIC || mob_t == RWP || mob_t == RWALK || mob_t == STEADY_RWP)
{
tmp->node->x_pos =
(double) ((int)
(randomgen
(omg_param_list[node_t].min_x,
omg_param_list[node_t].max_x) * 100)) / 100;
tmp->node->mob->x_from = tmp->node->x_pos;
tmp->node->mob->x_to = tmp->node->x_pos;
tmp->node->y_pos =
(double) ((int)
(randomgen
(omg_param_list[node_t].min_y,
omg_param_list[node_t].max_y) * 100)) / 100;
tmp->node->mob->y_from = tmp->node->y_pos;
tmp->node->mob->y_to = tmp->node->y_pos;
tmp->node->mob->speed = 0.0;
tmp->node->generator = mob_t;
if (prev_mob != STATIC)
job_vector[prev_mob] =
remove_job (job_vector[prev_mob], id, node_t);
}
//end
switch (mob_t)
{
case STATIC:
break;
case RWP:
pair = (pair_struct *) malloc (sizeof (struct pair_struct));
pair->b = tmp->node;
sleep_rwp_node (pair, cur_time);
job_vector[RWP] = addjob (pair, job_vector[RWP]);
break;
case RWALK:
pair = (pair_struct *) malloc (sizeof (struct pair_struct));
pair->b = tmp->node;
sleep_rwalk_node (pair, cur_time);
job_vector[RWALK] = addjob (pair, job_vector[RWALK]);
break;
case STEADY_RWP:
tmp->node->event_num = 0;
pair = (pair_struct *) malloc (sizeof (struct pair_struct));
pair->b = tmp->node;
pause_p = pause_probability (omg_param_list[node_t]);
if (randomgen (0, 1) < pause_p)
sleep_steadystaterwp_node (pair, cur_time);
else
move_steadystaterwp_node (pair, cur_time);
break;
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:
LOG_E (OMG, " Unsupported generator \n");
}
}
}
#ifdef STANDALONE #ifdef STANDALONE
void usage(void){
fprintf(stderr, "\n\t-X: assign maximum width of the simulation area (X_max)"\ /************************** get options ************************************/
"\n\t-x: assign minimum width of the simulation area (X_min)"\ void
"\n\t-Y: assign maximum height of the simulation area (Y_max)"\ usage (void)
"\n\t-y: assign minimum height of the simulation area (Y_min)"\ {
"\n\t-N: assign number of nodes"\ fprintf (stderr,
"\n\t-n: assign number of frames" \ "\n\t-X: assign maximum width of the simulation area for UE nodes(X_max)"
"\n\t-B: assign maximum duration of sleep/pause time (max_break)" "\n\t-x: assign minimum width of the simulation area for UE nodes(X_min)"
"\n\t-b: assign minimum duration of sleep/pause time (min_break)"\ "\n\t-C: assign maximum width of the simulation area for eNB nodes(X_max)"
"\n\t-J: assign maximum duration of journey (max_journey_time)"\ "\n\t-c: assign minimum width of the simulation area for eNB nodes(X_min)"
"\n\t-j: assign minimum duration of journey (min_journey_time)"\ "\n\t-B: assign maximum width of the simulation area for relay nodes(X_max)"
"\n\t-S: assign maximum speed "\ "\n\t-b: assign minimum width of the simulation area for relay nodes(X_min)"
"\n\t-s: assign minimum speed"\ "\n\t-Y: assign maximum height of the simulation area for UE nodes(Y_max)"
"\n\t-g: choose generator (STATIC: 0x00, RWP: 0x01, RWALK: 0x02, TRACE: 0x03 or SUMO: 0x04)\n"\ "\n\t-y: assign minimum height of the simulation area for UE nodes (Y_min)"
"\n\t-e: choose seed \n"\ "\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)"
exit(0); "\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[]){
char tag;
while ((tag = getopt(argc, argv, "vj:J:g:B:b:S:s:Y:y:X:x:n:N:he:t:")) != EOF) { int
get_options (int argc, char *argv[])
{
switch (tag) { int node_t;
char tag;
case 'N': while ((tag =
omg_param_list.nodes = atoi(optarg); getopt (argc, argv,
LOG_D(OMG, "Number of nodes : %d \n",omg_param_list.nodes); "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:"))
break; != EOF)
case 'n': {
n_frames = atof(optarg);
LOG_D(OMG, "Number of frames : %f \n",n_frames );
break; switch (tag)
case 't': {
omg_param_list.nodes_type = atoi(optarg);
LOG_D(OMG, "Type of nodes : %d \n",omg_param_list.nodes_type); case 'U':
break; if (atoi (optarg) < 0)
case 'b': {
omg_param_list.min_sleep = atof(optarg); usage ();
LOG_D(OMG, "min sleep : %.2f \n",omg_param_list.min_sleep); exit (1);
break; }
omg_param_list[UE].nodes = atoi (optarg);
case 'B': LOG_D (OMG, "#Number of UE nodes : %d \n",
omg_param_list.max_sleep = atof(optarg); omg_param_list[UE].nodes);
LOG_D(OMG, "max_sleep : %.2f \n",omg_param_list.max_sleep); break;
break;
case 'E':
case 's': if (atoi (optarg) < 0)
omg_param_list.min_speed = atof(optarg); {
LOG_D(OMG, "min_speed : %.2f \n",omg_param_list.min_speed); usage ();
break; exit (1);
}
case 'S': omg_param_list[eNB].nodes = atoi (optarg);
omg_param_list.max_speed = atof(optarg); LOG_D (OMG, "#Number of eNB nodes : %d \n",
LOG_D(OMG, "max_speed : %.2f \n",omg_param_list.max_speed); omg_param_list[eNB].nodes);
break; break;
case 'v':
omv_enabled = 1; case 'R':
break; if (atoi (optarg) < 0)
case 'X': {
omg_param_list.max_X = atof(optarg); usage ();
LOG_D(OMG, "X_max : %.2f \n",omg_param_list.max_X); exit (1);
break; }
case 'x': omg_param_list[RELAY].nodes = atoi (optarg);
omg_param_list.min_X = atof(optarg); LOG_D (OMG, "#Number of relay nodes : %d \n",
LOG_D(OMG, "X_min : %.2f \n",omg_param_list.min_X); omg_param_list[RELAY].nodes);
break; break;
case 'Y': case 'k':
omg_param_list.max_Y = atof(optarg); if (atof (optarg) < 0)
LOG_D(OMG, "Y_max : %.2f \n",omg_param_list.max_Y); LOG_E (OMG, "#Number of frames can not be negative \n");
break; n_frames = abs (atof (optarg));
LOG_D (OMG, "#Number of frames : %f \n", n_frames);
case 'y': break;
omg_param_list.min_Y = atof(optarg);
LOG_D(OMG, "Y_min : %.2f \n",omg_param_list.min_Y); case 'u':
break; if (atoi (optarg) < 0 || atoi (optarg) >= MAX_NUM_MOB_TYPES)
{
case 'J': usage ();
omg_param_list.max_journey_time = atof(optarg); exit (1);
LOG_D(OMG, "Journey_time_max : %.2f \n",omg_param_list.max_journey_time); }
break; omg_param_list[UE].mobility_type = atoi (optarg);
LOG_D (OMG, "#UE nodes mobility type: %d \n",
omg_param_list[UE].mobility_type);
case 'j': break;
omg_param_list.min_journey_time = atof(optarg);
LOG_D(OMG, "Journey_time_min : %.2f \n",omg_param_list.min_journey_time); case 'e':
break; if (atoi (optarg) < 0 || atoi (optarg) >= MAX_NUM_MOB_TYPES)
{
usage ();
case 'g': exit (1);
omg_param_list.mobility_type = atoi(optarg); }
LOG_D(OMG, "Mobility type is %d \n",omg_param_list.mobility_type); omg_param_list[eNB].mobility_type = atoi (optarg);
break; LOG_D (OMG, "#eNB nodes mobility type: %d \n",
omg_param_list[eNB].mobility_type);
case 'e': break;
omg_param_list.seed = atoi(optarg);
LOG_D(OMG, "Seed is %d \n",omg_param_list.seed ); case 'r':
break; if (atoi (optarg) < 0 || atoi (optarg) >= MAX_NUM_MOB_TYPES)
case 'h': {
usage(); usage ();
break; exit (1);
}
default: omg_param_list[RELAY].mobility_type = atoi (optarg);
usage(); LOG_D (OMG, "#relay nodes mobility type: %d \n",
exit(1); omg_param_list[RELAY].mobility_type);
} break;
case 's':
if (atof (optarg) < 0)
LOG_E (OMG, "#min sleep can not be negative \n");
omg_param_list[UE].min_sleep = fabs (atof (optarg));
LOG_D (OMG, "#UE min sleep is set to: %.2f \n",
omg_param_list[UE].min_sleep);
break;
case 'S':
if (atof (optarg) < 0)
LOG_E (OMG, "#max_sleep can not be negative \n");
omg_param_list[UE].max_sleep = fabs (atof (optarg));
LOG_D (OMG, "#UE max_sleep is set to : %.2f \n",
omg_param_list[UE].max_sleep);
break;
case 'l':
if (atof (optarg) < 0)
LOG_E (OMG, "#min sleep can not be negative or zero \n");
if (atof (optarg) != 0)
omg_param_list[eNB].min_sleep = fabs (atof (optarg));
LOG_D (OMG, "#eNB min sleep is set to : %.2f \n",
omg_param_list[eNB].min_sleep);
break;
case 'L':
if (atof (optarg) <= 0)
LOG_E (OMG, "#max_sleep can not be negative or zero \n");
if (atof (optarg) != 0)
omg_param_list[eNB].max_sleep = fabs (atof (optarg));
LOG_D (OMG, "#eNB max_sleep is set to : %.2f \n",
omg_param_list[eNB].max_sleep);
break;
case 'p':
if (atof (optarg) < 0)
LOG_E (OMG, "#min sleep can not be negative \n");
omg_param_list[RELAY].min_sleep = fabs (atof (optarg));
LOG_D (OMG, "#relay min sleep is set to: %.2f \n",
omg_param_list[RELAY].min_sleep);
break;
case 'P':
if (atof (optarg) < 0)
LOG_E (OMG, "#max_sleep can not be negative \n");
omg_param_list[RELAY].max_sleep = fabs (atof (optarg));
LOG_D (OMG, "#relay max_sleep is set to : %.2f \n",
omg_param_list[RELAY].max_sleep);
break;
case 'd':
if (atof (optarg) < 0)
LOG_E (OMG, "#min_speed can not be negative \n");
if (atof (optarg) != 0)
omg_param_list[UE].min_speed = fabs (atof (optarg));
LOG_D (OMG, "#UE min_speed is set to: %.2f \n",
omg_param_list[UE].min_speed);
break;
case 'D':
if (atof (optarg) < 0)
LOG_E (OMG, "#max_speed can not be negative \n");
omg_param_list[UE].max_speed = fabs (atof (optarg));
LOG_D (OMG, "#UE max_speed is set to: %.2f \n",
omg_param_list[UE].max_speed);
break;
case 'i':
if (atof (optarg) < 0)
LOG_E (OMG, "#min_speed can not be negative \n");
if (atof (optarg) != 0)
omg_param_list[eNB].min_speed = fabs (atof (optarg));
LOG_D (OMG, "#eNB min_speed is set to: %.2f \n",
omg_param_list[eNB].min_speed);
break;
case 'I':
if (atof (optarg) < 0)
LOG_E (OMG, "#max_speed can not be negative \n");
omg_param_list[eNB].max_speed = fabs (atof (optarg));
LOG_D (OMG, "#eNB max_speed is set to : %.2f \n",
omg_param_list[eNB].max_speed);
break;
case 'a':
if (atof (optarg) < 0)
LOG_E (OMG, "#min_speed can not be negative \n");
if (atof (optarg) != 0)
omg_param_list[RELAY].min_speed = fabs (atof (optarg));
LOG_D (OMG, "#relay min_speed is set to : %.2f \n",
omg_param_list[RELAY].min_speed);
break;
case 'A':
if (atof (optarg) < 0)
LOG_E (OMG, "#max_speed can not be negative \n");
omg_param_list[RELAY].max_speed = fabs (atof (optarg));
LOG_D (OMG, "#relay max_speed is set to: %.2f \n",
omg_param_list[RELAY].max_speed);
break;
case 'v':
omv_enabled = 1;
break;
case 'X':
omg_param_list[UE].max_x = fabs (atof (optarg));
LOG_D (OMG, "#UE X_max : %.2f \n", omg_param_list[UE].max_x);
break;
case 'x':
omg_param_list[UE].min_x = fabs (atof (optarg));
LOG_D (OMG, "#UE X_min : %.2f \n", omg_param_list[UE].min_x);
break;
case 'C':
omg_param_list[eNB].max_x = fabs (atof (optarg));
LOG_D (OMG, "#eNB X_max : %.2f \n", omg_param_list[eNB].max_x);
break;
case 'c':
omg_param_list[eNB].min_x = fabs (atof (optarg));
LOG_D (OMG, "#eNB X_min : %.2f \n", omg_param_list[eNB].min_x);
break;
case 'B':
omg_param_list[RELAY].max_x = fabs (atof (optarg));
LOG_D (OMG, "#relay X_max : %.2f \n", omg_param_list[RELAY].max_x);
break;
case 'b':
omg_param_list[RELAY].min_x = fabs (atof (optarg));
LOG_D (OMG, "#relay X_min : %.2f \n", omg_param_list[RELAY].min_x);
break;
case 'Y':
omg_param_list[UE].max_y = fabs (atof (optarg));
LOG_D (OMG, "#UE Y_max : %.2f \n", omg_param_list[UE].max_y);
break;
case 'y':
omg_param_list[UE].min_y = fabs (atof (optarg));
LOG_D (OMG, "#UE Y_min : %.2f \n", omg_param_list[UE].min_y);
break;
case 'Z':
omg_param_list[eNB].max_y = fabs (atof (optarg));
LOG_D (OMG, "#eNB Y_max : %.2f \n", omg_param_list[eNB].max_y);
break;
case 'z':
omg_param_list[eNB].min_y = fabs (atof (optarg));
LOG_D (OMG, "#eNB Y_min : %.2f \n", omg_param_list[eNB].min_y);
break;
case 'W':
omg_param_list[RELAY].max_y = fabs (atof (optarg));
LOG_D (OMG, "#relay Y_max : %.2f \n", omg_param_list[RELAY].max_y);
break;
case 'w':
omg_param_list[RELAY].min_y = fabs (atof (optarg));
LOG_D (OMG, "#relay Y_min : %.2f \n", omg_param_list[RELAY].min_y);
break;
case 'J':
if (atof (optarg) < 0)
LOG_E (OMG, "#Journey_time_max can not be negative \n");
omg_param_list[UE].max_journey_time = fabs (atof (optarg));
LOG_D (OMG, "UE Journey_time_max : %.2f \n",
omg_param_list[UE].max_journey_time);
break;
case 'j':
if (atof (optarg) < 0)
LOG_E (OMG, "#Journey_time_min can not be negative \n");
omg_param_list[UE].min_journey_time = fabs (atof (optarg));
LOG_D (OMG, "#UE Journey_time_min : %.2f \n",
omg_param_list[UE].min_journey_time);
break;
case 'T':
if (atof (optarg) < 0)
LOG_E (OMG, "#Journey_time_max can not be negative \n");
omg_param_list[eNB].max_journey_time = fabs (atof (optarg));
LOG_D (OMG, "#eNB Journey_time_max : %.2f \n",
omg_param_list[eNB].max_journey_time);
break;
case 't':
if (atof (optarg) < 0)
LOG_E (OMG, "#Journey_time_min can not be negative \n");
omg_param_list[eNB].min_journey_time = fabs (atof (optarg));
LOG_D (OMG, "#eNB Journey_time_min : %.2f \n",
omg_param_list[eNB].min_journey_time);
break;
case 'N':
if (atof (optarg) < 0)
LOG_E (OMG, "#Journey_time_max can not be negative \n");
omg_param_list[RELAY].max_journey_time = fabs (atof (optarg));
LOG_D (OMG, "#relay Journey_time_max : %.2f \n",
omg_param_list[RELAY].max_journey_time);
break;
case 'n':
if (atof (optarg) < 0)
LOG_E (OMG, "#Journey_time_min can not be negative \n");
omg_param_list[RELAY].min_journey_time = fabs (atof (optarg));
LOG_D (OMG, "#relay Journey_time_min : %.2f \n",
omg_param_list[RELAY].min_journey_time);
break;
case 'f':
for (node_t = eNB; node_t < MAX_NUM_NODE_TYPES; node_t++)
{
omg_param_list[node_t].seed = atoi (optarg);
LOG_D (OMG, "#Seed is %d \n", omg_param_list[node_t].seed);
}
break;
case 'g':
if (atoi (optarg) < 1 || atoi (optarg) > 2)
{
LOG_E (OMG, "#value given for graph should be 1 or 2 \n");
exit (-1);
}
grid = abs (atof (optarg));
LOG_D (OMG, "#graph value is %d \n", grid);
break;
case 'h':
usage ();
break;
default:
usage ();
exit (1);
} }
return 0; }
return 1;
} }
int main(int argc, char *argv[]) { /**************************** main **********************************/
int i;
double cur_time=0.0; int
//srand(time(NULL)); main (int argc, char *argv[])
double ms=0.0; {
Node_list Current_positions = NULL; int i, node_type;
NodePtr my_node = NULL; double cur_time = 0.0;
int my_ID = 0; double ms = 0.0;
double emu_info_time; node_list *current_positions = NULL;
//omv node_struct *my_node = NULL;
char full_name[200]; int my_id = 0, time_s;
int pfd[2]; // fd for omv : fixme: this could be a local var double emu_info_time;
char full_name[200];
int pfd[2]; // fd for omv : fixme: this could be a local var
char fdstr[10]; char fdstr[10];
char frames[10]; char frames[10];
char num_enb[10]; char num_enb[10];
char num_ue[10]; char num_ue[10];
//area_x, area_y and area_z for omv //area_x, area_y and area_z for omv
char x_area[20]; char x_area[20];
char y_area[20]; char y_area[20];
char z_area[20]; char z_area[20];
char fname[64],vname[64]; char fname[64], vname[64];
Data_Flow_Unit omv_data ; Data_Flow_Unit omv_data;
//float n_frames=200.0;
omg_param_list.nodes = 200; //default parameters
omg_param_list.min_X = 0; for (node_type = eNB; node_type < MAX_NUM_NODE_TYPES; node_type++)
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; if (node_type == UE)
omg_param_list.max_speed = 20.0; omg_param_list[node_type].nodes = 5;
omg_param_list.min_journey_time = 0.1; else
omg_param_list.max_journey_time = 10.0; omg_param_list[node_type].nodes = 0;
omg_param_list.min_azimuth = 0; omg_param_list[node_type].min_x = 0;
omg_param_list.max_azimuth = 360; omg_param_list[node_type].max_x = 100;
omg_param_list.min_sleep = 0.1; omg_param_list[node_type].min_y = 0;
omg_param_list.max_sleep = 5.0; omg_param_list[node_type].max_y = 100;
omg_param_list.mobility_file = "TRACE/example_trace.tr"; omg_param_list[node_type].min_speed = 0.1;
omg_param_list.sumo_command = "sumo-gui"; omg_param_list[node_type].max_speed = 20.0;
omg_param_list.sumo_config = "SUMO/SCENARIOS/traci.scen.sumo.cfg"; omg_param_list[node_type].min_journey_time = 0.1;
// omg_param_list.sumo_config = "SUMO/SCENARIOS/traci.koln.sumo.cfg"; omg_param_list[node_type].max_journey_time = 20.0;
omg_param_list.sumo_start = 0;//25900; omg_param_list[node_type].min_azimuth = 0;
omg_param_list.sumo_end = 200;//26200; omg_param_list[node_type].max_azimuth = 360;
omg_param_list.sumo_step = 1; omg_param_list[node_type].min_sleep = 0.1;
omg_param_list.sumo_host = "localhost"; omg_param_list[node_type].max_sleep = 5.0;
omg_param_list.sumo_port = 8890; omg_param_list[node_type].mobility_file = "TRACE/mobility_3ues.tr";
omg_param_list.mobility_type = STATIC; omg_param_list[node_type].mobility_type = STATIC;
omg_param_list.nodes_type = UE; omg_param_list[node_type].nodes_type = node_type;
// overwrite the default params if defined //omg_param_list.sumo_config = "SUMO/SCENARIOS/traci.koln.sumo.cfg";
get_options(argc, argv); omg_param_list[node_type].sumo_command = "sumo-gui";
omg_param_list[node_type].sumo_config =
// check if we are out of range "SUMO/SCENARIOS/traci.scen.sumo.cfg";
if(omg_param_list.max_X == 0.0 || omg_param_list.max_Y == 0.0 ) { omg_param_list[node_type].sumo_start = 0; //25900;
usage(); omg_param_list[node_type].sumo_end = 200; //26200;
exit(1); omg_param_list[node_type].sumo_step = 1;
} omg_param_list[node_type].sumo_host = "localhost";
omg_param_list[node_type].sumo_port = 8890;
}
//char sumo_line[300]; init_omg_global_params (); //initialize global paramaters
//printf("TEST %s \n", sumo_line); get_options (argc, argv); // overwrite the default params if any input parameter
// 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); for (node_type = eNB; node_type < MAX_NUM_NODE_TYPES; node_type++)
{
//printf("%s \n",sumo_line); omg_param_list[node_type].max_vertices =
max_vertices_ongrid (omg_param_list[node_type]);
//pid_t pid; omg_param_list[node_type].max_block_num =
//pid_t cpid; max_connecteddomains_ongrid (omg_param_list[node_type]);
// 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);
init_mobility_generator (omg_param_list); //initialize choosen mobility generator
//char kill_line[300]; // ****************init omv********************
if (omv_enabled == 1)
{
if (pipe (pfd) == -1)
perror ("pipe error \n");
//printf("TEST %s \n", sumo_line); 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]);
//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);*/
switch (fork ())
/////////////// to call by OCG {
// init omv case -1:
if (omv_enabled == 1) { perror ("fork failed \n");
if(pipe(pfd) == -1) break;
perror("pipe error \n"); case 0:
if (close (pfd[1]) == -1)
sprintf(full_name, "%s/UTIL/OMV/OMV",getenv("OPENAIR2_DIR")); perror ("close on write\n");
LOG_I(EMU,"Stating the OMV path %s pfd[0] %d pfd[1] %d \n", full_name, pfd[0],pfd[1]); sprintf (fdstr, "%d", pfd[0]);
sprintf (num_enb, "%d", 1);
switch(fork()) { sprintf (num_ue, "%d", omg_param_list[UE].nodes);
case -1 : sprintf (x_area, "%f", omg_param_list[UE].max_x);
perror("fork failed \n"); sprintf (y_area, "%f", omg_param_list[UE].max_y);
break; sprintf (z_area, "%f", 200.0);
case 0 : sprintf (frames, "%d", (int) n_frames);
if(close(pfd[1]) == -1 )
perror("close on write\n" ); execl (full_name, "OMV", fdstr, frames, num_enb, num_ue, x_area,
sprintf(fdstr, "%d", pfd[0] ); y_area, z_area, NULL);
sprintf(num_enb, "%d", 1); perror ("error in execl the OMV");
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" );
}
//parent
if(close( pfd[0] ) == -1 )
perror("close on read\n" );
} }
//parent
for (emu_info_time = 0.0 ; emu_info_time <= n_frames; emu_info_time+=0.1){ if (close (pfd[0]) == -1)
//printf("updating node positions\n"); perror ("close on read\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){ for (emu_info_time = 0.0; emu_info_time <= n_frames; emu_info_time += 0.1)
LOG_D(OMG, " mob model %d \n ", i); {
update_nodes(i ,emu_info_time);
} update_nodes (emu_info_time);
else {LOG_D( "nodes are STATIC\n"); } time_s = round (emu_info_time * 1000.0);
}*/ //printf("%d \n",time_s);
printf(" **********asking for positions in %d **********\n ", omg_param_list.mobility_type); for (node_type = eNB; node_type < MAX_NUM_NODE_TYPES; node_type++)
Current_positions = get_current_positions(omg_param_list.mobility_type, {
omg_param_list.nodes_type, current_positions =
emu_info_time); // type: enb, ue, all get_current_positions (omg_param_list[node_type].mobility_type,
node_type, emu_info_time);
if(Current_positions !=NULL) {
printf(" **********Current_positions at time %f**********\n ",emu_info_time); if (current_positions != NULL)
display_node_list(Current_positions);
printf(" **********DONE**********\n "); display_job_list (emu_info_time,
if (omv_enabled == 1) job_vector[omg_param_list
omv_write(pfd[1], Current_positions, omv_data); [node_type].mobility_type]);
}
/*if(current_positions!= NULL && time_s %1000==0)
} LOG_D(OMG, "%.2f %d\n",emu_info_time,
stop_mobility_generator(omg_param_list.mobility_type); nodes_avgspeed(job_vector[omg_param_list [node_type].mobility_type])); */
}
/*LOG_D(OMG, " **********DISPLAY JOB LIST**********\n ");
display_job_list(Job_Vector);
emu_info_time = 10.0;*/ //display current postion of nodes
if (omv_enabled == 1)
omv_write (pfd[1], node_vector[SUMO], omv_data);
//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);
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; return 0;
} }
int omv_write (int pfd, Node_list ue_node_list, Data_Flow_Unit omv_data){ /**********************************sumo****************************/
int i=0,j; int
omv_data.end=0; omv_write (int pfd, node_list * ue_node_list, Data_Flow_Unit omv_data)
{
int i = 0, j;
omv_data.end = 0;
// enb // enb
omv_data.geo[i].x = 0.0; omv_data.geo[i].x = 0.0;
omv_data.geo[i].y = 0.0; omv_data.geo[i].y = 0.0;
omv_data.geo[i].z = 1.0; omv_data.geo[i].z = 1.0;
omv_data.geo[i].mobility_type = 0; omv_data.geo[i].mobility_type = 0;
omv_data.geo[i].node_type = 0; //eNB omv_data.geo[i].node_type = 0; //eNB
omv_data.geo[i].Neighbors=0; omv_data.geo[i].Neighbors = 0;
for (i=1;i<omg_param_list.nodes+1;i++) { 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; if (ue_node_list != NULL)
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].x =
omv_data.geo[i].mobility_type = omg_param_list.mobility_type; (int) (ue_node_list->node->x_pos <
omv_data.geo[i].node_type = 1; //UE 0.0) ? 0.0 : ue_node_list->node->x_pos;
ue_node_list = ue_node_list->next; omv_data.geo[i].y =
omv_data.geo[i].Neighbors=0; (int) (ue_node_list->node->y_pos <
printf("node %d at (%d, %d)\n", i, omv_data.geo[i].x ,omv_data.geo[i].y ); 0.0) ? 0.0 : ue_node_list->node->y_pos;
omv_data.geo[i].z = 1.0;
omv_data.geo[i].mobility_type = omg_param_list[SUMO].mobility_type;
omv_data.geo[i].node_type = 1; //UE
ue_node_list = ue_node_list->next;
omv_data.geo[i].Neighbors = 0;
printf ("node %d at (%d, %d)\n", i, omv_data.geo[i].x,
omv_data.geo[i].y);
}
} }
}
if (write (pfd, &omv_data, sizeof (struct Data_Flow_Unit)) == -1)
if( write( pfd, &omv_data, sizeof(struct Data_Flow_Unit) ) == -1 ) perror ("write omv failed");
perror( "write omv failed" );
return 1; return 1;
} }
void omv_end (int pfd, Data_Flow_Unit omv_data) {
omv_data.end=1;
if( write( pfd, &omv_data, sizeof(struct Data_Flow_Unit) ) == -1 )
perror( "write omv failed" );
}
#endif
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 @@ ...@@ -30,7 +30,7 @@
/*! \file OMG.h /*! \file OMG.h
* \brief Prototypes of OMG functions that may be called by OCG * \brief Prototypes of OMG functions that may be called by OCG
* \author M. Mahersi, N. Nikaein, J. Harri * \author M. Mahersi, N. Nikaein, J. Harri
* \date 2011 * \date 2011 - 2014
* \version 0.1 * \version 0.1
* \company Eurecom * \company Eurecom
* \email: * \email:
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "omg_constants.h" #include "omg_constants.h"
#include "defs.h" #include "defs.h"
#include "omg_vars.h" #include "omg_vars.h"
#if STANDALONE #if STANDALONE
#define LOG_G(c, x...) printf(x) #define LOG_G(c, x...) printf(x)
#define LOG_A(c, x...) printf(x) #define LOG_A(c, x...) printf(x)
...@@ -57,6 +58,8 @@ ...@@ -57,6 +58,8 @@
#else #else
#include "UTIL/LOG/log.h" #include "UTIL/LOG/log.h"
#endif #endif
/** @defgroup _omg OpenAir Mobility Generation (OMG) /** @defgroup _omg OpenAir Mobility Generation (OMG)
...@@ -195,14 +198,14 @@ void init_omg_global_params(void); ...@@ -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 * \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 * \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) * \fn void stop_mobility_generator(int mobility_type)
* \brief Call the destructor for the respective mobility type. * \brief Call the destructor for the respective mobility type.
* \param int mobility_type to stop and call destructor * \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) * \fn void update_nodes(double cur_time)
...@@ -220,9 +223,9 @@ 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 * \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 * \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) * \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 */ ...@@ -45,14 +45,29 @@ RWP, /*!< Random Way Point mobility model */
RWALK, /*!< Random Walk mobility model */ RWALK, /*!< Random Walk mobility model */
TRACE, /*!< Trace-based Mobility description file */ TRACE, /*!< Trace-based Mobility description file */
SUMO, /*!< SUMO-based mobility model */ 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 */ MAX_NUM_MOB_TYPES /*!< The maximum number of mobility models. Used to adjust the length of the #Node_Vector */
}mobility_types; }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 */ /*! The available nodes types */
typedef enum { typedef enum {
eNB=0, /*!< enhanced Node B */ eNB=0, /*!< enhanced Node B */
UE, /*!< User Equipement */ 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; }node_types;
...@@ -60,6 +75,11 @@ ALL /*!< All the types. Used to perform the same operations to all the types of ...@@ -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 */ /*! A constant used to compare two doubles */
#define eps 0.10 //10.99 #define eps 0.10 //10.99
#define SLEEP 1
#define GET_DATA 0
#define GET_DATA_UPDATE 1
#endif /* __OMG_H_ */ #endif /* __OMG_H_ */
...@@ -39,21 +39,29 @@ ...@@ -39,21 +39,29 @@
#include "omg.h" #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 */ /*!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 */ /*! 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 */ /*!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 */ /*! 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*/ /*! 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; //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__ */ #endif /* __OMG_VARS_H__ */
...@@ -29,8 +29,8 @@ ...@@ -29,8 +29,8 @@
/*! \file rwalk.c /*! \file rwalk.c
* \brief random walk mobility generator * \brief random walk mobility generator
* \author M. Mahersi, J. Harri, N. Nikaein, * \author S. Gashaw, N. Nikaein, J. Harri, M. Mahersi
* \date 2011 * \date 2014
* \version 0.1 * \version 0.1
* \company Eurecom * \company Eurecom
* \email: * \email:
...@@ -41,422 +41,478 @@ ...@@ -41,422 +41,478 @@
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include <math.h> #include <math.h>
#include "rwalk.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; double cur_time = 0.0, pause_p, mean_pause, mean_travel;
NodePtr node = NULL; node_struct *node = NULL;
MobilityPtr mobility = NULL; mobility_struct *mobility = NULL;
pair_struct *pair = NULL;
if (omg_param_list.nodes <= 0){
LOG_W(OMG, "Number of nodes has not been set\n"); srand (omg_param_list.seed + RWALK);
return(-1);
} mean_pause = (omg_param_list.max_sleep - omg_param_list.min_sleep) / 2;
mean_travel =
if (omg_param_list.nodes_type == eNB) { (omg_param_list.max_journey_time - omg_param_list.min_journey_time) / 2;
LOG_I(OMG, "Node type has been set to eNB\n"); pause_p = mean_pause / (mean_travel + mean_pause);
} else if (omg_param_list.nodes_type == UE) {
LOG_I(OMG, "Node type has been set to UE\n"); LOG_I (OMG, "#RWALK mobility model for %d %d nodes\n", omg_param_list.nodes,
} omg_param_list.nodes_type);
LOG_I(OMG, "Number of random walk nodes has been set to %d\n", omg_param_list.nodes);
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 ();
node = (NodePtr) create_node(); mobility = create_mobility ();
mobility = (MobilityPtr) create_mobility();
node->mobile = 0; // static for the moment
node->ID = n_id;
node->type = omg_param_list.nodes_type;
node->generator = omg_param_list.mobility_type;
node->mob = mobility;
place_rwalk_node(node); //initial positions
Pair pair = malloc (sizeof(Pair));
pair = (Pair) sleep_rwalk_node(node, cur_time); //sleep
Job_Vector = add_job(pair, Job_Vector);
Job_Vector_len ++;
if (Job_Vector == NULL)
LOG_E(OMG, "Job Vector is NULL\n");
}
return(0);
}
node->id = id;
node->type = omg_param_list.nodes_type;
node->mob = mobility;
node->generator = RWALK;
node->event_num = 0;
place_rwalk_node (node); //initial positions
void place_rwalk_node(NodePtr node) { 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
node->X_pos = (double) ((int) (randomGen(omg_param_list.min_X, omg_param_list.max_X)*100))/ 100; if (randomgen (0, 1) < pause_p)
node->mob->X_from = node->X_pos; sleep_steadystaterwp_node (pair, cur_time); //sleep
node->mob->X_to = node->X_pos; else
node->Y_pos = (double) ((int) (randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100; move_steadystaterwp_node (pair, cur_time);
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 "); job_vector_end[RWALK] = add_job (pair, job_vector_end[RWALK]);
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]); if (job_vector[RWALK] == NULL)
Node_Vector_len[RWALK]++; job_vector[RWALK] = job_vector_end[RWALK];
//Initial_Node_Vector_len[RWALK]++;
job_vector_len[RWALK]++;
}
n_id += omg_param_list.nodes;
if (job_vector[RWALK] == NULL)
LOG_E (OMG, "[RWP] Job Vector is NULL\n");
return (0);
} }
Pair sleep_rwalk_node(NodePtr node, double cur_time){ void
node->mobile = 0; place_rwalk_node (node_struct * node)
node->mob->speed = 0.0; {
node->mob->X_from = node->mob->X_to; node->x_pos =
node->mob->Y_from = node->mob->Y_to; (double) ((int)
node->X_pos = node->mob->X_to; (randomgen
node->Y_pos = node->mob->Y_to; (omg_param_list[node->type].min_x,
Pair pair = malloc(sizeof(Pair)) ; 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_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]++;
}
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->start_journey = cur_time; void
pair->a = node->mob->start_journey + node->mob->sleep_duration; //when to wake up sleep_rwalk_node (pair_struct * pair, double cur_time)
LOG_D(OMG, "to wake up at time: cur_time + sleep_duration : %.2f\n", pair->a); {
pair->b = node; 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->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->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)); void
LOG_D(OMG, "MOVE RWALK NODE ID: %d\n",node->ID); move_rwalk_node (pair_struct * pair, double cur_time)
{
node->X_pos = node->mob->X_to; double distance, x_next, y_next, journeytime_next;
node->Y_pos = node->mob->Y_to; int i = 0;
node->mob->X_from = node->X_pos; double dx, dy, x_now, y_now;
node->mob->Y_from = node->Y_pos; double alpha, distancex, distancey;
node->mobile = 1; node_struct *node;
double speed_next = randomGen(omg_param_list.min_speed, omg_param_list.max_speed); node = pair->b;
node->mob->speed = speed_next; //LOG_D (OMG, "MOVE RWALK NODE ID: %d\n", node->ID);
LOG_D(OMG, "speed_next: %f\n", speed_next); //m/s node->mob->x_from = node->mob->x_to;
node->mob->y_from = node->mob->y_to;
double azimuth_next = randomGen(omg_param_list.min_azimuth, omg_param_list.max_azimuth); node->x_pos = node->mob->x_to;
node->mob->azimuth = azimuth_next; node->y_pos = node->mob->y_to;
LOG_D(OMG, "azimuth_next: %f\n", node->mob->azimuth); node->mobile = 1;
double journeyTime_next = randomGen(omg_param_list.min_journey_time, omg_param_list.max_journey_time); node->mob->speed =
node->mob->journey_time = journeyTime_next; randomgen (omg_param_list[node->type].min_speed,
LOG_D(OMG, "journey_time_next: %f\n", node->mob->journey_time); omg_param_list[node->type].max_speed);
double distance = node->mob->speed * node->mob->journey_time; node->mob->azimuth =
LOG_D(OMG, "distance = speed * journey_time: %f\n", distance); randomgen (omg_param_list[node->type].min_azimuth,
omg_param_list[node->type].max_azimuth);
double dX = distance * cos(node->mob->azimuth*M_PI/180); if (node->event_num == 0)
LOG_D(OMG, "dX = distance * cos(azimuth): %f\n", dX); {
double dY = distance * sin(node->mob->azimuth*M_PI/180); node->mob->journey_time = residualtime (omg_param_list[node->type]);
LOG_D(OMG, "dY = distance * sin(azimuth): %f\n", dY); node->event_num++;
}
LOG_D(OMG, "from: (%.2f, %.2f)\n", node->X_pos, node->Y_pos); else
double X_next = (double) ((int)((node->X_pos + dX) *100))/ 100; {
double Y_next = (double) ((int)((node->X_pos + dY) *100))/ 100; node->mob->journey_time =
LOG_D(OMG, "theoritical_destination: (%f, %f)\n", X_next, Y_next); randomgen (omg_param_list[node->type].min_journey_time,
omg_param_list[node->type].max_journey_time);
/*if (X_next<param_list.min_X){ // first method }
node->mob->X_to = param_list.min_X; distance = node->mob->speed * node->mob->journey_time;
dx = distance * cos (node->mob->azimuth * M_PI / 180);
dy = distance * sin (node->mob->azimuth * M_PI / 180);
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); */
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);
} }
else if (X_next>param_list.max_X){ else if (x_next > omg_param_list[node->type].max_x)
node->mob->X_to = param_list.max_X; {
distancex =
(omg_param_list[node->type].max_x - x_now) / cos (alpha);
} }
else { else
node->mob->X_to = X_next; {
distancex = distance;
} }
if (Y_next<param_list.min_Y){ if (y_next < omg_param_list[node->type].min_y)
node->mob->Y_to = param_list.min_Y; {
distancey =
(omg_param_list[node->type].min_y - y_now) / sin (alpha);
} }
else if (Y_next>param_list.max_Y){ else if (y_next > omg_param_list[node->type].max_y)
node->mob->Y_to = param_list.max_Y; {
distancey =
(omg_param_list[node->type].max_y - y_now) / sin (alpha);
} }
else { else
node->mob->Y_to = Y_next; {
}*/ distancey = distance;
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;
} }
if (Y_next < omg_param_list.min_Y){
while (Y_next < omg_param_list.min_Y){ if ((distancex == distance && distancey == distance))
Y_next = Y_next + omg_param_list.max_Y; break;
}
node->mob->Y_to = Y_next;
}
else if (Y_next > omg_param_list.max_Y){ if (distancey < distancex)
while (Y_next > omg_param_list.max_Y){ {
Y_next = Y_next - omg_param_list.max_Y;
} x_now = distancey * cos (alpha) + x_now;
node->mob->Y_to = Y_next; 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;
} }
else { else if (distancex < distancey)
node->mob->Y_to = Y_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;
} }
i++;
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 );
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;
}
}
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++;
}
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 );
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;
}
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) != (RWALK=%d)\n ",tmp->pair->a, cur_time, tmp->pair->b->generator, RWALK );
tmp = tmp->next;
}
}
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 );
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);
} }
void get_rwalk_positions_updated(double cur_time){ double
residualtime (omg_global_param omg_param)
double X_now=0.0; {
double Y_now=0.0; double u;
LOG_D(OMG,"--------GET RWALK POSITIONS--------\n"); u = randomgen (0, 1);
Pair my_pair = Job_Vector->pair; if (u <
if ( my_pair ==NULL) { (2 * omg_param.min_sleep /
LOG_E(OMG, "my_pair ==NULL"); (omg_param.max_journey_time + omg_param.min_journey_time)))
} return u * (omg_param.max_journey_time + omg_param.min_journey_time) / 2;
else if ( (my_pair !=NULL) && (cur_time <= my_pair->a ) ){ else
LOG_D(OMG," %.2f <= %.2f \n",cur_time, my_pair->a); return omg_param.max_journey_time -
Job_list tmp = Job_Vector; sqrtf ((1 - u) * (pow (omg_param.max_journey_time, 2) -
while (tmp != NULL){ pow (omg_param.min_sleep, 2)));
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"); void
} update_rwalk_nodes (double cur_time)
else if (tmp->pair->b->mobile == 1){ //node is moving {
LOG_T(OMG,"Node_number %d\n", tmp->pair->b->ID); int done = 0;
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); job_list *tmp = job_vector[RWALK];
node_struct *my_node;
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)); while (tmp != NULL && done == 0)
double dx = fabs(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to) / len; {
my_node = (node_struct *) tmp->pair->b;
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); //case1:time to next event equals to current time
if (tmp->pair->b->mob->X_from < tmp->pair->b->mob->X_to ){ if (tmp->pair != NULL
X_now = tmp->pair->b->mob->X_from + (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey) ) ); && ((double) tmp->pair->next_event_t >= cur_time - eps)
} && ((double) tmp->pair->next_event_t <= cur_time + eps))
else{ {
X_now = tmp->pair->b->mob->X_from - (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey))); if (my_node->mobile == 1)
} sleep_rwalk_node (tmp->pair, cur_time);
else
if (tmp->pair->b->mob->Y_from < tmp->pair->b->mob->Y_to ){ move_rwalk_node (tmp->pair, cur_time);
Y_now = tmp->pair->b->mob->Y_from + (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
} }
else{ //case2: current time is greater than the time to next event
Y_now = tmp->pair->b->mob->Y_from - (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
} else if (tmp->pair != NULL
&& (cur_time - eps) > tmp->pair->next_event_t)
{
LOG_D(OMG,"X_now %f\tY_now %f\n", X_now, Y_now);
while (cur_time >= tmp->pair->next_event_t)
if (X_now < omg_param_list.min_X){ {
while (X_now < omg_param_list.min_X){ if (my_node->mobile == 1)
X_now = X_now + omg_param_list.max_X; sleep_rwalk_node (tmp->pair, cur_time);
} else
} move_rwalk_node (tmp->pair, cur_time);
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;
}
}
else {
X_now = X_now;
}
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;
}
}
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 {
Y_now = Y_now;
}
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 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 { //case3: current time less than the time to next event
LOG_E(OMG,"ERROR current time %f > first job_time %f\n", cur_time, my_pair->a); 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[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)
{
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];
while (tmp != NULL)
{
/*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 if (tmp->pair->b->mobile == 1 && tmp->pair->next_event_t >= cur_time)
{
LOG_D(OMG,"--------UPDATE--------\n");
int l = 0; len =
tmp->pair->b->mob->speed * (cur_time -
Job_list tmp = Job_Vector; tmp->pair->b->mob->start_journey);
while (l < Job_Vector_len){
LOG_D(OMG,"l == %d \n", l); dx = len * cos (tmp->pair->b->mob->azimuth * M_PI / 180);
Pair my_pair = tmp->pair; dy = len * sin (tmp->pair->b->mob->azimuth * M_PI / 180);
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)) { x_next =
LOG_D(OMG,"%.2f == %.2f \n ",my_pair->a, cur_time ); (double) ((int) ((tmp->pair->b->mob->x_from + dx) * 100)) / 100;
if (my_pair->b->generator == RWALK) { y_next =
LOG_D(OMG," UPDATE RWALK \n "); (double) ((int) ((tmp->pair->b->mob->y_from + dy) * 100)) / 100;
NodePtr my_node= (NodePtr)my_pair->b;
//if(my_node->mobile == 1) {
// LOG_D(OMG," move again \n" ); alpha = (tmp->pair->b->mob->azimuth * M_PI / 180); //in radian
// // stop node and let it sleep x_now = tmp->pair->b->mob->x_from;
// my_node->mobile = 0; y_now = tmp->pair->b->mob->y_from;
// Pair pair = malloc(sizeof(Pair));
// pair = sleep_rwalk_node(my_node, cur_time); while (true)
// Job_Vector->pair = pair; {
//}
if ((my_node->mobile ==0) ||( my_node->mobile == 1)) { if (x_next < omg_param_list[tmp->pair->b->type].min_x)
LOG_D(OMG," ...let's move again \n" ); {
// ...let's move again distancex =
my_node->mobile = 1; (omg_param_list[tmp->pair->b->type].min_x -
Pair pair = malloc(sizeof(Pair)); x_now) / cos (alpha);
pair = move_rwalk_node(my_node, cur_time); }
Job_Vector->pair = pair; else if (x_next > omg_param_list[tmp->pair->b->type].max_x)
} {
else{ distancex =
LOG_E(OMG, "update_generator: unsupported node state - mobile : %d \n", my_node->mobile); (omg_param_list[tmp->pair->b->type].max_x -
} x_now) / cos (alpha);
//sorting the new entries }
LOG_D(OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T else
display_job_list(Job_Vector); {
Job_Vector = quick_sort (Job_Vector); ////////// distancex = len;
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);
}
}
}*/
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
{
distancey = len;
}
if (distancex == len && distancey == len)
break;
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;
}
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) ; ...@@ -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 * \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 * \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) * \fn Pair sleep_rwalk_node(NodePtr node, double cur_time)
...@@ -58,7 +58,7 @@ void place_rwalk_node(NodePtr node) ; ...@@ -58,7 +58,7 @@ void place_rwalk_node(NodePtr node) ;
* \param cur_time a variable of type double that represents the current time * \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 * \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) ; ...@@ -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 * \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 * \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) * \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 ...@@ -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) ; void get_rwalk_positions_updated(double cur_time) ;
/*for perfect simulation of random walk*/
double residualtime(omg_global_param omg_param);
#endif /* RWALK_H_ */ #endif /* RWALK_H_ */
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
/*! \file rwp.c /*! \file rwp.c
* \brief random waypoint mobility generator * \brief random waypoint mobility generator
* \author M. Mahersi, J. Harri, N. Nikaein, * \author M. Mahersi, N. Nikaein, J. Harri
* \date 2011 * \date 2011
* \version 0.1 * \version 0.1
* \company Eurecom * \company Eurecom
...@@ -43,329 +43,405 @@ ...@@ -43,329 +43,405 @@
#include <time.h> #include <time.h>
#include <math.h> #include <math.h>
#include "rwp.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);
double cur_time = 0.0;
NodePtr node = NULL;
MobilityPtr mobility = NULL;
if (omg_param_list.nodes <= 0){
LOG_W(OMG,"[RWP] Number of nodes has not been set\n");
return(-1);
}
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);
for (n_id = 0; n_id< omg_param_list.nodes; n_id++) {
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->mob = mobility;
place_rwp_node(node); //initial positions
Pair pair = malloc (sizeof(Pair));
pair = sleep_rwp_node(node, cur_time); //sleep
Job_Vector = add_job(pair, Job_Vector);
Job_Vector_len ++;
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);*/
}
return(0);
}
void place_rwp_node(NodePtr node) {
node->X_pos = (double) ((int) (randomGen(omg_param_list.min_X, omg_param_list.max_X)*100))/ 100; int
node->mob->X_from = node->X_pos; start_rwp_generator (omg_global_param omg_param_list)
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; static int n_id = 0;
node->mob->Y_from = node->Y_pos; int id;
node->mob->Y_to = node->Y_pos; double cur_time = 0.0;
node_struct *node = NULL;
mobility_struct *mobility = NULL;
pair_struct *pair = NULL;
srand (omg_param_list.seed + RWP);
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++)
{
node = create_node ();
mobility = create_mobility ();
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
pair = (pair_struct *) malloc (sizeof (struct pair_struct));
pair->b = node;
sleep_rwp_node (pair, cur_time); //sleep
job_vector_end[RWP] = add_job (pair, job_vector_end[RWP]);
if (job_vector[RWP] == NULL)
job_vector[RWP] = job_vector_end[RWP];
job_vector_len[RWP]++;
}
n_id += omg_param_list.nodes;
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); if (job_vector[RWP] == NULL)
Node_Vector[RWP] = (Node_list) add_entry(node, Node_Vector[RWP]); LOG_E (OMG, "[RWP] Job Vector is NULL\n");
Node_Vector_len[RWP]++; return (0);
//Initial_Node_Vector_len[RWP]++;
} }
Pair sleep_rwp_node(NodePtr node, double cur_time){ void
node->mobile = 0; place_rwp_node (node_struct * node)
node->mob->speed = 0.0; {
node->mob->X_from = node->mob->X_to;
node->mob->Y_from = node->mob->Y_to; int loc_num;
node->X_pos = node->mob->X_to; double block_xmin, block_ymin;
node->Y_pos = node->mob->Y_to;
Pair pair = malloc(sizeof(Pair)) ;
if (omg_param_list[node->type].rwp_type == RESTIRICTED_RWP)
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); loc_num = (int) randomgen (0, omg_param_list[node->type].max_vertices);
node->x_pos =
node->mob->start_journey = cur_time; (double) vertice_xpos (loc_num, omg_param_list[node->type]);
pair->a = node->mob->start_journey + node->mob->sleep_duration; //when to wake up node->y_pos =
LOG_D(OMG, "[RWP] wake up at time: cur_time + sleep_duration : %.2f\n", pair->a); (double) vertice_ypos (loc_num, omg_param_list[node->type]);
pair->b = node; //LOG_D(OMG,"location number %d x pos %.2f y pos %.2f \n\n",loc_num,node->x_pos,node->y_pos);
}
return pair; 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 (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);
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 move_rwp_node(NodePtr node, double cur_time) { void
sleep_rwp_node (pair_struct * pair, double cur_time)
Pair pair = malloc(sizeof(Pair)); {
LOG_D(OMG, "[RWP] move node: %d\n",node->ID ); node_struct *node;
node->mob->X_from = node->X_pos; node = pair->b;
node->mob->Y_from = node->Y_pos; node->mobile = 0;
LOG_D(OMG, "[RWP] Current Position: (%.2f, %.2f)\n", node->mob->X_from, node->mob->Y_from); node->mob->speed = 0.0;
node->mob->x_from = node->mob->x_to;
node->mobile = 0; node->mob->y_from = node->mob->y_to;
double X_next = (double) ((int)(randomGen(omg_param_list.min_X,omg_param_list.max_X)*100))/ 100; node->x_pos = node->mob->x_to;
node->mob->X_to = X_next; node->y_pos = node->mob->y_to;
double Y_next = (double) ((int)(randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100;
node->mob->Y_to = Y_next; node->mob->sleep_duration =
LOG_D(OMG, "[RWP] destination: (%.2f, %.2f)\n", node->mob->X_to, node->mob->Y_to); (double) ((int)
(randomgen
double speed_next = (double) ((int)(randomGen(omg_param_list.min_speed, omg_param_list.max_speed)*100))/ 100; (omg_param_list[node->type].min_sleep,
node->mob->speed = speed_next; omg_param_list[node->type].max_sleep) * 100)) / 100;
LOG_D(OMG, "[RWP] speed_next %.2f\n", speed_next); //m/s /*LOG_D (OMG, "#[RWP] node: %d \tsleep duration : %.2f\n", node->id,
double distance = (double) ((int)(sqrtf(pow(node->mob->X_from - X_next, 2) + pow(node->mob->Y_from - Y_next, 2))*100))/ 100; node->mob->sleep_duration); */
LOG_D(OMG, "[RWP] distance %.2f\n", distance); //m
node->mob->start_journey = cur_time;
double journeyTime_next = (double) ((int)(distance/speed_next*100))/ 100; //duration to get to dest pair->next_event_t = cur_time + node->mob->sleep_duration; //when to wake up
////node->mob->journey_time = journeyTime_next; // LOG_D (OMG, "[RWP] wake up at time: cur_time + sleep_duration : %.2f\n",
node->mobile = 1; // pair->a);
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;
} }
void
void update_rwp_nodes(double cur_time) { move_rwp_node (pair_struct * pair, double cur_time)
Job_list tmp = Job_Vector; {
int done = 0; // int loc_num;
while ((tmp != NULL) && (done == 0)){ double distance, journeytime_next;
// if (tmp->pair == NULL){LOG_E(OMG, "UPDATE RWP : tmp->pair ==NULL\n" );} double pr, block_xmin, block_ymin;
// if (tmp->pair != NULL){LOG_E(OMG, "UPDATE RWP : tmp->pair !=NULL\n" );} //LOG_D (OMG, "[RWP] move node: %d\n", node->ID);
LOG_D(OMG, "[RWP] cur_time %f reaching the destination at %f\n", cur_time, tmp->pair->a ); node_struct *node;
node = pair->b;
if((tmp->pair !=NULL) && ( (double)tmp->pair->a >= cur_time - eps) && ( (double)tmp->pair->a <= cur_time + eps) ) { node->mob->x_from = node->mob->x_to;
if (tmp->pair->b->generator == RWP){ node->mob->y_from = node->mob->y_to;
LOG_D(OMG, "[RWP](first_job_time) %.2f == %.2f (cur_time) \n ",tmp->pair->a, cur_time ); node->x_pos = node->mob->x_to;
NodePtr my_node = (NodePtr)tmp->pair->b; node->y_pos = node->mob->y_to;
if(my_node->mobile == 1) { 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)); if (omg_param_list[node->type].rwp_type == RESTIRICTED_RWP)
pair = sleep_rwp_node(my_node, cur_time); {
tmp->pair = pair; do
tmp = tmp->next; {
} loc_num =
else if (my_node->mobile ==0) { (int) randomgen (0, omg_param_list[node->type].max_vertices);
LOG_D(OMG, "[RWP] node %d starts to move again \n", my_node->ID); node->mob->x_to =
my_node->mobile = 1; (double) vertice_xpos (loc_num, omg_param_list[node->type]);
Pair pair = malloc(sizeof(Pair)); node->mob->y_to =
pair = move_rwp_node(my_node, cur_time); (double) vertice_ypos (loc_num, omg_param_list[node->type]);
tmp->pair = pair;
tmp = tmp->next;
} }
else{ while (node->mob->x_to == node->mob->x_from
LOG_E(OMG,"[RWP] update_generator: unsupported node state - mobile : %d \n", my_node->mobile); && node->mob->y_to == node->mob->y_from);
exit(-1);
} distance = fabs (node->mob->x_to - node->mob->x_from) +
} fabs (node->mob->y_to - node->mob->y_from);
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 ); /* 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); */
tmp = tmp->next;
} }
} else if (omg_param_list[node->type].rwp_type == CONNECTED_DOMAIN)
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); pr = randomgen (0, 1);
done = 1; //quit the loop
} if (pr <= 0.50)
else { /*node->block_num =
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 ); (int) randomgen (0, omg_param_list[node->type].max_block_num); */
done = 1; //quit the loop node->block_num =
// exit(-1); (int) next_block (node->block_num, omg_param_list[node->type]);
}
} block_xmin = area_minx (node->block_num, omg_param_list[node->type]);
//sorting the new entries block_ymin = area_miny (node->block_num, omg_param_list[node->type]);
LOG_D(OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
display_job_list(Job_Vector); node->mob->x_to =
Job_Vector = quick_sort (Job_Vector);/////////// (double) ((int) (randomgen (block_xmin, xloc_div + block_xmin) * 100))
LOG_D(OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n"); / 100;
display_job_list(Job_Vector);
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
{
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++;
}
*/
} }
void get_rwp_positions_updated(double cur_time){
/*update RWP nodes position*/
double X_now=0.0;
double Y_now=0.0; void
LOG_D(OMG, "--------GET RWP POSITIONS--------\n"); update_rwp_nodes (double cur_time)
{
Pair my_pair = Job_Vector->pair;
if ( (my_pair !=NULL) && (cur_time <= my_pair->a +eps)){ int done = 0;
LOG_D(OMG, "[RWP] current time %.2f <= time when reaching the destination %.2f\n ",cur_time, my_pair->a); job_list *tmp = job_vector[RWP];
Job_list tmp = Job_Vector; node_struct *my_node;
while (tmp != NULL){ while (tmp != NULL && done == 0)
if (tmp->pair->b->generator == RWP){ {
if (tmp->pair->b->mobile == 0){ //node is sleeping my_node = (node_struct *) tmp->pair->b;
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);
} //case1:time to next event equals to current time
else if (tmp->pair->b->mobile == 1){ //node is moving if (tmp->pair != NULL
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", && ((double) tmp->pair->next_event_t >= cur_time - eps)
tmp->pair->b->ID, tmp->pair->b->mob->X_from, tmp->pair->b->mob->Y_from,tmp->pair->b->mob->X_to, && ((double) tmp->pair->next_event_t <= cur_time + eps))
tmp->pair->b->mob->Y_to,tmp->pair->b->mob->speed, tmp->pair->b->X_pos, tmp->pair->b->Y_pos); {
if (my_node->mobile == 1)
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)); sleep_rwp_node (tmp->pair, cur_time);
double dx = fabs(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to) / len; else
move_rwp_node (tmp->pair, cur_time);
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 ){ //case2: current time is greater than the time to next event
X_now = tmp->pair->b->mob->X_from + (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey) ) );
} else if (tmp->pair != NULL
else{ && (cur_time - eps) > tmp->pair->next_event_t)
X_now = tmp->pair->b->mob->X_from - (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey))); {
}
while (cur_time >= tmp->pair->next_event_t)
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))); if (my_node->mobile == 1)
} sleep_rwp_node (tmp->pair, cur_time);
else{ else
Y_now = tmp->pair->b->mob->Y_from - (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey))); 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; //case3: current time less than the time to next event
//tmp->pair->b->mob->X_from = tmp->pair->b->X_pos; else
//tmp->pair->b->mob->Y_from = tmp->pair->b->Y_pos; {
//tmp->pair->b->mob->start_journey = cur_time; done = 1; //quit the loop
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;
} }
}
tmp = tmp->next; tmp = tmp->next;
} }
}
else { //sorting the new entries
LOG_E(OMG, "ERROR (current time) %f > %f (first job_time) \n", cur_time ,my_pair->a ); //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) { void
LOG_D(OMG, "--------UPDATE--------\n"); get_rwp_positions_updated (double cur_time)
int l = 0; {
Job_list tmp = Job_Vector; double x_now = 0.0, y_now = 0.0;
double len, dx, dy;
while (l < Job_Vector_len){ job_list *tmp = job_vector[RWP];
LOG_D(OMG, "l == %d \n", l);
while (tmp != NULL)
//Pair my_pair = malloc (sizeof(Pair)); {
//my_pair = tmp->pair;
if (tmp->pair->b->mobile == 1 && tmp->pair->next_event_t >= cur_time)
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 (omg_param_list[tmp->pair->b->type].rwp_type == RESTIRICTED_RWP)
LOG_D(OMG, "cur_time %f\n", cur_time ); {
LOG_D(OMG, "tmp->pair->a %f\n", tmp->pair->a ); len =
tmp->pair->b->mob->speed * (cur_time -
if((tmp->pair !=NULL) && ( (double)tmp->pair->a >= cur_time - eps) && ( (double)tmp->pair->a <= cur_time + eps) ) { tmp->pair->b->mob->start_journey);
if (tmp->pair->b->generator == RWP){ dx = fabs (tmp->pair->b->mob->x_from - tmp->pair->b->mob->x_to);
LOG_D(OMG, " (first_job_time) %.2f == %.2f (cur_time) \n ",tmp->pair->a, cur_time );
LOG_D(OMG, " UPDATE RWP \n "); if (dx < len)
NodePtr my_node = (NodePtr)tmp->pair->b; {
if(my_node->mobile == 1) { tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
LOG_D(OMG, " stop node and let it sleep \n" ); tmp->pair->b->y_pos =
my_node->mobile = 0; tmp->pair->b->mob->y_from + (len -
Pair pair = malloc(sizeof(Pair)); dx) *
pair = sleep_rwp_node(my_node, cur_time); ((tmp->pair->b->mob->y_to -
tmp->pair = pair; tmp->pair->b->mob->y_from) /
} fabs (tmp->pair->b->mob->y_to -
else if (my_node->mobile ==0) { tmp->pair->b->mob->y_from));
LOG_D(OMG, " node %d slept enough...let's move again \n", my_node->ID); }
my_node->mobile = 1; else
Pair pair = malloc(sizeof(Pair)); {
pair = move_rwp_node(my_node, cur_time); tmp->pair->b->y_pos = tmp->pair->b->mob->y_from;
tmp->pair = pair; tmp->pair->b->x_pos = tmp->pair->b->mob->x_from + len *
} ((tmp->pair->b->mob->x_to - tmp->pair->b->mob->x_from)
else / fabs (tmp->pair->b->mob->x_to -
{ tmp->pair->b->mob->x_from));
LOG_D(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);
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 @@ ...@@ -37,7 +37,7 @@
#define RWP_H_ #define RWP_H_
#include "omg.h" #include "omg.h"
#include "grid.h"
/** /**
* \fn void start_rwp_generator(omg_global_param omg_param_list) * \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) ; ...@@ -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 * \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 * \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) * \fn Pair sleep_rwp_node(NodePtr node, double cur_time)
...@@ -61,7 +61,7 @@ void place_rwp_node(NodePtr node); ...@@ -61,7 +61,7 @@ void place_rwp_node(NodePtr node);
* \param cur_time a variable of type double that represents the current time * \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 * \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) * \fn Pair move_rwp_node(NodePtr node, double cur_time)
...@@ -71,7 +71,7 @@ Pair sleep_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 * \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 * \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) * \fn void update_rwp_nodes(double cur_time)
......
...@@ -77,17 +77,17 @@ int connection_(char *, int); ...@@ -77,17 +77,17 @@ int connection_(char *, int);
void sendExact(int); void sendExact(int);
/** /**
* \fn recieveExact(); * \fn recieveExact(void);
* \brief Pack the data to storage from buf after reading from socket * \brief Pack the data to storage from buf after reading from socket
* Returns storage pointer * Returns storage pointer
*/ */
storage* receiveExact(); storage* receiveExact(void);
/** /**
* \fn close_connection(); * \fn close_connection(void);
* \brief close socket connection * \brief close socket connection
*/ */
void close_connection(); void close_connection(void);
#endif #endif
...@@ -29,11 +29,11 @@ ...@@ -29,11 +29,11 @@
/*! \file rwalk.c /*! \file rwalk.c
* \brief static mobility generator * \brief static mobility generator
* \author M. Mahersi, J. Harri, N. Nikaein, Andre Gomes (One source) * \author M. Mahersi, N. Nikaein, J. Harri
* \date 2011 * \date 2011
* \version 0.1 * \version 0.1
* \company Eurecom * \company Eurecom
* \email: openair_tech@eurecom.fr * \email:
* \note * \note
* \warning * \warning
*/ */
...@@ -41,79 +41,103 @@ ...@@ -41,79 +41,103 @@
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "static.h"
void
start_static_generator (omg_global_param omg_param_list)
{
int id;
static int n_id = 0;
node_struct *node = NULL;
mobility_struct *mobility = NULL;
srand (omg_param_list.seed + STATIC);
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 = create_node ();
mobility = create_mobility ();
node->id = id;
node->type = omg_param_list.nodes_type;
node->mob = mobility;
node->generator = STATIC;
place_static_node (node); //initial positions
}
n_id += omg_param_list.nodes;
#include "omg.h"
void place_static_node(NodePtr node);
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;
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++) {
node = (NodePtr) create_node();
mobility = (MobilityPtr) create_mobility();
node->ID = n_id;
node->generator = omg_param_list.mobility_type;
node->type = omg_param_list.nodes_type;
node->mob = mobility;
node->generator = STATIC;
place_static_node(node); //initial positions
}
} }
void place_static_node(NodePtr node) {
if (omg_param_list.user_fixed && node->type == eNB) { void
if (omg_param_list.fixed_X <= omg_param_list.max_X && omg_param_list.fixed_X >= omg_param_list.min_X) place_static_node (node_struct * node)
node->X_pos = omg_param_list.fixed_X; {
else if (omg_param_list[node->type].user_fixed && node->type == eNB)
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; if (omg_param_list[node->type].fixed_x <=
node->mob->X_to = node->X_pos; omg_param_list[node->type].max_x
if (omg_param_list.fixed_Y <= omg_param_list.max_Y && omg_param_list.fixed_Y >= omg_param_list.min_Y) && omg_param_list[node->type].fixed_x >=
node->Y_pos = omg_param_list.fixed_Y; omg_param_list[node->type].min_x)
else node->x_pos = omg_param_list[node->type].fixed_x;
node->Y_pos = (double) ((int) (randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100; else
node->mob->Y_from = node->Y_pos; node->x_pos =
node->mob->Y_to = node->Y_pos; (double) ((int)
} (randomgen
else { (omg_param_list[node->type].min_x,
node->X_pos = (double) ((int) (randomGen(omg_param_list.min_X, omg_param_list.max_X)*100))/ 100; omg_param_list[node->type].max_x) * 100)) / 100;
node->mob->X_from = node->X_pos; node->mob->x_from = node->x_pos;
node->mob->X_to = 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; if (omg_param_list[node->type].fixed_y <=
node->mob->Y_from = node->Y_pos; omg_param_list[node->type].max_y
node->mob->Y_to = node->Y_pos; && 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[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[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->speed = 0.0;
node->mob->journey_time = 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); ...@@ -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] * \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 * \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_ */ #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){ ...@@ -204,12 +204,12 @@ void writeString(char *s){
} }
String_list readStringList(String_list vector){ string_list* readStringList(string_list* vector){
int i=0; int i=0;
int len = readInt(); int len = readInt();
descLen = len; descLen = len;
String_list entry = NULL; string_list* entry = NULL;
for (; i < len; i++) { for (; i < len; i++) {
if (vector->string == NULL) { if (vector->string == NULL) {
...@@ -218,14 +218,14 @@ String_list readStringList(String_list vector){ ...@@ -218,14 +218,14 @@ String_list readStringList(String_list vector){
vector->string = tmp;//readString(); vector->string = tmp;//readString();
} }
else { else {
entry = (String_list)malloc(sizeof(String_list)); entry = (string_list*) malloc(sizeof(string_list));
char *tmp = readString(); char *tmp = readString();
//printf("OMG - SUMO ID: %s \n",tmp); //printf("OMG - SUMO ID: %s \n",tmp);
entry->string = tmp;//readString(); entry->string = tmp;//readString();
entry->next = NULL; entry->next = NULL;
if(vector !=NULL) { if(vector !=NULL) {
String_list tmp = vector; string_list* tmp = vector;
while (tmp->next != NULL){ while (tmp->next != NULL){
tmp = tmp->next; tmp = tmp->next;
} }
...@@ -238,11 +238,11 @@ String_list readStringList(String_list vector){ ...@@ -238,11 +238,11 @@ String_list readStringList(String_list vector){
} }
void writeStringList(String_list vector){ void writeStringList(string_list* vector){
int count=0; 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.... // 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) if (tmp->string !=NULL)
count++; count++;
...@@ -463,9 +463,9 @@ void freeStorage(storage * freePtr){ ...@@ -463,9 +463,9 @@ void freeStorage(storage * freePtr){
freePtr = NULL; // finally, mark as empty list. freePtr = NULL; // finally, mark as empty list.
} }
void reset_String_list(String_list vector) { void reset_String_list(string_list* vector) {
String_list entry = vector; string_list* entry = vector;
String_list tmp; string_list* tmp;
while (entry->next != NULL) { while (entry->next != NULL) {
tmp = entry; tmp = entry;
......
...@@ -58,7 +58,7 @@ union n{ ...@@ -58,7 +58,7 @@ union n{
} un ; } un ;
void check_endianness(); void check_endianness(void);
//----------------STORAGE------------------------------------ //----------------STORAGE------------------------------------
struct Storage { struct Storage {
...@@ -78,36 +78,36 @@ int descLen; ...@@ -78,36 +78,36 @@ int descLen;
extern int msgLength; extern int msgLength;
void reset(); void reset(void);
int storageLength(storage *); int storageLength(storage *);
void rearange(); void rearange(void);
unsigned char readChar(); unsigned char readChar(void);
void writeChar(unsigned char); void writeChar(unsigned char);
int readByte() ; int readByte(void) ;
void writeByte(int) ; void writeByte(int) ;
int readUnsignedByte(); int readUnsignedByte(void);
void writeUnsignedByte(int); void writeUnsignedByte(int);
char * readString() ; char * readString(void) ;
void writeString(char *); void writeString(char *);
String_list readStringList(String_list) ; string_list* readStringList(string_list*) ;
void writeStringList(String_list); void writeStringList(string_list*);
int readShort() ; int readShort(void) ;
void writeShort(int); void writeShort(int);
int readInt() ; int readInt(void) ;
void writeInt(int); void writeInt(int);
float readFloat() ; float readFloat(void) ;
void writeFloat( float ); void writeFloat( float );
double readDouble() ; double readDouble(void) ;
void writeDouble( double ); void writeDouble( double );
storage* writePacket(unsigned char*, int); storage* writePacket(unsigned char*, int);
......
...@@ -52,361 +52,443 @@ ...@@ -52,361 +52,443 @@
#include "client_traci_OMG.h" #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]; 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 -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)
{
// Start SUMO in the child process
system (sumo_line);
//childs addresss space
}
printf("%s\n",sumo_line);
if ( (pid = fork()) == 0)
{
// Start SUMO in the child process
system(sumo_line);
//childs addresss space
}
//still in the parent process //still in the parent process
// Talk to SUMO // Talk to SUMO
targetTime = 1; targetTime = 1;
departed = NULL; departed = NULL;
arrived = NULL; arrived = NULL;
// switch on error to return to OAI // 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); 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 // create the OAI/SUMO ID manager
id_manager = create_IDManager(); id_manager = create_IDManager ();
node_struct *node = NULL;
mobility_struct *mobility = NULL;
NodePtr node = NULL; active_nodes = NULL; // container to return a subset of only ACTIVE OAI nodes in SUMO
MobilityPtr mobility = NULL;
active_nodes = NULL; // container to return a subset of only ACTIVE OAI nodes in SUMO
last_update_time = 0.0; last_update_time = 0.0;
// just check for faulty values // just check for faulty values
if (omg_param_list.nodes <= 0){ if (omg_param_list.nodes <= 0)
#ifdef STANDALONE {
printf("Number of nodes has not been set\n"); #ifdef STANDALONE
#else printf ("Number of nodes has not been set\n");
LOG_W(OMG, "Number of nodes has not been set\n"); #else
#endif LOG_W (OMG, "Number of nodes has not been set\n");
return(-1); #endif
} return (-1);
#ifdef STANDALONE }
printf("Number of OAI-equipped nodes in SUMO has been set to %d\n", omg_param_list.nodes); #ifdef STANDALONE
printf("Number of SUMO simulated nodes has been set to %d\n", max_node_SUMO); printf ("Number of OAI-equipped nodes in SUMO has been set to %d\n",
#else omg_param_list.nodes);
LOG_I(OMG, "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",
LOG_I(OMG, "Number of SUMO simulated nodes has been set to %d\n", max_node_SUMO); max_node_SUMO);
#endif #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 // check and match number of nodes in mobility file provided
if (omg_param_list.nodes > max_node_SUMO){ if (omg_param_list.nodes > max_node_SUMO)
#ifdef STANDALONE {
printf("Not all OAI nodes will be moving according to SUMO.\n"); #ifdef STANDALONE
#else printf ("Not all OAI nodes will be moving according to SUMO.\n");
LOG_I(OMG, "Not all OAI nodes will be moving according to SUMO.\n"); #else
#endif LOG_I (OMG, "Not all OAI nodes will be moving according to SUMO.\n");
} #endif
else { }
#ifdef STANDALONE else
printf("OAI nodes will be mapped to a subset of SUMO nodes\n"); {
#else #ifdef STANDALONE
LOG_I(OMG, "OAI nodes will be mapped to a subset of SUMO nodes\n"); printf ("OAI nodes will be mapped to a subset of SUMO nodes\n");
#endif #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"); if (omg_param_list.nodes_type == eNB)
#else {
LOG_I(OMG, "Node type has been set to eNB\n"); #ifdef STANDALONE
#endif printf ("Node type has been set to eNB\n");
} #else
else if (omg_param_list.nodes_type == UE) { LOG_I (OMG, "Node type has been set to eNB\n");
#endif
#ifdef STANDALONE }
printf("Node type has been set to UE\n"); else if (omg_param_list.nodes_type == UE)
#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
int n_id = 0; LOG_I (OMG, "Node type has been set to UE\n");
for ( n_id = 0; n_id< omg_param_list.nodes; n_id++) { #endif
}
node = (NodePtr) create_node();
mobility = (MobilityPtr) create_mobility(); for (n_id = id; n_id < omg_param_list.nodes + id; n_id++)
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->type = omg_param_list.nodes_type; // UE eNB... node = create_node ();
node->generator = omg_param_list.mobility_type; // SUMO mobility = create_mobility ();
node->mob = 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_Vector[SUMO] = (Node_list) add_entry(node, Node_Vector[SUMO]); node->type = omg_param_list.nodes_type; // UE eNB...
} node->generator = SUMO; // SUMO
node->mob = mobility;
update_IDs(); // update the mapping between departed and arrived nodes in SUMO.
node_vector_end[SUMO] =
return(0); (node_list *) add_entry (node, node_vector_end[SUMO]);
if (node_vector[SUMO] == NULL)
node_vector[SUMO] = node_vector_end[SUMO];
}
id += omg_param_list.nodes;
update_IDs (); // update the mapping between departed and arrived nodes in SUMO.
return (0);
} }
void update_IDs() { void
#ifdef STANDALONE update_IDs (void)
printf("Updating the ID mapping between SUMO and OAI\n"); {
#else #ifdef STANDALONE
LOG_D(OMG, "Updating the ID mapping between SUMO and OAI\n"); printf ("Updating the ID mapping between SUMO and OAI\n");
#endif #else
String_list tmp_arrived, tmp_departed; LOG_D (OMG, "Updating the ID mapping between SUMO and OAI\n");
#endif
if(arrived == NULL) { string_list *tmp_arrived, *tmp_departed;
printf("arrived vehicles is NULL \n");
return; if (arrived == NULL)
} {
printf ("arrived vehicles is NULL \n");
return;
}
tmp_arrived = arrived; tmp_arrived = arrived;
tmp_departed = departed; tmp_departed = departed;
if(departed == NULL) { if (departed == NULL)
printf("departed vehicles is NULL \n"); {
return; printf ("departed vehicles is NULL \n");
} return;
}
if(tmp_departed->string !=NULL) {
char * tmp_string = malloc(sizeof(strlen(tmp_departed->string))); if (tmp_departed->string != NULL)
strcpy(tmp_string, tmp_departed->string); {
//printf("OMG - 2 head is not null and value is: %s\n",tmp_string); char *tmp_string = malloc (sizeof (strlen (tmp_departed->string)));
int OAI_ID = get_oaiID_by_SUMO(tmp_string, id_manager); strcpy (tmp_string, tmp_departed->string);
if (OAI_ID ==-1) { //printf("OMG - 2 head is not null and value is: %s\n",tmp_string);
if (!activate_and_map(tmp_string)) { int OAI_ID = get_oaiID_by_SUMO (tmp_string, id_manager);
// printf("Reached the Maximum of OAI nodes to be mapped to SUMO\n"); if (OAI_ID == -1)
// 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; 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;
}
}
} }
} while (tmp_departed->next != NULL)
while (tmp_departed->next != NULL) { {
// printf("OMG - 2 main is not null \n"); // printf("OMG - 2 main is not null \n");
//char tmp_string [strlen(tmp_departed->string)]; //char tmp_string [strlen(tmp_departed->string)];
char * tmp_string = malloc(sizeof(strlen(tmp_departed->string))); char *tmp_string = malloc (sizeof (strlen (tmp_departed->string)));
strcpy(tmp_string, tmp_departed->string); strcpy (tmp_string, tmp_departed->string);
//char *tmp_string = tmp_departed->string; //char *tmp_string = tmp_departed->string;
int OAI_ID = get_oaiID_by_SUMO(tmp_string, id_manager); int OAI_ID = get_oaiID_by_SUMO (tmp_string, id_manager);
if (OAI_ID ==-1) { if (OAI_ID == -1)
if (!activate_and_map(tmp_string)) { {
//printf("Reached the Maximum of OAI nodes to be mapped to SUMO\n"); if (!activate_and_map (tmp_string))
//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; //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;
}
}
tmp_departed = tmp_departed->next;
} }
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;
char *tmp_string = tmp_arrived->string; //printf("OMG - 3 head is not null and value is: %s\n",tmp_arrived->string);
//printf("OMG - 3 head is not null and value is: %s\n",tmp_arrived->string);
if (!desactivate_and_unmap (tmp_string))
if(!desactivate_and_unmap(tmp_string)) { {
printf("Could not locate the OAI node ID %s \n", 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); //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;
char *tmp_string = tmp_arrived->string; if (!desactivate_and_unmap (tmp_string))
if(!desactivate_and_unmap(tmp_string)) { {
printf("Could not locate the OAI node\n"); printf ("Could not locate the OAI node\n");
// LOG_I(OMG, "Could not locate the OAI node\n"); // LOG_I(OMG, "Could not locate the OAI node\n");
}
tmp_arrived = tmp_arrived->next;
} }
tmp_arrived = tmp_arrived->next; arrived = clear_string_list (arrived);
}
arrived = clear_String_list(arrived);
} }
bool desactivate_and_unmap(char *sumo_id) { bool
#ifdef STANDALONE desactivate_and_unmap (char *sumo_id)
printf("desactivating node %s \n",sumo_id); {
#else #ifdef STANDALONE
LOG_I(OMG, "desactivating node %s \n",sumo_id); printf ("desactivating node %s \n", sumo_id);
#endif #else
int OAI_ID = get_oaiID_by_SUMO(sumo_id, id_manager); LOG_I (OMG, "desactivating node %s \n", sumo_id);
remove_oaiID_by_SUMO(sumo_id, id_manager); #endif
if (OAI_ID !=-1) { 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) //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) 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); node->mobile = 0; // this node is now inactive;
return true; 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); #ifdef STANDALONE
#else printf
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); ("Could not desactive an OAI node, as the SUMO-OAI mapping could not be found for the SUMO node ID %s \n",
#endif sumo_id);
#else
return false; 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) { bool
MapPtr map = create_map(); activate_and_map (char *sumo_id)
#ifdef STANDALONE {
printf("activating node %s \n",sumo_id); MapPtr map = create_map ();
#else #ifdef STANDALONE
LOG_I(OMG, "activating node %s \n",sumo_id); printf ("activating node %s \n", sumo_id);
#endif #else
// TODO: So far, only UE can be SUMO mobile, but could change LOG_I (OMG, "activating node %s \n", sumo_id);
NodePtr active_node = get_first_inactive_OAI_node(Node_Vector[SUMO], UE); #endif
if(active_node != NULL) { // found an inactive OAI node; will be mapped to SUMO // TODO: So far, only UE can be SUMO mobile, but could change
active_node->mobile = 1; // now node is active in SUMO node_struct *active_node =
get_first_inactive_OAI_node (node_vector[SUMO], UE);
active_nodes = add_entry(active_node, active_nodes); if (active_node != NULL)
{ // found an inactive OAI node; will be mapped to SUMO
map->oai_id = active_node->ID; active_node->mobile = 1; // now node is active in SUMO
map->sumo_id = malloc(sizeof((int)strlen(sumo_id)));
strcpy(map->sumo_id, sumo_id); active_nodes = add_entry (active_node, active_nodes);
#ifdef STANDALONE map->oai_id = active_node->id;
printf("added a mapping between oai ID: %d and SUMO ID: %s \n",map->oai_id, map->sumo_id); map->sumo_id = malloc (sizeof ((int) strlen (sumo_id)));
#else strcpy (map->sumo_id, sumo_id);
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",
// TODO fusion the two lists...leads to data inconsistency map->oai_id, map->sumo_id);
id_manager->map_sumo2oai = add_map_entry(map, id_manager->map_sumo2oai); #else
LOG_I (OMG, "added a mapping between oai ID: %d and SUMO ID: %s \n",
id_manager->map_oai2sumo = add_map_entry(map, id_manager->map_oai2sumo); //map_sumo2oai 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_oai2sumo = add_map_entry (map, id_manager->map_oai2sumo); //map_sumo2oai
return true;
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
return false;
}
}
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");
return;
}
void update_sumo_nodes(double cur_time) { last_update_time = cur_time; // keeps track of the last update time to get the update interval
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;
}
last_update_time = cur_time; // keeps track of the last update time to get the update interval
// commandSimulationStep(1.0);// Advance the SUMO simulation by cur_time units // 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); LOG_I (OMG, "--------Updated SUMO positions by %f [ms]--------\n",
update_IDs(); // both are in the traCI client 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 #ifdef STANDALONE
LOG_D(OMG, "--------GET SUMO Mobility for a single node--------\n"); printf ("--------GET SUMO Mobility for a single node--------\n");
#endif #else
LOG_D (OMG, "--------GET SUMO Mobility for a single node--------\n");
Map_list tmp = id_manager->map_oai2sumo; #endif
char *sumo_id = get_sumo_entry(node->ID, tmp);
Map_list tmp = id_manager->map_oai2sumo;
if(sumo_id !=NULL) { char *sumo_id = get_sumo_entry (node->id, tmp);
//printf(" OAI ID is: %d and SUMO ID is %s \n",node->ID, sumo_id);
GetPosition(node, sumo_id); if (sumo_id != NULL)
GetSpeed(node, sumo_id); {
} //printf(" OAI ID is: %d and SUMO ID is %s \n",node->ID, 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 #ifdef STANDALONE
LOG_I(OMG, "--------GET SUMO Mobility for a group of ACTIVE OAI nodes--------\n"); printf
#endif ("--------GET SUMO Mobility for a group of ACTIVE OAI nodes--------\n");
#else
if (Node_Vector[SUMO] != NULL){ LOG_I (OMG,
Node_list tmp = Node_Vector[SUMO]; "--------GET SUMO Mobility for a group of ACTIVE OAI nodes--------\n");
while (tmp != NULL){ #endif
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); if (node_vector[SUMO] != NULL)
LOG_I(OMG, "Old Positions \n"); {
//printf("Old Positions \n"); node_list *tmp = node_vector[SUMO];
display_node_position(tmp->node->ID, tmp->node->generator, tmp->node->type ,tmp->node->mobile, tmp->node->X_pos, tmp->node->Y_pos ); while (tmp != NULL)
{
update_sumo_positions(tmp->node); if ((tmp->node->generator == SUMO) && (tmp->node->mobile == 1))
{ // OAI node MUST be active
//printf("New Positions \n"); LOG_I (OMG, "found an active node with id %d \n",
LOG_I(OMG, "New Positions \n"); tmp->node->id);
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, "Old Positions \n");
} //printf("Old Positions \n");
tmp = tmp->next; 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);
//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);
}
tmp = tmp->next;
}
} }
}
return active_nodes; return active_nodes;
} }
NodePtr get_first_inactive_OAI_node(Node_list list, int node_type) { node_struct *
Node_list current; get_first_inactive_OAI_node (node_list * list, int node_type)
{
if (list !=NULL) { //start search node_list *current;
current = list;
while (current->next != NULL) { if (list != NULL)
if((current->node->mobile == 0) && (current->node->type == node_type)) { { //start search
return current->node; current = list;
} while (current->next != NULL)
current = current->next; {
if ((current->node->mobile == 0)
&& (current->node->type == node_type))
{
return current->node;
}
current = current->next;
}
} }
} return NULL; // all nodes are active already..reached the maximum number of OAI nodes
return NULL; // all nodes are active already..reached the maximum number of OAI nodes
} }
bool stop_sumo_generator() { bool
#ifdef STANDALONE stop_sumo_generator (void)
printf(" --------Destructor for SUMO: closing the TraCI socket and killing SUMO ---- \n"); {
#else #ifdef STANDALONE
LOG_I(OMG, " --------Destructor for SUMO: closing the TraCI socket and killing SUMO ---- \n"); printf
#endif (" --------Destructor for SUMO: closing the TraCI socket and killing SUMO ---- \n");
commandClose(); // closing the connection with SUMO via TraCI #else
close_connection(); // closing the socket connection LOG_I (OMG,
kill(pid,SIGKILL); // killing SUMO in case it could not close by itself " --------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; return true;
} }
...@@ -50,11 +50,11 @@ ...@@ -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*/ /*! 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; 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; 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*/ /*! 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 */ /*! 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; double last_update_time;
...@@ -79,7 +79,7 @@ void update_sumo_nodes(double cur_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 * \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. * \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); * \fn Node_list get_sumo_positions_updated(double cur_time);
...@@ -87,7 +87,7 @@ void update_sumo_positions(NodePtr node); ...@@ -87,7 +87,7 @@ void update_sumo_positions(NodePtr node);
* \param cur_time a variable of type double that represents the current time * \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 * \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) * \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); ...@@ -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) * \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) * \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) * \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. * \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) * \fn bool desactive_and_unmap(char *sumo_id)
...@@ -122,10 +122,10 @@ bool desactivate_and_unmap(char *sumo_id); ...@@ -122,10 +122,10 @@ bool desactivate_and_unmap(char *sumo_id);
bool activate_and_map(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. * \brief stops SUMO, stop the socket and kills SUMO process in the child domain.
* \return true in case of success; false otherwise * \return true in case of success; false otherwise
*/ */
bool stop_sumo_generator(); bool stop_sumo_generator(void);
#endif /* SUMO_H_ */ #endif /* SUMO_H_ */
...@@ -29,11 +29,11 @@ ...@@ -29,11 +29,11 @@
/*! \file trace.c /*! \file trace.c
* \brief The trace-based mobility model for OMG/OAI (mobility is statically imported from a file) * \brief The trace-based mobility model for OMG/OAI (mobility is statically imported from a file)
* \author S. Uppoor and Navid Nikaein * \author S. Gashaw, N. Nikaein, J. Harri
* \date 2011 * \date 2014
* \version 0.1 * \version 0.1
* \company INRIA * \company EURECOM
* \email: sandesh.uppoor@inria.fr * \email:
* \note * \note
* \warning * \warning
*/ */
...@@ -41,443 +41,515 @@ ...@@ -41,443 +41,515 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include <math.h> #include <math.h>
#include "trace.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;
int start_trace_generator(omg_global_param omg_param_list) { //check if the next input data is the same as the previous
// MobilityPtr mobility = NULL;
//read the mobility file here int
read_mobility_file(omg_param_list.mobility_file); // JHNOTE: in order to debug, please give and change name here... start_trace_generator (omg_global_param omg_param_list)
LOG_I(OMG, "mobility file %s put in the table %p\n",omg_param_list.mobility_file, table ); {
double cur_time = 0.0;
sort_veh_movement(table); int immobile = 0;
int node_number;
if (omg_param_list.nodes <= 0){ node_struct *node = NULL;
LOG_W(OMG, "Number of nodes has not been set\n"); mobility_struct *mobility = NULL;
return(-1); pair_struct *pair = NULL;
} node_info *temp;
// check and match number of nodes in mobility file provided parse_data (omg_param_list.mobility_file, omg_param_list.nodes_type); //read mobility file
if (omg_param_list.nodes != get_num_nodes()){
LOG_W(OMG, "Make sure all nodes have mobility description in mobility file (%d,%d)\n", //LOG_I (OMG, "mobility file %s put in the table %p\n",omg_param_list.mobility_file, table);
omg_param_list.nodes, get_num_nodes());
//return(-1); node_number = get_number_of_nodes (omg_param_list.nodes_type);
}
if (node_number == 0)
if (omg_param_list.nodes_type == eNB) { LOG_E (OMG, "[TRACE] empty input file \n");
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); 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];
deploy_nodes();
return(0); while (temp != NULL)
} {
node_data *this_node =
int deploy_nodes() { get_next_data (table[omg_param_list.nodes_type], temp->g_id, DATA_AND_STATUS_CHANGE);
NodePtr node = NULL; if (this_node == NULL)
{
// int count = 0; LOG_E (OMG, "[TRACE] Unexpected empty data entry\n");
node_info * head_node = head_node_info; exit (-1);
while (head_node!=NULL){ }
//if (count<omg_param_list.nodes){
create_trace_node(node,head_node); node = create_node ();
//count++; mobility = create_mobility ();
head_node=head_node->next; node->id = temp->vid;
//}else node->gid = temp->g_id;
// break;
/* if(this_node->type == -1) //if node type is given in the file set the defualt type UE
} node->type = UE; */
//if (count!=omg_param_list.nodes) node->type = omg_param_list.nodes_type;
// create_trace_node(node,head_node); node->generator = TRACE;
node->mob = mobility;
return(0);
} place_trace_node (node, this_node); //initial positions
if (this_node->visit == 1)
{
pair = (pair_struct *) malloc (sizeof (struct pair_struct));
pair->b = node;
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)
sleep_trace_node (pair, this_node, cur_time);
else
move_trace_node (pair, this_node, cur_time); //move
}
//LOG_I (OMG,
//"[TRACE] position of node ID: %d %d\n ",node->id, node->type);
}
else
{
temp = temp->next;
continue;
}
job_vector_end[TRACE] = add_job (pair, job_vector_end[TRACE]);
if (job_vector[TRACE] == NULL)
job_vector[TRACE] = job_vector_end[TRACE];
job_vector_len[TRACE]++;
temp = temp->next;
}
if (job_vector[TRACE] == NULL)
LOG_I (OMG, "[TRACE] Job Vector is NULL\n");
int create_trace_node(NodePtr node,node_info *head_node){
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;
place_trace_node(node); //initial positions
Pair pair = malloc (sizeof(Pair));
Exnode* next_loc=NULL;
next_loc=get_next_position(table,node->ID);
// 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;
}
Job_Vector = add_job(pair, Job_Vector);
Job_Vector_len ++;
if (Job_Vector == NULL)
LOG_E(OMG, "Job Vector is NULL\n");
return 0; return 0;
} }
void place_trace_node(NodePtr node) { void
Exnode* next_loc=NULL ; place_trace_node (node_struct * node, node_data * n)
next_loc=get_next_position(table,node->ID); {
node_data *n_ptr = n;
node->X_pos = next_loc->x; node->x_pos = (double) n_ptr->x_pos;
node->mob->X_from = node->X_pos; node->mob->x_from = node->x_pos;
node->mob->X_to = node->X_pos; node->mob->x_to = node->x_pos;
node->Y_pos = next_loc->y;
node->mob->Y_from = node->Y_pos; node->y_pos = (double) n_ptr->y_pos;
node->mob->Y_to = node->Y_pos; node->mob->y_from = node->y_pos;
node->mob->y_to = node->y_pos;
node->mob->speed = next_loc->speed;
node->mob->journey_time = 0.0;
reset_visit_status(table,next_loc->time,node->ID);
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]++;
}
// [NO MORE USED] sleep just after creation and after mobility description is over node->mob->speed = n_ptr->speed;
Pair sleep_trace_node(NodePtr node, double cur_time,float sleep_duration){ node->mob->journey_time = 0.0;
// node->start_journey=(double) n_ptr->time; //time of initial position
node->mobile = 0; // node->mob->target_time=(double) n_ptr->next->time; //time of next destination
node->mob->speed = 0.0; LOG_I (OMG,
node->mob->X_from = node->mob->X_to; "[TRACE] Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = %.2f \n ",
node->mob->Y_from = node->mob->Y_to; node->id, node->type, node->x_pos, node->y_pos, node->mob->speed);
node->X_pos = node->mob->X_to;
node->Y_pos = node->mob->Y_to;
Pair pair = malloc(sizeof(Pair)) ;
node->mob->sleep_duration = sleep_duration ; node_vector_end[node->type] =
LOG_D(OMG, "node: %d \tsleep duration : %.2f\n",node->ID, node->mob->sleep_duration); (node_list *) add_entry (node, node_vector_end[node->type]);
node->mob->start_journey = cur_time; if (node_vector[node->type] == NULL)
node_vector[node->type] = node_vector_end[node->type];
pair->a =(node->mob->start_journey + node->mob->sleep_duration);
LOG_D(OMG, "to wake up at time: cur_time %f + sleep_duration : %.2f\n", cur_time,pair->a); node_vector_len[node->type]++;
pair->b = node;
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->mobile = 1;
node->mob->speed = n_data->speed;
node->mob->speed = 0.0; node->mob->x_to = (double) n_data->next->x_pos;
node->mob->y_to = (double) n_data->next->y_pos;
// jump is used to displace node to strictly follow mobility discription node->mob->target_time = (double) n_data->next->time;
if (jump== 1){
node->X_pos = node->mob->X_to; //if speed equals to zero compute the speed(i.e node was on sleep move it)
node->Y_pos = node->mob->Y_to; if (node->mob->speed == 0)
}else{ {
node->mob->X_to = node->X_pos; cdistance =
node->mob->Y_to = node->Y_pos; (double)
} sqrtf
node->mob->X_from = node->mob->X_to; (pow (node->mob->x_from - node->mob->x_to, 2) +
node->mob->Y_from = node->mob->Y_to; pow (node->mob->y_from - node->mob->y_to, 2));
Pair pair = malloc(sizeof(Pair)) ; journeytime = node->mob->target_time - n_data->time;
LOG_D(OMG, "Node: %d \tawake duration : %.2f\n",node->ID, duration); 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);*/
node->mob->start_journey = cur_time;
pair->next_event_t = cur_time + journeytime_next; //when to reach the destination
}
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; node->mob->start_journey = cur_time;
pair->next_event_t = n_data->time; //when to move this node
//node->mob->target_time= 9999.; //LOG_D (OMG, "[TRACE] Node will wake up at time: %.2f\n", pair->next_event_t);
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;
} }
Pair move_trace_node(NodePtr node, double cur_time) { void
sleep_trace_node (pair_struct * pair, node_data * n_data, double cur_time)
Exnode* next_loc=NULL; {
next_loc=get_next_position(table,node->ID); double journeytime, distance;
node_struct *node = pair->b;
if (next_loc==NULL) {//Option 1 : no job, I am awake node->mobile = 0;
LOG_D(OMG, "NULL detected\n"); node->mob->speed = 0.0;
return keep_awake_trace_node(node,cur_time,9999,1); node->mob->x_from = node->mob->x_to;
} node->mob->y_from = node->mob->y_to;
else{ // location discription available node->x_pos = node->mob->x_to;
// Job_list tmp1 = Job_Vector; node->y_pos = node->mob->y_to;
LOG_D(OMG, "Location fetch : (%.2f, %.2f)\n", next_loc->x, next_loc->y); //sleep duration
double X_next; if (n_data->x_pos == n_data->next->x_pos &&
double Y_next; n_data->y_pos == n_data->next->y_pos)
double journeyTime_next; {
node->mob->sleep_duration = n_data->next->time - n_data->time;
// 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);
//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);
} }
else
Pair pair = malloc(sizeof(Pair)); { //sleep case 2
LOG_D(OMG, "MOVE TRACE NODE\n"); node->mob->target_time - (journeytime + node->mob->start_journey);
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); node->mob->start_journey = cur_time;
pair->next_event_t = cur_time + node->mob->sleep_duration; //when to wake up
if (!(next_loc->x==node->X_pos && next_loc->y==node->Y_pos) && (next_loc->speed==0. && node->mob->speed==0.0) ){ /*LOG_D (OMG, "#[TRACE] node: %d \tsleep duration : %.2f\n", node->id,
node->mob->X_to = node->X_pos; node->mob->sleep_duration);*/
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;
double speed_next;
speed_next = next_loc->speed;
node->mob->speed = speed_next;
LOG_D(OMG, "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, "distance %.2f\n", distance); //m
LOG_D(OMG,"next_loc->time %f",next_loc->time);
journeyTime_next = (double) ((int)(distance/speed_next*100))/ 100;
} //duration to get to dest ;
node->mobile = 1;
LOG_D(OMG, "mob->journey_time_next %.2f\n",journeyTime_next );
node->mob->start_journey = cur_time;
LOG_D(OMG, "start_journey %.2f\n", node->mob->start_journey );
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);
pair->b = node;
return pair;
}
} }
void update_trace_nodes(double cur_time) {
void
LOG_D(OMG, "--------UPDATE--------\n"); update_trace_nodes (double cur_time)
Job_list tmp = Job_Vector; {
int done = 0; // job_list *tmp;
int done = 0;
display_job_list(Job_Vector); node_data *node_n;
while ((tmp != NULL) && (done == 0)){ node_struct *my_node;
// 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 ); tmp = job_vector[TRACE];
LOG_D(OMG, "tmp->pair->a %f %f %f\n", tmp->pair->a , cur_time - eps,cur_time + eps); if (tmp == NULL)
LOG_D (OMG, "[TRACE] last data for all nodes\n");
if((tmp->pair !=NULL) && ( (double)tmp->pair->a >= cur_time - eps) && ( (double)tmp->pair->a <= cur_time + eps) ) {
if (tmp->pair->b->generator == TRACE){ while (tmp != NULL && done != 1)
LOG_D(OMG, " (first_job_time) %.2f == %.2f (cur_time) \n ",tmp->pair->a, cur_time ); { //1
my_node = tmp->pair->b;
// update to a new location node_n = get_next_data (table[my_node->type], my_node->gid, DATA_ONLY);
/*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)
{
next_loc=get_next_position(table,tmp->pair->b->ID); tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
if (next_loc !=NULL){ tmp->pair->b->mob->x_from = tmp->pair->b->x_pos;
tmp->pair->b->X_pos = next_loc->x ; tmp->pair->b->y_pos = tmp->pair->b->mob->y_to;
tmp->pair->b->Y_pos = next_loc->y ; 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, " UPDATE TRACE \n "); // LOG_D (OMG, "[TRACE] last data for all nodes\n");
NodePtr my_node = (NodePtr)tmp->pair->b; tmp = tmp->next;
continue;
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)); //case1:time to next event equals to current time
pair = move_trace_node(my_node, cur_time); if (tmp->pair != NULL && tmp->pair->next_event_t >= cur_time - eps
&& tmp->pair->next_event_t <= cur_time + eps)
tmp->pair = pair; {
tmp = tmp->next; //LOG_D (OMG, "[TRACE] last data for all nodes\n");
} if (my_node->mobile == 1)
else{ {
LOG_E(OMG, "update_generator: unsupported node state - mobile : %d \n", my_node->mobile); if (my_node->mob->target_time > tmp->pair->next_event_t) //sleep node
exit(-1); {
} sleep_trace_node (tmp->pair, node_n, cur_time);
} }
else { 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; node_n =
} get_next_data (table[my_node->type], my_node->gid,
DATA_AND_STATUS_CHANGE);
}
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 (node_n->x_pos == node_n->next->x_pos &&
if ((cur_time >= tmp->pair->b->mob->target_time-eps) && (cur_time<=tmp->pair->b->mob->target_time + eps)){ node_n->y_pos == node_n->next->y_pos)
tmp->pair->b->X_pos = tmp->pair->b->mob->X_to; sleep_trace_node (tmp->pair, node_n, cur_time);
tmp->pair->b->Y_pos = tmp->pair->b->mob->Y_to;
Pair pair = malloc(sizeof(Pair)); else
//pair = keep_awake_trace_node(tmp->pair->b,cur_time,awake_duration,1); move_trace_node (tmp->pair, node_n, cur_time);
pair = move_trace_node(tmp->pair->b, cur_time); }
tmp->pair = pair;
} }
tmp = tmp->next; else if (my_node->mobile == 0)
} {
else { node_n =
LOG_E(OMG, "%.2f > %.2f\n", cur_time,tmp->pair->a ); //LOG_D(OMG, " (generator=%d) != (RWP=%d) \n", tmp->pair->b->generator, RWP ); get_next_data (table[my_node->type], my_node->gid, DATA_AND_STATUS_CHANGE);
done = 1; //quit the loop
exit(-1); if (node_n->x_pos == node_n->next->x_pos &&
} node_n->y_pos == node_n->next->y_pos)
}
//sorting the new entries sleep_trace_node (tmp->pair, node_n, cur_time);
LOG_D(OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
display_job_list(Job_Vector); else
Job_Vector = quick_sort (Job_Vector);/////////// move_trace_node (tmp->pair, node_n, cur_time);
LOG_D(OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
display_job_list(Job_Vector); }
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)
sleep_trace_node (tmp->pair, node_n, cur_time);
else
move_trace_node (tmp->pair, node_n, 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 (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;
}
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);
if (node_n->x_pos == node_n->next->x_pos &&
node_n->y_pos == node_n->next->y_pos)
sleep_trace_node (tmp->pair, node_n, cur_time);
else
move_trace_node (tmp->pair, node_n, cur_time);
}
}
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)
sleep_trace_node (tmp->pair, node_n, cur_time);
else
move_trace_node (tmp->pair, node_n, cur_time);
}
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)
sleep_trace_node (tmp->pair, node_n, cur_time);
else
move_trace_node (tmp->pair, node_n, cur_time);
}
node_n = get_next_data (table[my_node->type], my_node->gid, DATA_ONLY);
if (node_n == NULL || node_n->next == NULL)
{
break;
}
} //2
}
//case3: current time less than the time to next event
else
{
done = 1; //quit the loop
}
tmp = tmp->next;
} //1
//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]);
} }
void get_trace_positions_updated(double cur_time){
void
double X_now=0.0; get_trace_positions_updated (double cur_time)
double Y_now=0.0; {
//LOG_D(OMG, "--------GET TRACE POSITIONS--------\n"); double x_now = 0.0, y_now = 0.0;
double len, dx, dy;
Pair my_pair = Job_Vector->pair; job_list *tmp = job_vector[TRACE];
if ( (my_pair !=NULL) && (cur_time <= my_pair->a )){ while (tmp != NULL)
// LOG_D(OMG, "%.2f <= %.2f\n ",cur_time, my_pair->a); {
Job_list tmp = Job_Vector;
if (tmp->pair->b->mobile == 1 && tmp->pair->next_event_t >= cur_time)
{
while (tmp != NULL){
if (tmp->pair->b->generator == TRACE){ //printf("hiiiiiiiiiii \n");
len =
if (tmp->pair->b->mobile == 0){ //node is sleeping sqrtf (pow
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); (tmp->pair->b->mob->x_from -
LOG_T(OMG, "nothing to do\n"); tmp->pair->b->mob->x_to,
} 2) + pow (tmp->pair->b->mob->y_from -
else if (tmp->pair->b->mobile == 1){ //node is moving tmp->pair->b->mob->y_to, 2));
LOG_D(OMG,"Node %d is mobile at %f\n", tmp->pair->b->ID,cur_time); if (len != 0)
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); dx =
fabs (tmp->pair->b->mob->x_from -
double step=0.10; tmp->pair->b->mob->x_to) / len;
dy =
if (tmp->pair->b->mob->speed == 0.0 ){ fabs (tmp->pair->b->mob->y_from -
tmp->pair->b->mob->y_to) / len;
if (tmp->pair->b->mob->target_speed == 0.0 ){ //x coordinate
if (tmp->pair->b->mob->x_from < tmp->pair->b->mob->x_to)
if ((cur_time >= (tmp->pair->b->mob->target_time-step)-eps) && (cur_time<=(tmp->pair->b->mob->target_time + step)+eps)) { {
x_now =
Exnode* next_loc=NULL; tmp->pair->b->mob->x_from +
next_loc=get_next_position(table,tmp->pair->b->ID); (dx *
(tmp->pair->b->mob->speed *
if (next_loc !=NULL){ (cur_time - tmp->pair->b->mob->start_journey)));
tmp->pair->b->X_pos = next_loc->x ; }
tmp->pair->b->Y_pos = next_loc->y ; else
//tmp->pair->b->X_pos = tmp->pair->b->mob->X_to; {
//tmp->pair->b->Y_pos = tmp->pair->b->mob->Y_to; x_now =
} tmp->pair->b->mob->x_from -
} (dx *
} (tmp->pair->b->mob->speed *
// needed ? (cur_time - tmp->pair->b->mob->start_journey)));
//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;
//y coordinate
} if (tmp->pair->b->mob->y_from < tmp->pair->b->mob->y_to)
else { {
y_now =
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)); tmp->pair->b->mob->y_from +
double dx = fabs(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to) / len; (dy *
(tmp->pair->b->mob->speed *
double dy = fabs(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to) / len; (cur_time - tmp->pair->b->mob->start_journey)));
}
if (tmp->pair->b->mob->X_from < tmp->pair->b->mob->X_to ){ else
X_now = tmp->pair->b->mob->X_from + (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey) ) ); {
} y_now =
else{ tmp->pair->b->mob->y_from -
X_now = tmp->pair->b->mob->X_from - (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey))); (dy *
} (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)));
} tmp->pair->b->x_pos = (double) ((int) (x_now * 100)) / 100;
else{ tmp->pair->b->y_pos = (double) ((int) (y_now * 100)) / 100;
Y_now = tmp->pair->b->mob->Y_from - (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
}
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; else
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->x_pos = tmp->pair->b->mob->x_to;
//tmp->pair->b->mob->Y_from = tmp->pair->b->Y_pos; tmp->pair->b->y_pos = tmp->pair->b->mob->y_to;
//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; 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 @@ ...@@ -42,65 +42,22 @@
#define TRACE_H_ #define TRACE_H_
//#include "defs.h" //#include "defs.h"
#include "omg.h" #include "omg.h"
#include "hashtable.h" #include "trace_hashtable.h"
#include "mobility_parser.h" #include "mobility_parser.h"
int start_trace_generator (omg_global_param omg_param_list);
/** void place_trace_node (node_struct* node, node_data* n);
* \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 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_ */ #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