* 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
This commit is contained in:
@@ -53,6 +53,8 @@ typedef enum {
|
||||
/* decomposition of node functions into jobs for a given event */
|
||||
typedef enum Job_type_e { JT_OTG, JT_PDCP, JT_PHY_MAC, JT_INIT_SYNC, JT_DL, JT_UL, RN_DL, RN_UL, JT_END} Job_Type_t;
|
||||
|
||||
typedef enum Operation_Type_e { READ, WRITE, RESET} Operation_Type_t;
|
||||
|
||||
typedef struct Job_s {
|
||||
enum Job_type_e type;
|
||||
int exe_time; /* execution time at the worker*/
|
||||
@@ -87,9 +89,12 @@ typedef struct Packet_otg_s {
|
||||
|
||||
typedef struct {
|
||||
Event_Type_t type;
|
||||
enum Operation_Type_e optype; //op
|
||||
char *key;
|
||||
void *value;
|
||||
frame_t frame;
|
||||
int ue;
|
||||
int lcid;
|
||||
} Event_t;
|
||||
|
||||
/*typedef struct Global_Time {
|
||||
@@ -101,6 +106,8 @@ typedef struct {
|
||||
double time_ms;
|
||||
};*/
|
||||
|
||||
|
||||
|
||||
typedef struct Packet_otg_elt_s {
|
||||
struct Packet_otg_elt_s *next;
|
||||
struct Packet_otg_elt_s *previous;
|
||||
|
||||
@@ -178,7 +178,7 @@ int logInit (void)
|
||||
g_log->log_component[OMG].interval = 1;
|
||||
g_log->log_component[OMG].fd = 0;
|
||||
g_log->log_component[OMG].filelog = 0;
|
||||
g_log->log_component[OMG].filelog_name = "";
|
||||
g_log->log_component[OMG].filelog_name = "/tmp/omg.csv";
|
||||
|
||||
g_log->log_component[OTG].name = "OTG";
|
||||
g_log->log_component[OTG].level = LOG_EMERG;
|
||||
|
||||
@@ -50,7 +50,7 @@ OMG_OBJS += $(OMG_DIR)/job.o
|
||||
OMG_OBJS += $(OMG_DIR)/static.o
|
||||
OMG_OBJS += $(OMG_DIR)/rwp.o
|
||||
OMG_OBJS += $(OMG_DIR)/rwalk.o
|
||||
OMG_OBJS += $(OMG_DIR)/omg_hashtable.o
|
||||
#OMG_OBJS += $(OMG_DIR)/omg_hashtable.o
|
||||
OMG_OBJS += $(OMG_DIR)/mobility_parser.o
|
||||
OMG_OBJS += $(OMG_DIR)/trace.o
|
||||
OMG_OBJS += $(OMG_DIR)/sumo.o
|
||||
@@ -58,6 +58,10 @@ OMG_OBJS += $(OMG_DIR)/id_manager.o
|
||||
OMG_OBJS += $(OMG_DIR)/client_traci_OMG.o
|
||||
OMG_OBJS += $(OMG_DIR)/storage_traci_OMG.o
|
||||
OMG_OBJS += $(OMG_DIR)/socket_traci_OMG.o
|
||||
OMG_OBJS += $(OMG_DIR)/steadystaterwp.o
|
||||
OMG_OBJS += $(OMG_DIR)/grid.o
|
||||
OMG_OBJS += $(OMG_DIR)/trace_hashtable.o
|
||||
|
||||
|
||||
OTG_OBJS = $(OTG_DIR)/otg_tx.o
|
||||
OTG_OBJS += $(OTG_DIR)/otg.o
|
||||
|
||||
+30
-1
@@ -295,6 +295,7 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need
|
||||
////// options of UE_Mobility_Type
|
||||
typedef struct
|
||||
{
|
||||
char *selected_option;
|
||||
int horizontal_grid;
|
||||
int vertical_grid;
|
||||
} Grid_Map;
|
||||
@@ -464,6 +465,32 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need
|
||||
/* @}*/
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t priority[11];//pas possible d'acceder au MAX_NUM_LCID
|
||||
//
|
||||
uint8_t DCI_aggregation_min;
|
||||
uint8_t DLSCH_dci_size_bits;
|
||||
//UL transmission bandwidth in RBs
|
||||
uint8_t ul_bandwidth[11];
|
||||
//DL transmission bandwidth in RBs
|
||||
uint8_t dl_bandwidth[11];
|
||||
//UL transmission bandwidth in RBs
|
||||
uint8_t min_ul_bandwidth[11];
|
||||
//DL transmission bandwidth in RBs
|
||||
uint8_t min_dl_bandwidth[11];
|
||||
//aggregated bit rate of non-gbr bearer per UE
|
||||
uint64_t ue_AggregatedMaximumBitrateDL;
|
||||
//aggregated bit rate of non-gbr bearer per UE
|
||||
uint64_t ue_AggregatedMaximumBitrateUL;
|
||||
//CQI scheduling interval in subframes.
|
||||
uint16_t cqiSchedInterval;
|
||||
//Contention resolution timer used during random access
|
||||
uint8_t mac_ContentionResolutionTimer;
|
||||
uint16_t max_allowed_rbs[11];
|
||||
uint8_t max_mcs[11];
|
||||
} Mac_config;
|
||||
|
||||
/** @defgroup _Predefined_traffic Configuration
|
||||
* @ingroup _OSD_basic
|
||||
* @brief Including Application type, Source, destination, background, etc
|
||||
@@ -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 omg_model_rn;
|
||||
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
|
||||
// control eNB/UE instance through CLI
|
||||
unsigned char cli_enabled;
|
||||
@@ -733,6 +761,7 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need
|
||||
* @{*/
|
||||
typedef struct
|
||||
{
|
||||
Mac_config mac_config[NUMBER_OF_UE_MAX];
|
||||
Environment_System_Config environment_system_config; /*!< \brief Evironment configuration */
|
||||
Topology_Config topology_config; /*!< \brief Topology configuration */
|
||||
Application_Config application_config; /*!< \brief Applications configuration */
|
||||
|
||||
@@ -1015,14 +1015,18 @@ void characters(void *user_data, const xmlChar *xmlch, int xmllen) { // called o
|
||||
} else if (mobility_) {
|
||||
if (UE_mobility_) {
|
||||
if (UE_mobility_type_) {
|
||||
oai_emulation.topology_config.mobility.UE_mobility.UE_mobility_type.selected_option = strndup(ch, len);
|
||||
} else if (grid_walk_) {
|
||||
oai_emulation.topology_config.mobility.UE_mobility.UE_mobility_type.selected_option = strndup(ch, len);
|
||||
|
||||
}else if (grid_walk_) {
|
||||
if (grid_map_) {
|
||||
oai_emulation.topology_config.mobility.UE_mobility.grid_walk.grid_map.selected_option = strndup(ch, len);
|
||||
/*
|
||||
if (horizontal_grid_) {
|
||||
oai_emulation.topology_config.mobility.UE_mobility.grid_walk.grid_map.horizontal_grid = atoi(ch);
|
||||
} else if (vertical_grid_) {
|
||||
oai_emulation.topology_config.mobility.UE_mobility.grid_walk.grid_map.vertical_grid = atoi(ch);
|
||||
}
|
||||
*/
|
||||
} else if (grid_trip_type_) {
|
||||
oai_emulation.topology_config.mobility.UE_mobility.grid_walk.grid_trip_type.selected_option = strndup(ch, len);
|
||||
}
|
||||
@@ -1087,6 +1091,7 @@ void characters(void *user_data, const xmlChar *xmlch, int xmllen) { // called o
|
||||
} else if (eNB_mobility_) {
|
||||
if (eNB_mobility_type_) {
|
||||
oai_emulation.topology_config.mobility.eNB_mobility.eNB_mobility_type.selected_option = strndup(ch, len);
|
||||
|
||||
} else if (eNB_initial_distribution_) {
|
||||
oai_emulation.topology_config.mobility.eNB_mobility.eNB_initial_distribution.selected_option = strndup(ch, len);
|
||||
} else if (eNB_initial_coordinates_) {
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
1 0 2050 1500 0
|
||||
1 1 2150 1500 0
|
||||
|
||||
|
||||
@@ -105,12 +105,12 @@ void init(int max_sim_time) {
|
||||
sendExact(storageLength(storageStart));
|
||||
extractCommandStatus(receiveExact(), CMD_SUBSCRIBE_SIM_VARIABLE, description);
|
||||
if (departed == NULL) {
|
||||
departed = (String_list)malloc(sizeof(String_list)); // departed MUST point to HEAD
|
||||
departed = (string_list*) malloc(sizeof(string_list)); // departed MUST point to HEAD
|
||||
departed->string = NULL;
|
||||
departed->next = NULL;
|
||||
}
|
||||
if (arrived == NULL) {
|
||||
arrived = (String_list)malloc(sizeof(String_list)); // arrived MUST point to HEAD
|
||||
arrived = (string_list*) malloc(sizeof(string_list)); // arrived MUST point to HEAD
|
||||
arrived->string = NULL;
|
||||
arrived->next = NULL;
|
||||
}
|
||||
@@ -123,8 +123,8 @@ void init(int max_sim_time) {
|
||||
void processSubscriptions() {
|
||||
int noSubscriptions = readInt();
|
||||
|
||||
String_list tmp_departed = departed;
|
||||
String_list tmp_arrived = arrived;
|
||||
string_list* tmp_departed = departed;
|
||||
string_list* tmp_arrived = arrived;
|
||||
int s;
|
||||
for (s = 0; s<noSubscriptions; ++s) {
|
||||
|
||||
@@ -240,12 +240,12 @@ void commandSimulationStep(double time)
|
||||
extractCommandStatus(receiveExact(), CMD_SIMSTEP2, description);
|
||||
|
||||
if (departed == NULL) {
|
||||
departed = (String_list)malloc(sizeof(String_list)); // departed MUST point to HEAD
|
||||
departed = (string_list*) malloc(sizeof(string_list)); // departed MUST point to HEAD
|
||||
departed->string = NULL;
|
||||
departed->next = NULL;
|
||||
}
|
||||
if (arrived == NULL) {
|
||||
arrived = (String_list)malloc(sizeof(String_list)); // arrived MUST point to HEAD
|
||||
arrived = (string_list*) malloc(sizeof(string_list)); // arrived MUST point to HEAD
|
||||
arrived->string = NULL;
|
||||
arrived->next = NULL;
|
||||
}
|
||||
@@ -402,14 +402,14 @@ int commandGetMaxSUMONodesVariable()
|
||||
|
||||
|
||||
|
||||
void GetSpeed(NodePtr node, char * sumo_id)
|
||||
void GetSpeed(node_struct* node, char * sumo_id)
|
||||
{
|
||||
commandGetVehicleVariable(sumo_id, VAR_SPEED);
|
||||
double speed_double = readDouble();
|
||||
node->mob->speed = speed_double;
|
||||
}
|
||||
|
||||
void GetPosition(NodePtr node, char * sumo_id)
|
||||
void GetPosition(node_struct* node, char * sumo_id)
|
||||
{
|
||||
commandGetVehicleVariable(sumo_id, VAR_POSITION);
|
||||
double x_double = readDouble();
|
||||
@@ -420,6 +420,6 @@ void GetPosition(NodePtr node, char * sumo_id)
|
||||
if (y_double < 0.0)
|
||||
y_double = 0.0;
|
||||
|
||||
node->X_pos = x_double;
|
||||
node->Y_pos = y_double;
|
||||
node->x_pos = x_double;
|
||||
node->y_pos = y_double;
|
||||
}
|
||||
|
||||
@@ -56,8 +56,8 @@ int targetTime;
|
||||
|
||||
char *description;
|
||||
|
||||
String_list departed; // string list of all vehicles appearing in SUMO at the current time step
|
||||
String_list arrived; // string list of all vehicles leaving SUMO at the current time step
|
||||
string_list* departed; // string list of all vehicles appearing in SUMO at the current time step
|
||||
string_list* arrived; // string list of all vehicles leaving SUMO at the current time step
|
||||
|
||||
/**
|
||||
* Global parameters defined in storage_traci_OMG.h
|
||||
@@ -89,10 +89,10 @@ int extractCommandStatus(storage *, unsigned char , char *);
|
||||
void commandSimulationStep(double);
|
||||
|
||||
/**
|
||||
* \fn commandClose();
|
||||
* \fn commandClose(void);
|
||||
* \brief Send termination command to SUMO
|
||||
*/
|
||||
void commandClose();
|
||||
void commandClose(void);
|
||||
|
||||
/**
|
||||
* \fn commandGetVehicleVariable(char *vehID, int varID)
|
||||
@@ -103,10 +103,10 @@ void commandGetVehicleVariable(char *vehID, int varID);
|
||||
|
||||
|
||||
/**
|
||||
* \fn get_num_sumo_nodes()
|
||||
* \fn get_num_sumo_nodes(void)
|
||||
* \brief Return the total number of nodes to be simulated in SUMO
|
||||
*/
|
||||
int commandGetMaxSUMONodesVariable();
|
||||
int commandGetMaxSUMONodesVariable(void);
|
||||
|
||||
/**
|
||||
* \fn init(int max_sim_time)
|
||||
@@ -126,7 +126,7 @@ void processSubscriptions(void);
|
||||
* \param NodePtr node the pointer to the OAISim node
|
||||
* \param char *sumo_id the SUMO ID of the target node
|
||||
*/
|
||||
void GetSpeed(NodePtr node, char * sumo_id);
|
||||
void GetSpeed(node_struct* node, char * sumo_id);
|
||||
|
||||
/**
|
||||
* \fn void Position(NodePtr node, char * sumo_id);
|
||||
@@ -134,7 +134,7 @@ void GetSpeed(NodePtr node, char * sumo_id);
|
||||
* \param NodePtr node the pointer to the OAISim node
|
||||
* \param char *sumo_id the SUMO ID of the target node
|
||||
*/
|
||||
void GetPosition(NodePtr node, char * sumo_id);
|
||||
void GetPosition(node_struct* node, char * sumo_id);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
+351
-245
@@ -47,297 +47,392 @@
|
||||
|
||||
#define frand() ((double) rand() / (RAND_MAX+1))
|
||||
//#ifndef STANDALONE
|
||||
mapping nodes_type[] =
|
||||
{
|
||||
{"eNB", eNB},
|
||||
{"UE", UE},
|
||||
{NULL, -1}
|
||||
mapping nodes_type[] = {
|
||||
{"eNB", eNB}
|
||||
,
|
||||
{"UE", UE}
|
||||
,
|
||||
{NULL, -1}
|
||||
};
|
||||
|
||||
mapping nodes_status[] =
|
||||
{
|
||||
{"sleeping", 0},
|
||||
{"moving", 1},
|
||||
{NULL, -1}
|
||||
mapping nodes_status[] = {
|
||||
{"sleeping", 0}
|
||||
,
|
||||
{"moving", 1}
|
||||
,
|
||||
{NULL, -1}
|
||||
};
|
||||
|
||||
mapping mob_type[] =
|
||||
{
|
||||
{"STATIC", STATIC},
|
||||
{"RWP", RWP},
|
||||
{"RWALK", RWALK},
|
||||
{"TRACE", TRACE},
|
||||
{"SUMO", SUMO},
|
||||
{NULL, -1}
|
||||
mapping mob_type[] = {
|
||||
{"STATIC", STATIC}
|
||||
,
|
||||
{"RWP", RWP}
|
||||
,
|
||||
{"RWALK", RWALK}
|
||||
,
|
||||
{"TRACE", TRACE}
|
||||
,
|
||||
{"SUMO", SUMO}
|
||||
,
|
||||
{NULL, -1}
|
||||
};
|
||||
|
||||
//#endif
|
||||
NodePtr create_node(void) {
|
||||
NodePtr ptr;
|
||||
ptr = calloc(1, sizeof(node_struct));
|
||||
return ptr;
|
||||
|
||||
node_struct *
|
||||
create_node (void)
|
||||
{
|
||||
node_struct *ptr;
|
||||
ptr = calloc (1, sizeof (node_struct));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void delete_node(NodePtr node) {
|
||||
free(node->mob);
|
||||
|
||||
void
|
||||
delete_node (node_struct * node)
|
||||
{
|
||||
free (node->mob);
|
||||
node->mob = NULL;
|
||||
free(node);
|
||||
free (node);
|
||||
}
|
||||
|
||||
double randomGen(double a, double b){
|
||||
double
|
||||
randomgen (double a, double b)
|
||||
{
|
||||
|
||||
return ( rand()/(double)RAND_MAX ) * (b-a) + a;
|
||||
return (rand () / (double) RAND_MAX) * (b - a) + a;
|
||||
}
|
||||
|
||||
|
||||
MobilityPtr create_mobility(void) {
|
||||
MobilityPtr ptr;
|
||||
ptr = calloc(1, sizeof(mobility_struct));
|
||||
return ptr;
|
||||
mobility_struct *
|
||||
create_mobility (void)
|
||||
{
|
||||
mobility_struct *ptr;
|
||||
ptr = calloc (1, sizeof (mobility_struct));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
Node_list add_entry(NodePtr node, Node_list Node_Vector){
|
||||
Node_list entry = malloc(sizeof(node_list_struct));
|
||||
entry->node = node;
|
||||
entry->next = NULL;
|
||||
if (Node_Vector == NULL) {
|
||||
// LOG_D(OMG, "\nempty Node_list");
|
||||
//LOG_D(OMG, "\nadded elmt ID %d\n", entry->node->ID);
|
||||
return entry;
|
||||
node_list *
|
||||
add_entry (node_struct * node, node_list * node_vector_end)
|
||||
{
|
||||
node_list *entry = malloc (sizeof (struct node_list_struct));
|
||||
entry->node = node;
|
||||
entry->next = NULL;
|
||||
if (node_vector_end == NULL)
|
||||
{
|
||||
return entry;
|
||||
}
|
||||
else {
|
||||
Node_list tmp = Node_Vector;
|
||||
while (tmp->next != NULL){
|
||||
tmp = tmp->next;
|
||||
}
|
||||
tmp->next = entry;
|
||||
//LOG_D(OMG, "\nnon empty Node_list");
|
||||
//LOG_D(OMG, "added elmt ID %d\n", entry->node->ID);
|
||||
|
||||
return Node_Vector;
|
||||
else
|
||||
{
|
||||
node_list *tmp = node_vector_end;
|
||||
tmp->next = entry;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
Node_list remove_node_entry(NodePtr node, Node_list Node_Vector){
|
||||
Node_list list = Node_Vector;
|
||||
Node_list tmp, toRemove;
|
||||
if (list == NULL){
|
||||
return NULL;
|
||||
}
|
||||
if(list->node->ID == node->ID) {
|
||||
// TODO delete the entry
|
||||
toRemove = list;
|
||||
LOG_D(OMG,"removed entry for node %d \n",list->node->ID);
|
||||
if(list->next ==NULL) {
|
||||
Node_Vector = NULL;
|
||||
return NULL;
|
||||
|
||||
node_list *
|
||||
remove_node_entry (node_struct * node, node_list * node_vector)
|
||||
{
|
||||
node_list *list = node_vector;
|
||||
node_list *tmp, *toremove;
|
||||
if (list == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
Node_Vector = list->next;
|
||||
if (list->node->id == node->id)
|
||||
{
|
||||
// TODO delete the entry
|
||||
toremove = list;
|
||||
LOG_D (OMG, "removed entry for node %d \n", list->node->id);
|
||||
if (list->next == NULL)
|
||||
{
|
||||
node_vector = NULL;
|
||||
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
|
||||
void display_node_list(Node_list Node_Vector){
|
||||
Node_list tmp = Node_Vector;
|
||||
|
||||
while ((tmp != NULL) &&
|
||||
(tmp->node != NULL)){
|
||||
LOG_I(OMG,"[%s][%s] Node of ID %d is %s. Now, it is at location (%.3f, %.3f)\n",
|
||||
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 );
|
||||
void
|
||||
display_node_list (node_list * node_vector)
|
||||
{
|
||||
node_list *tmp = node_vector;
|
||||
if (tmp == NULL)
|
||||
{
|
||||
#ifdef STANDALONE
|
||||
printf ("Empty Node_list\n");
|
||||
#else
|
||||
LOG_I (OMG, "Empty Node_list\n");
|
||||
#endif
|
||||
}
|
||||
while (tmp != NULL)
|
||||
{
|
||||
/*LOG_I(OMG,"[%s][%s] Node of ID %d is %s. Now, it is at location (%.3f, %.3f)\n",
|
||||
map_int_to_str(mob_type, tmp->node->generator),
|
||||
map_int_to_str(nodes_type, tmp->node->type),
|
||||
tmp->node->ID,
|
||||
map_int_to_str(nodes_status, tmp->node->mobile),
|
||||
tmp->node->X_pos,
|
||||
tmp->node->Y_pos ); */
|
||||
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_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 );
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
void display_node_position(int ID, int generator, int type, int mobile, double X, double Y){
|
||||
LOG_I(OMG,"[%s][%s] Node of ID %d is %s. Now, it is at location (%.2f, %.2f) \n",
|
||||
map_int_to_str(mob_type, generator),
|
||||
map_int_to_str(nodes_type, type),
|
||||
ID,
|
||||
map_int_to_str(nodes_status, mobile),
|
||||
X,
|
||||
Y
|
||||
);
|
||||
void
|
||||
display_node_position (int id, int generator, int type, int mobile, double x,
|
||||
double y)
|
||||
{
|
||||
LOG_I (OMG,
|
||||
"[%s][%s] Node of ID %d is %s. Now, it is at location (%.2f, %.2f) \n",
|
||||
map_int_to_str (mob_type, generator), map_int_to_str (nodes_type,
|
||||
type), id,
|
||||
map_int_to_str (nodes_status, mobile), x, y);
|
||||
}
|
||||
|
||||
Node_list filter(Node_list Vector, int node_type){
|
||||
Node_list tmp1, tmp2;
|
||||
tmp1 = Vector;
|
||||
node_list *
|
||||
filter (node_list * vector, int node_type)
|
||||
{
|
||||
node_list *tmp1, *tmp2;
|
||||
tmp1 = vector;
|
||||
tmp2 = NULL;
|
||||
while (tmp1 != NULL){
|
||||
if (tmp1->node->type == node_type){
|
||||
tmp2 = add_entry(tmp1->node, tmp2);
|
||||
while (tmp1 != NULL)
|
||||
{
|
||||
if (tmp1->node->type == node_type)
|
||||
{
|
||||
tmp2 = add_entry (tmp1->node, tmp2);
|
||||
}
|
||||
tmp1 = tmp1->next;
|
||||
}
|
||||
tmp1 = tmp1->next;
|
||||
}
|
||||
return tmp2;
|
||||
}
|
||||
|
||||
void delete_node_entry(Node_list entry) {
|
||||
NodePtr node = entry->node;
|
||||
delete_node(node);
|
||||
entry->node = NULL;
|
||||
free(entry);
|
||||
|
||||
void
|
||||
delete_node_entry (node_list * 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;
|
||||
Node_list current, previous;
|
||||
node_list *current, *previous;
|
||||
//int cond=0;
|
||||
//int i=0;
|
||||
if (list == NULL){
|
||||
found = 1; //false
|
||||
return NULL;
|
||||
}
|
||||
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 ");
|
||||
if (list == NULL)
|
||||
{
|
||||
found = 1; //false
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
int length(char* s){
|
||||
int count = 0;
|
||||
while(s[count] != '\0'){
|
||||
++count;
|
||||
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;
|
||||
}
|
||||
return count;
|
||||
//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;
|
||||
|
||||
}
|
||||
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;
|
||||
Node_list current;
|
||||
|
||||
if (list == 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;
|
||||
node_list *current;
|
||||
|
||||
if (list == NULL)
|
||||
{
|
||||
printf (" Node_LIST for nodeID %d is NULL \n ", nid);
|
||||
return NULL;
|
||||
}
|
||||
//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);
|
||||
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
|
||||
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;
|
||||
} //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 tmp;
|
||||
node_list *
|
||||
clear_node_list (node_list * list)
|
||||
{
|
||||
node_list *tmp;
|
||||
|
||||
if (list == NULL){
|
||||
return NULL;
|
||||
}
|
||||
else{
|
||||
while (list->next !=NULL) {
|
||||
tmp = list;
|
||||
list = list->next;
|
||||
delete_node_entry(tmp);
|
||||
}
|
||||
delete_node_entry(list); // clearing the last one
|
||||
}
|
||||
if (list == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (list->next != NULL)
|
||||
{
|
||||
tmp = list;
|
||||
list = list->next;
|
||||
delete_node_entry (tmp);
|
||||
}
|
||||
delete_node_entry (list); // clearing the last one
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// TODO rewrite this part...not working correctly
|
||||
Node_list reset_node_list(Node_list list) {
|
||||
Node_list tmp;
|
||||
Node_list last = list;
|
||||
if (list == NULL){
|
||||
//printf("Node_list is NULL\n");
|
||||
return NULL;
|
||||
}
|
||||
else{
|
||||
while (list->next !=NULL) {
|
||||
tmp = list;
|
||||
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);
|
||||
}
|
||||
node_list *
|
||||
reset_node_list (node_list * list)
|
||||
{
|
||||
node_list *tmp;
|
||||
node_list *last = list;
|
||||
if (list == NULL)
|
||||
{
|
||||
//printf("Node_list is NULL\n");
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (list->next != NULL)
|
||||
{
|
||||
tmp = list;
|
||||
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;
|
||||
}
|
||||
|
||||
// TODO rewrite this part...not working correctly
|
||||
String_list clear_String_list(String_list list) {
|
||||
String_list tmp;
|
||||
string_list *
|
||||
clear_string_list (string_list * list)
|
||||
{
|
||||
string_list *tmp;
|
||||
|
||||
if (list == NULL){
|
||||
return NULL;
|
||||
}
|
||||
else{
|
||||
while (list->next !=NULL) {
|
||||
tmp = list;
|
||||
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...
|
||||
}
|
||||
if (list == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (list->next != NULL)
|
||||
{
|
||||
tmp = list;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -347,32 +442,43 @@ String_list clear_String_list(String_list list) {
|
||||
* with string value NULL
|
||||
*/
|
||||
/* map a string to an int. Takes a mapping array and a string as arg */
|
||||
int map_str_to_int(mapping *map, const char *str){
|
||||
while (1) {
|
||||
if (map->name == NULL) {
|
||||
return(-1);
|
||||
}
|
||||
if (!strcmp(map->name, str)) {
|
||||
return(map->value);
|
||||
}
|
||||
map++;
|
||||
int
|
||||
map_str_to_int (mapping * map, const char *str)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
if (map->name == NULL)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
if (!strcmp (map->name, str))
|
||||
{
|
||||
return (map->value);
|
||||
}
|
||||
map++;
|
||||
}
|
||||
}
|
||||
|
||||
/* map an int to a string. Takes a mapping array and a value */
|
||||
char *map_int_to_str(mapping *map, int val) {
|
||||
while (1) {
|
||||
if (map->name == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (map->value == val) {
|
||||
return map->name;
|
||||
}
|
||||
map++;
|
||||
char *
|
||||
map_int_to_str (mapping * map, int val)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
if (map->name == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (map->value == val)
|
||||
{
|
||||
return map->name;
|
||||
}
|
||||
map++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
+100
-76
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Eurecom OpenAirInterface
|
||||
Copyright(c) 1999 - 2014 Eurecom
|
||||
Copyright(c) 1999 - 2011 Eurecom
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
@@ -28,16 +28,9 @@
|
||||
*******************************************************************************/
|
||||
|
||||
/**
|
||||
* \file defs.h
|
||||
* \brief Typedefs & Prototypes of OMG functions
|
||||
* \author Navid Nikaein and Andre Gomes (one source)
|
||||
* \date 2014
|
||||
* \version 1.0
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
* \file defs.h
|
||||
* \brief Typedefs & Prototypes of OMG functions
|
||||
*/
|
||||
|
||||
#ifndef __DEFS_H__
|
||||
#define __DEFS_H__
|
||||
@@ -61,69 +54,90 @@ int map_str_to_int(mapping *map, const char *str);
|
||||
char *map_int_to_str(mapping *map, int val);
|
||||
#endif
|
||||
|
||||
/*!A sructure that includes all the characteristic mobility elements of a node */
|
||||
typedef struct mobility_struct {
|
||||
double X_from; /*!< The X coordinate of the previous location of the node */
|
||||
double Y_from; /*!< The Y coordinate of the previous location of the node */
|
||||
double X_to; /*!< The X coordinate of the destination location of the node */
|
||||
double Y_to; /*!< The Y coordinate of the destination location of the node */
|
||||
/****************************************************************************
|
||||
!A sructure that includes all the characteristic mobility elements of a node
|
||||
*****************************************************************************/
|
||||
struct mobility_struct {
|
||||
double x_from; /*!< The X coordinate of the previous location of the node */
|
||||
double y_from; /*!< The Y coordinate of the previous location of the node */
|
||||
double x_to; /*!< The X coordinate of the destination location of the node */
|
||||
double y_to; /*!< The Y coordinate of the destination location of the node */
|
||||
double speed; /*!< The speed of the node */
|
||||
double sleep_duration; /*!< The sleep duration of the node (Used with the RWP model) */
|
||||
double azimuth; /*!< The direction in which the node moves (Used with RWALK model) */
|
||||
double journey_time; /*!< The duration of the node trip */
|
||||
double start_journey; /*!< The instant on which the node trip starts*/
|
||||
double target_time;/*!<The time instant before the node should complete>*/ double target_speed;/*!<The time instant before the node should complete>*/
|
||||
}mobility_struct;
|
||||
double target_time;/*!<The time instant before the node should complete>*/
|
||||
double target_speed;/*!<The time instant before the node should complete>*/
|
||||
};
|
||||
|
||||
typedef struct mobility_struct *MobilityPtr; /*!< The typedef that reflects a #mobility_struct*/
|
||||
typedef struct mobility_struct mobility_struct; /*!< The typedef that reflects a #mobility_struct*/
|
||||
|
||||
/*!A sructure that defines a node and its associated informaion */
|
||||
typedef struct node_struct {
|
||||
int ID; /*!< The identifier of the node in question */
|
||||
/******************************************************************************
|
||||
!A sructure that defines a node and its associated informaion
|
||||
*******************************************************************************/
|
||||
struct node_struct {
|
||||
int id; /*!< The identifier of the node in question */
|
||||
int gid; /*!< given id of node used for trace mobility */
|
||||
int type; /*!< The node's type, it is one of types enumarated in #node_types */
|
||||
int mobile; /*!< The node status: static or mobile */
|
||||
double X_pos; /*!< The X coordinate of the current location of the node */
|
||||
double Y_pos; /*!< The Y coordinate of the current location of the node */
|
||||
mobility_struct *mob; /*!< An instantiation of the structure #mobility_struct that includes the mobility elements corresponding to the node*/
|
||||
double x_pos; /*!< The X coordinate of the current location of the node */
|
||||
double y_pos; /*!< The Y coordinate of the current location of the node */
|
||||
struct mobility_struct *mob; /*!< An instantiation of the structure #mobility_struct that includes the mobility elements corresponding to the node*/
|
||||
int generator; /*!< The mobility generator according to which the node is moving or stagnating. It is one of the types enumarated in #mobility_types*/
|
||||
}node_struct;
|
||||
int block_num; /*!<block identification for connected domain rwp*/
|
||||
int event_num;
|
||||
};
|
||||
|
||||
typedef struct node_struct* NodePtr; /*!< The typedef that reflects a #node_struct*/
|
||||
typedef struct node_struct node_struct; /*!< The typedef that reflects a #node_struct*/
|
||||
|
||||
/*!A sructure that gathers all the existing nodes */
|
||||
/********************************************************************************
|
||||
!A sructure that gathers all the existing nodes
|
||||
*********************************************************************************/
|
||||
struct node_list_struct {
|
||||
node_struct *node; /*!< Avariable of type #NodePtr. It represents a node */
|
||||
struct node_struct *node; /*!< Avariable of type #NodePtr. It represents a node */
|
||||
struct node_list_struct *next; /*!< A pointer to the next element */
|
||||
}node_list_struct;
|
||||
};
|
||||
|
||||
typedef struct node_list_struct* Node_list; /*!< The typedef that reflects a #node_list_struct*/
|
||||
typedef struct node_list_struct node_list; /*!< The typedef that reflects a #node_list_struct*/
|
||||
|
||||
/*!A sructure that represents a peer (Node, Time), i.e the node in question and its job (move or sleep) execution time. It is the atomic component of the #job_list_struct structure*/
|
||||
typedef struct pair_struct {
|
||||
/********************************************************************************
|
||||
!A sructure that represents a peer (Node, Time),
|
||||
i.e the node in question and its job (move or sleep) execution time.
|
||||
It is the atomic component of the #job_list_struct structure
|
||||
*********************************************************************************/
|
||||
|
||||
struct pair_struct {
|
||||
node_struct *b; /*!< A variable of type #NodePtr. It represents a node */
|
||||
double a; /*!< The corresponding time of job execution */
|
||||
}pair_struct;
|
||||
double next_event_t; /*!< The corresponding time of job execution */
|
||||
};
|
||||
|
||||
typedef struct pair_struct* Pair; /*!< The typedef that reflects a #pair_struct*/
|
||||
typedef struct pair_struct pair_struct; /*!< The typedef that reflects a #pair_struct*/
|
||||
|
||||
|
||||
/*!A sructure that gathers the jobs to be executed by all the non static nodes. In the context of OMG, a job is either a move or a sleep */
|
||||
/*****************************************************************************
|
||||
!A sructure that gathers the jobs to be executed by all the non static nodes.
|
||||
In the context of OMG, a job is either a move or a sleep
|
||||
*****************************************************************************/
|
||||
struct job_list_struct {
|
||||
Pair pair; /*!< A variable of type #Pair. It represents a (Node, job-execution Time) peer */
|
||||
pair_struct* pair; /*!< A variable of type #Pair. It represents a (Node, job-execution Time) peer */
|
||||
struct job_list_struct *next; /*!< A pointer to the next element */
|
||||
}job_list_struct;
|
||||
typedef struct job_list_struct* Job_list; /*!< The typedef that reflects a #job_list_struct*/
|
||||
};
|
||||
typedef struct job_list_struct job_list; /*!< The typedef that reflects a #job_list_struct*/
|
||||
|
||||
/*!A sructure that gathers the ultimate parameters needed to launch a simulation scenario */
|
||||
typedef struct omg_global_param{
|
||||
/****************************************************************************************
|
||||
!A sructure that gathers the ultimate parameters needed to launch a simulation scenario
|
||||
***************************************************************************************/
|
||||
typedef struct{
|
||||
int nodes; /*!< The total number of nodes */
|
||||
double min_X; /*!< The minimum value that the X coordinate might take. In other words, the minimum boundary of the simulation area according to the X axis */
|
||||
double max_X; /*!< The maximum value that the X coordinate might take, i.e the maximum boundary of the simulation area according to the X axis*/
|
||||
double min_Y; /*!< The minimum value that the Y coordinate might take, i.e the minimum boundary of the simulation area according to the Y axis */
|
||||
double max_Y; /*!< The minimum value that the Y coordinate might take, i.e the maximum boundary of the simulation area according to the Y axis */
|
||||
bool user_fixed; /*!< Sets if the coordinates are user defined*/
|
||||
double fixed_X; /*!< The user defined x value*/
|
||||
double fixed_Y; /*!< The user defined y value*/
|
||||
//int number_of_nodes[MAX_NUM_NODE_TYPES];
|
||||
double min_x; /*!< The minimum value that the X coordinate might take. In other words, the minimum boundary of the simulation area according to the X axis */
|
||||
double max_x; /*!< The maximum value that the X coordinate might take, i.e the maximum boundary of the simulation area according to the X axis*/
|
||||
double min_y; /*!< The minimum value that the Y coordinate might take, i.e the minimum boundary of the simulation area according to the Y axis */
|
||||
double max_y; /*!< The minimum value that the Y coordinate might take, i.e the maximum boundary of the simulation area according to the Y axis */
|
||||
bool user_fixed; /*!< Sets if the coordinates are user defined*/
|
||||
double fixed_x; /*!< The user defined x value*/
|
||||
double fixed_y; /*!< The user defined y value*/
|
||||
double min_speed; /*!< The minimum speed. It should be different than 0.0 in order to avoid instability*/
|
||||
double max_speed; /*!< The maximum allowed speed */
|
||||
double min_journey_time; /*!< The minimum allowed trip duration. It should be different than 0.0 in order to avoid instability and properly reflect the mobility model behavior */
|
||||
@@ -133,7 +147,12 @@ typedef struct omg_global_param{
|
||||
double min_sleep; /*!< The minimum allowed sleep duration. It should be different than 0.0 in order to avoid instability */
|
||||
double max_sleep; /*!< The minimum allowed sleep duration*/
|
||||
int mobility_type; /*!< The chosen mobility model for the nodes in question. It should be one of the types inumarated as #mobility_types*/
|
||||
int rwp_type; /*!< The chosen RWP mobility model for the nodes in question either RESTRICTED or CONNECTED_DOMAIN. */
|
||||
int nodes_type; /*!< The type of the nodes in question. It should be one of the types inumarated as #node_types */
|
||||
//int nodes_mob_type[MAX_NUM_NODE_TYPES];
|
||||
int max_vertices; /*!<maximum number of verices in the grid>*/
|
||||
int max_block_num; /*!<maximum number of blocks in the grid>*/
|
||||
|
||||
int seed; /*!< The seed used to generate the random positions*/
|
||||
char* mobility_file; /*!< The mobility file name containing the mobility traces used by the TRACE model; DEFAULT: TRACE/example_trace.tr */
|
||||
char* sumo_command; /*!< The command to start SUMO; Either 'sumo' or 'sumo-gui' in case a GUI would be required; see SUMO for further details; DEFAULT: sumo */
|
||||
@@ -145,13 +164,15 @@ typedef struct omg_global_param{
|
||||
int sumo_port; /*!< The port number attached to SUMO on the host DEFAULT: TBC */
|
||||
}omg_global_param;
|
||||
|
||||
/*!A string List structure */
|
||||
/******************************************************************************
|
||||
!A string List structure
|
||||
*******************************************************************************/
|
||||
struct string_list_struct {
|
||||
char* string; /*! a string */
|
||||
struct string_list_struct *next; /*!< A pointer to the next string in the list */
|
||||
}string_list_struct;
|
||||
};
|
||||
|
||||
typedef struct string_list_struct* String_list; /*!< The typedef that reflects a #string_list_struct*/
|
||||
typedef struct string_list_struct string_list; /*!< The typedef that reflects a #string_list_struct*/
|
||||
|
||||
/* PROTOTYPES */
|
||||
|
||||
@@ -171,7 +192,7 @@ void update_node_vector(int mobility_type, double cur_time);
|
||||
* \param nID a variable of type int that represents the specific node's ID
|
||||
* \return a NodePtr structure that stores the updated information about the specific node ((X,Y) coordinates), speed, etc.)
|
||||
*/
|
||||
NodePtr get_node_position(int node_type, int nID);
|
||||
node_struct* get_node_position(int node_type, int nid);
|
||||
|
||||
|
||||
/**
|
||||
@@ -181,7 +202,7 @@ NodePtr get_node_position(int node_type, int nID);
|
||||
* \param Node_Vector a pointer of type Node_list that represents the Node_Vector storing all the nodes of the specified mobility type
|
||||
* \return the Node_list to which a new entry is added
|
||||
*/
|
||||
Node_list add_entry(NodePtr node, Node_list Node_Vector);
|
||||
node_list* add_entry(node_struct* node, node_list* node_vector);
|
||||
|
||||
/**
|
||||
* \fn Node_list remove_node_entry(NodePtr node, Node_list Node_Vector)
|
||||
@@ -191,14 +212,14 @@ Node_list add_entry(NodePtr node, Node_list Node_Vector);
|
||||
* \param Node_Vector a pointer of type Node_list that represents the Node_Vector storing all the nodes of the specified mobility type
|
||||
* \return the Node_list to which a new entry is removed
|
||||
*/
|
||||
Node_list remove_node_entry(NodePtr node, Node_list Node_Vector);
|
||||
node_list* remove_node_entry(node_struct* node, node_list* node_vector);
|
||||
|
||||
/**
|
||||
* \fn void display_node_list(Node_list Node_Vector)
|
||||
* \brief Display the useful informaion about the specified Node_list (for instance the nodes IDs, their types (UE, eNB, etc.), their corresponding mobility models, their status (moving, sleeping) and their current positions)
|
||||
* \param Node_Vector a pointer of type Node_list that represents the Node_list to be dispalyed
|
||||
*/
|
||||
void display_node_list(Node_list Node_Vector);
|
||||
void display_node_list(node_list* node_vector);
|
||||
|
||||
|
||||
/**
|
||||
@@ -209,7 +230,7 @@ void display_node_list(Node_list Node_Vector);
|
||||
* \param node_type an int that represents the type of the node to be removed from the Node_list
|
||||
* \return a pointer to the Node_list from which a new entry is removed
|
||||
*/
|
||||
Node_list remove_node(Node_list list, int nID, int node_type);
|
||||
node_list* remove_node(node_list* list, int nid, int node_type);
|
||||
|
||||
/**
|
||||
* \fn NodePtr find_node(Node_list list, int nID, int node_type)
|
||||
@@ -219,21 +240,21 @@ Node_list remove_node(Node_list list, int nID, int node_type);
|
||||
* \param node_type an int that represents the type of the node to be located in the Node_list
|
||||
* \return a pointer to the Node
|
||||
*/
|
||||
NodePtr find_node(Node_list list, int nID, int node_type);
|
||||
node_struct* find_node(node_list* list, int nid, int node_type);
|
||||
|
||||
/**
|
||||
* \fn void delete_entry(Node_list Node_Vector)
|
||||
* \brief Delete a Node_list entry node; calls delete_node to subsequently delete the node; free the memory
|
||||
* \param list a pointer of type Node_list that represents the entry to be deleted
|
||||
*/
|
||||
void delete_entry(Node_list Node_Vector);
|
||||
void delete_entry(node_list* node_vector);
|
||||
|
||||
/**
|
||||
* \fn void delete_entry(NodePtr node)
|
||||
* \brief Delete a node, and all subsequent data in its structure; free the memory
|
||||
* \param node a pointer to the node that should be deleted
|
||||
*/
|
||||
void delete_node(NodePtr node);
|
||||
void delete_node(node_struct* node);
|
||||
|
||||
/**
|
||||
* \fn void clear node_List(Node_list list)
|
||||
@@ -241,7 +262,7 @@ void delete_node(NodePtr node);
|
||||
* \param list a pointer of type Node_list that represents the list to be cleared
|
||||
* \return reference to the HEAD of the cleared Node_list
|
||||
*/
|
||||
Node_list clear_node_List(Node_list list);
|
||||
node_list* clear_node_List(node_list* list);
|
||||
|
||||
/**
|
||||
* \fn void init_node_list(Node_list list)
|
||||
@@ -249,7 +270,7 @@ Node_list clear_node_List(Node_list list);
|
||||
* \param list a pointer of type Node_list that represents the list to be reset
|
||||
* \return reference to the HEAD of the reset Node_list
|
||||
*/
|
||||
Node_list reset_node_list(Node_list list);
|
||||
node_list* reset_node_list(node_list* list);
|
||||
|
||||
/**
|
||||
* \fn void display_node_position(int ID, int generator, int type, int mobile, double X, double Y)
|
||||
@@ -261,7 +282,7 @@ Node_list reset_node_list(Node_list list);
|
||||
* \param X the node's current location according to the X axis
|
||||
* \param Y the node's current location according to the Y axis
|
||||
*/
|
||||
void display_node_position(int ID, int generator, int type, int mobile, double X, double Y);
|
||||
void display_node_position(int id, int generator, int type, int mobile, double x, double y);
|
||||
|
||||
|
||||
/**
|
||||
@@ -271,7 +292,7 @@ void display_node_position(int ID, int generator, int type, int mobile, double X
|
||||
* \param node_type the desired type
|
||||
* \return a pointer to a new Node_list which is the input Node_list after filtering
|
||||
*/
|
||||
Node_list filter(Node_list Vector, int node_type);
|
||||
node_list* filter(node_list* vector, int node_type);
|
||||
|
||||
|
||||
/**
|
||||
@@ -281,7 +302,7 @@ Node_list filter(Node_list Vector, int node_type);
|
||||
* \param b upper limit
|
||||
* \return double: the generated random number
|
||||
*/
|
||||
double randomGen(double a, double b);
|
||||
double randomgen(double a, double b);
|
||||
|
||||
|
||||
/**
|
||||
@@ -289,7 +310,7 @@ double randomGen(double a, double b);
|
||||
* \brief Creates a new #NodePtr by allocating the needed memory space for it
|
||||
* \return the created node structure
|
||||
*/
|
||||
NodePtr create_node(void);
|
||||
node_struct* create_node(void);
|
||||
|
||||
|
||||
/**
|
||||
@@ -297,7 +318,7 @@ NodePtr create_node(void);
|
||||
* \brief Creates a new #MobilityPtr by allocating the needed memory space for it
|
||||
* \return the created mobility structure
|
||||
*/
|
||||
MobilityPtr create_mobility(void);
|
||||
mobility_struct* create_mobility(void);
|
||||
|
||||
|
||||
/**
|
||||
@@ -307,7 +328,8 @@ MobilityPtr create_mobility(void);
|
||||
* \param Job_Vector a variable #Job_list that represents the Job_list that stores all the scheduled jobs
|
||||
* \return the created mobility structure
|
||||
*/
|
||||
Job_list add_job(Pair job, Job_list Job_Vector);
|
||||
job_list* add_job(pair_struct* job, job_list* job_vector);
|
||||
job_list* addjob(pair_struct* job, job_list* job_vector);
|
||||
|
||||
|
||||
/**
|
||||
@@ -315,9 +337,11 @@ Job_list add_job(Pair job, Job_list Job_Vector);
|
||||
* \brief Traverse the Job_Vector to diplay its contents
|
||||
* \param Job_Vector the structure that stoks all the jobs
|
||||
*/
|
||||
void display_job_list(Job_list Job_Vector);
|
||||
|
||||
|
||||
void display_job_list(double curr_t, job_list* job_vector);
|
||||
/**
|
||||
*time average of nodes speed
|
||||
*/
|
||||
unsigned int nodes_avgspeed(job_list* job_vector);
|
||||
/**
|
||||
* \fn Job_list job_list_sort (Job_list list, Job_list end)
|
||||
* \brief Called by the function Job_list quick_sort (Job_list list), it executes the quick sort
|
||||
@@ -325,7 +349,7 @@ void display_job_list(Job_list Job_Vector);
|
||||
* \param end Job_list needed for intermediate computation
|
||||
* \return a Job_list that is used by Job_list quick_sort (Job_list list) to perform the sort operation
|
||||
*/
|
||||
Job_list job_list_sort (Job_list list, Job_list end);
|
||||
job_list* job_list_sort (job_list* list, job_list* end);
|
||||
|
||||
|
||||
/**
|
||||
@@ -334,7 +358,7 @@ Job_list job_list_sort (Job_list list, Job_list end);
|
||||
* \param list the structure that stoks all the jobs
|
||||
* \return the sorted list
|
||||
*/
|
||||
Job_list quick_sort (Job_list list);
|
||||
job_list* quick_sort (job_list* list);
|
||||
|
||||
|
||||
/**
|
||||
@@ -345,7 +369,7 @@ Job_list quick_sort (Job_list list);
|
||||
* \param node_type the type of the node whose job should be removed
|
||||
* \return the updated Job_list after removing the job in question
|
||||
*/
|
||||
Job_list remove_job(Job_list list, int nID, int node_type);
|
||||
job_list* remove_job(job_list* list, int nid, int node_type);
|
||||
|
||||
/**
|
||||
* \fn int length(char* s)
|
||||
@@ -361,7 +385,7 @@ int length(char* s);
|
||||
* \param list the String_list to be cleared;
|
||||
* \return reference to the HEAD of the cleared String_list
|
||||
*/
|
||||
String_list clear_String_list(String_list list);
|
||||
string_list* clear_string_list(string_list* list);
|
||||
|
||||
/**
|
||||
* \fn void usage()
|
||||
|
||||
@@ -0,0 +1,242 @@
|
||||
/*******************************************************************************
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
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
|
||||
|
||||
+153
-108
@@ -29,8 +29,8 @@
|
||||
|
||||
/*! \file job.c
|
||||
* \brief handle jobs for future nodes' update
|
||||
* \author M. Mahersi, J. Harri, N. Nikaein,
|
||||
* \date 2011
|
||||
* \author S. Gashaw, M. Mahersi, J. Harri, N. Nikaein,
|
||||
* \date 2014
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email:
|
||||
@@ -44,127 +44,172 @@
|
||||
|
||||
#include "omg.h"
|
||||
|
||||
Job_list add_job(Pair job, Job_list Job_Vector){
|
||||
Job_list entry = malloc(sizeof(Job_list));
|
||||
entry->pair = job;
|
||||
|
||||
//LOG_D(OMG, " Job_Vector_len %d", Job_Vector_len);
|
||||
entry->next = NULL;
|
||||
job_list *
|
||||
add_job (pair_struct * job, job_list * job_vector)
|
||||
{
|
||||
|
||||
if (Job_Vector == NULL) {
|
||||
//LOG_D(OMG, "empty Job_Vector\n");
|
||||
//LOG_D(OMG, "added elmt ID %d\n", entry->pair->b->ID);
|
||||
return entry;
|
||||
job_list *tmp;
|
||||
job_list *entry = (job_list *) malloc (sizeof (struct job_list_struct));
|
||||
entry->pair = job;
|
||||
entry->next = NULL;
|
||||
|
||||
if (job_vector != NULL)
|
||||
{
|
||||
|
||||
tmp = job_vector;
|
||||
tmp->next = entry;
|
||||
}
|
||||
else {
|
||||
Job_list tmp = Job_Vector;
|
||||
while (tmp->next != NULL){
|
||||
tmp = tmp->next;
|
||||
}
|
||||
tmp->next = entry;
|
||||
//LOG_D(OMG, "non empty Job_Vector\n");
|
||||
//LOG_D(OMG, "dded elmt ID %d\n", entry->pair->b->ID);
|
||||
|
||||
return Job_Vector;
|
||||
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
|
||||
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);
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// display list of jobs
|
||||
void display_job_list(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))
|
||||
LOG_D(OMG, "node %d \ttime %.2f\n", tmp->pair->b->ID, tmp->pair->a);
|
||||
|
||||
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
|
||||
Job_list job_list_sort (Job_list list, Job_list end){
|
||||
|
||||
Job_list pivot, tmp, next, before, after;
|
||||
if ( list != end && list->next != end ){
|
||||
|
||||
pivot = list;
|
||||
before = pivot;
|
||||
after = end;
|
||||
for ( tmp=list->next; tmp != end; tmp=next )
|
||||
{
|
||||
next = tmp->next;
|
||||
if (tmp->pair->a > pivot->pair->a)
|
||||
tmp->next = after, after = tmp;
|
||||
else
|
||||
tmp->next = before, before = tmp;
|
||||
}
|
||||
|
||||
before = job_list_sort (before, pivot);
|
||||
after = job_list_sort (after, end);
|
||||
|
||||
pivot->next = after;
|
||||
return before;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
Job_list quick_sort (Job_list list)
|
||||
job_list *
|
||||
job_list_sort (job_list * list, job_list * end)
|
||||
{
|
||||
return job_list_sort(list, NULL);
|
||||
|
||||
job_list *pivot, *tmp, *next, *before, *after;
|
||||
if (list != end && list->next != end)
|
||||
{
|
||||
|
||||
pivot = list;
|
||||
before = pivot;
|
||||
after = end;
|
||||
for (tmp = list->next; tmp != end; tmp = next)
|
||||
{
|
||||
next = tmp->next;
|
||||
if (tmp->pair->next_event_t > pivot->pair->next_event_t)
|
||||
tmp->next = after, after = tmp;
|
||||
else
|
||||
tmp->next = before, before = tmp;
|
||||
}
|
||||
|
||||
before = job_list_sort (before, pivot);
|
||||
after = job_list_sort (after, end);
|
||||
|
||||
pivot->next = after;
|
||||
return before;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
job_list *
|
||||
quick_sort (job_list * list)
|
||||
{
|
||||
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;
|
||||
if (list == NULL){
|
||||
return NULL;
|
||||
}
|
||||
else{ //start search
|
||||
current = list;
|
||||
if ((current != NULL) && (current->pair->b->ID == nID) && (current->pair->b->type == node_type )){LOG_D(OMG, "(current != NULL) && (current->pair->b->ID != nID) && (current->pair->b->type != node_type ");}
|
||||
while ( (current != NULL) && ((current->pair->b->ID != nID) || (current->pair->b->type != node_type ))){
|
||||
LOG_D(OMG, "current->pair->b->ID %d",current->pair->b->ID);
|
||||
LOG_D(OMG, "nID %d",nID);
|
||||
LOG_D(OMG, "current->pair->b->type %d",current->pair->b->type ); // UE, eNB 1
|
||||
LOG_D(OMG, "node_type %d",node_type ); //UE, eNB 0
|
||||
LOG_D(OMG, "current->pair->b->generator %d",current->pair->b->generator ); //static
|
||||
|
||||
LOG_D(OMG, "i = %d", i);
|
||||
previous = current; // previous hobbles after
|
||||
job_list *current, *previous;
|
||||
|
||||
current = list;
|
||||
previous = NULL;
|
||||
while (current != NULL)
|
||||
{
|
||||
if (current->pair->b->id == nid && current->pair->b->type == node_type)
|
||||
{
|
||||
if (current == list || previous == NULL)
|
||||
list = current->next;
|
||||
else
|
||||
previous->next = current->next;
|
||||
|
||||
free (current);
|
||||
break;
|
||||
|
||||
}
|
||||
previous = current;
|
||||
current = current->next;
|
||||
i++;
|
||||
if (current ==NULL){LOG_D(OMG, "current ==NULL");}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//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;
|
||||
}
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
CC= gcc
|
||||
|
||||
OBJstatic = omg.c common.c static.c
|
||||
OBJrwp = omg.c common.c job.c rwp.c
|
||||
OBJrwp = omg.c common.c job.c rwp.c grid.c
|
||||
OBJrwalk = omg.c common.c job.c rwalk.c
|
||||
OBJtrace = omg.c common.c job.c trace.c mobility_parser.c omg_hashtable.c
|
||||
OBJtrace = omg.c common.c job.c trace.c mobility_parser.c hashtable.c
|
||||
OBJsumo = omg.c common.c sumo.c client_traci_OMG.c socket_traci_OMG.c storage_traci_OMG.c id_manager.c
|
||||
|
||||
OBJ = omg.c common.c static.c job.c rwp.c rwalk.c trace.c sumo.c mobility_parser.c omg_hashtable.c client_traci_OMG.c socket_traci_OMG.c storage_traci_OMG.c id_manager.c
|
||||
OBJ = omg.c common.c static.c job.c rwp.c rwalk.c trace.c steadystaterwp.c sumo.c grid.c mobility_parser.c hashtable.c client_traci_OMG.c socket_traci_OMG.c storage_traci_OMG.c id_manager.c
|
||||
|
||||
CFLAGS += -DSTANDALONE -DUSER_MODE
|
||||
CFLAGS += -DSTANDALONE -DUSER_MODE -g
|
||||
|
||||
.PHONY: help staticOMG rwpOMG clean
|
||||
|
||||
|
||||
+210
-426
@@ -29,11 +29,11 @@
|
||||
|
||||
/*! \file mobility_parser.c
|
||||
* \brief A parser for trace-based mobility information (parsed from a file)
|
||||
* \author S. Uppoor
|
||||
* \date 2011
|
||||
* \author S. Gashaw, N. Nikaein, J. Harri
|
||||
* \date 2014
|
||||
* \version 0.1
|
||||
* \company INRIA
|
||||
* \email: sandesh.uppoor@inria.fr
|
||||
* \company EURECOM
|
||||
* \email:
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
@@ -42,442 +42,226 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "mobility_parser.h"
|
||||
#include "omg_hashtable.h"
|
||||
#include "omg.h"
|
||||
#include <math.h>
|
||||
|
||||
extern hash_table_t **table;
|
||||
extern node_info **list_head;
|
||||
|
||||
node_info* head_node_info =NULL;
|
||||
omg_hash_table_t* table=NULL;
|
||||
|
||||
//need to be removed , used only once (old code)
|
||||
struct Exnode* gen_list(){
|
||||
struct Exnode* head = NULL;
|
||||
return head;
|
||||
}
|
||||
|
||||
|
||||
//read the mobility file and generates a hashtable of linked list with key pointing to vehicle id
|
||||
void read_mobility_file(char* mobility_file[]){
|
||||
//read the mobility file and generates a hashtable of linked list
|
||||
void
|
||||
parse_data (char *trace_file, int node_type)
|
||||
{
|
||||
FILE *fp;
|
||||
char str[128],*p;
|
||||
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);
|
||||
}
|
||||
}
|
||||
char *pch, *p;
|
||||
char str[128];
|
||||
int fmt, id = 0, gid;
|
||||
node_container *value;
|
||||
|
||||
//if(table==NULL)
|
||||
create_new_table (node_type);
|
||||
|
||||
if(list_head ==NULL)
|
||||
list_head = (node_info **) calloc (MAX_NUM_NODE_TYPES, sizeof (node_info*));
|
||||
|
||||
if (list_head == NULL )
|
||||
{
|
||||
LOG_E (OMG, "-------node list table creation failed--------\n");
|
||||
exit (-1);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
//return table;
|
||||
}
|
||||
|
||||
//builds linked list with each node holding vehicle is and linked list pointer on the hastable
|
||||
node_info* build_node_info(node_info* headRef, int vid, int *vid_addr){
|
||||
|
||||
node_info* newNode=malloc(sizeof(node_info));
|
||||
newNode->vid=vid;
|
||||
newNode->vid_addr=vid_addr;
|
||||
if (headRef==NULL){
|
||||
headRef=newNode;
|
||||
return headRef;
|
||||
}
|
||||
while(headRef->next!=NULL){
|
||||
headRef = headRef->next;
|
||||
}
|
||||
if (headRef->next==NULL ){
|
||||
headRef->next = newNode;
|
||||
|
||||
}
|
||||
return headRef->next;
|
||||
}
|
||||
|
||||
void AppendNode(struct Exnode* headRef, struct Exnode* newNode) {
|
||||
|
||||
while(headRef->next!=NULL){
|
||||
headRef = headRef->next;
|
||||
}
|
||||
if (headRef->next==NULL ){
|
||||
headRef->next = newNode;
|
||||
}
|
||||
}
|
||||
|
||||
//Just used for testing, it prints a linked list given the head pointer
|
||||
void print_list(struct Exnode* head){
|
||||
|
||||
while(head->next !=NULL)
|
||||
head=head->next;
|
||||
}
|
||||
|
||||
Exnode* get_next_position(omg_hash_table_t *table,int node_id){
|
||||
node_info* head_node=head_node_info;
|
||||
while(head_node->next!=NULL){
|
||||
|
||||
if(head_node->vid==node_id){
|
||||
int *value1 = NULL;
|
||||
value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
|
||||
if (value1!=NULL){
|
||||
Exnode* value2=(Exnode *)value1;
|
||||
while(value2->next!=NULL){
|
||||
if (value2->visit==1) value2=value2->next;
|
||||
else {
|
||||
value2->visit=1;
|
||||
return value2;
|
||||
}
|
||||
}
|
||||
if (value2->visit!=1){
|
||||
value2->visit=1;
|
||||
return value2;
|
||||
}
|
||||
}
|
||||
if ((fp = fopen (trace_file, "r")) == NULL)
|
||||
{
|
||||
LOG_E (OMG, "[OMG]:Cannot open file %s\n", trace_file);
|
||||
exit (1);
|
||||
}
|
||||
head_node=head_node->next;
|
||||
}
|
||||
// not to leave the last node with ->next=NULL
|
||||
if(head_node->vid==node_id){
|
||||
int *value1 = NULL;
|
||||
value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
|
||||
if (value1!=NULL){
|
||||
Exnode* value2=(Exnode *)value1;
|
||||
while(value2->next!=NULL){
|
||||
if (value2->visit==1) value2=value2->next;
|
||||
else {
|
||||
value2->visit=1;
|
||||
return value2;
|
||||
}
|
||||
}
|
||||
if (value2->visit!=1){
|
||||
value2->visit=1;
|
||||
return value2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void reset_visit_status(omg_hash_table_t *table,float time, int node_id){
|
||||
node_info* head_node=head_node_info;
|
||||
while(head_node->next!=NULL){
|
||||
|
||||
if(head_node->vid==node_id){
|
||||
int *value1 = NULL;
|
||||
value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
|
||||
if (value1!=NULL){
|
||||
Exnode* value2=(Exnode *)value1;
|
||||
while(value2->next!=NULL){
|
||||
if (value2->time == time) {
|
||||
value2->visit=0;
|
||||
}
|
||||
value2=value2->next;
|
||||
}
|
||||
if (value2->time == time){
|
||||
value2->visit=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
head_node=head_node->next;
|
||||
}
|
||||
// not to leave the last node with ->next=NULL
|
||||
if(head_node->vid==node_id){
|
||||
int *value1 = NULL;
|
||||
value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
|
||||
if (value1!=NULL){
|
||||
Exnode* value2=(Exnode *)value1;
|
||||
while(value2->next!=NULL){
|
||||
if (value2->time==time) value2->visit=0;
|
||||
value2=value2->next;
|
||||
}
|
||||
if (value2->time==time) value2->visit=0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
while (!feof (fp))
|
||||
{
|
||||
if (fgets (str, 126, fp))
|
||||
{
|
||||
fmt = 0;
|
||||
p = str;
|
||||
|
||||
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);
|
||||
}
|
||||
while (*p == ' ' || *p == '\t' || *p == '\r')
|
||||
p++; // skip whitespaces
|
||||
|
||||
// quick sort list
|
||||
void quicksortlist(Exnode *pLeft, Exnode *pRight){
|
||||
Exnode *pStart;
|
||||
Exnode *pCurrent;
|
||||
double swp_time;
|
||||
int swp_vid;
|
||||
double swp_x;
|
||||
double swp_y;
|
||||
double swp_speed;
|
||||
int swp_visit;
|
||||
|
||||
// If the left and right pointers are the same, then return
|
||||
if (pLeft == pRight) return;
|
||||
|
||||
// Set the Start and the Current item pointers
|
||||
pStart = pLeft;
|
||||
pCurrent = pStart->next;
|
||||
// Loop forever (well until we get to the right)
|
||||
while (1){
|
||||
if (pStart->time > pCurrent->time){
|
||||
// Swap the items,swapping address could be critical, head pointer change will disrupt
|
||||
// so swapping values
|
||||
swp_time = pCurrent->time;
|
||||
swp_vid = pCurrent->vid;
|
||||
swp_x = pCurrent->x;
|
||||
swp_y = pCurrent->y;
|
||||
swp_speed = pCurrent->speed;
|
||||
swp_visit = pCurrent->visit;
|
||||
|
||||
pCurrent->time = pStart->time;
|
||||
pCurrent->vid = pStart->vid;
|
||||
pCurrent->x = pStart->x;
|
||||
pCurrent->y = pStart->y;
|
||||
pCurrent->speed = pStart->speed;
|
||||
pCurrent->visit = pStart->visit;
|
||||
|
||||
pStart->time = swp_time;
|
||||
pStart->vid = swp_vid;
|
||||
pStart->x = swp_x;
|
||||
pStart->y = swp_y;
|
||||
pStart->speed = swp_speed;
|
||||
pStart->visit = swp_visit;
|
||||
}
|
||||
|
||||
// Check if we have reached the end
|
||||
if (pCurrent == pRight) break;
|
||||
|
||||
// Move to the next item in the list
|
||||
pCurrent = pCurrent->next;
|
||||
}
|
||||
quicksortlist(pStart->next,pCurrent);
|
||||
|
||||
}
|
||||
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;
|
||||
|
||||
void clear_llist(){
|
||||
|
||||
node_info* TempNode=NULL;
|
||||
node_info* tmp=NULL;
|
||||
TempNode=head_node_info;
|
||||
|
||||
while(TempNode->next!=NULL){
|
||||
int *value1 = NULL;
|
||||
value1 = (int *) HT_LOOKUP(table, TempNode->vid_addr);
|
||||
Exnode* TempMob = (Exnode *)value1;
|
||||
|
||||
while (TempMob->next!=NULL){
|
||||
Exnode* tmp=NULL;
|
||||
tmp=TempMob;
|
||||
TempMob=TempMob->next;
|
||||
free(tmp);
|
||||
tmp=NULL;
|
||||
}
|
||||
if (TempMob->next == NULL){
|
||||
free(TempMob);
|
||||
TempMob=NULL;
|
||||
}
|
||||
tmp=TempNode;
|
||||
TempNode=TempNode->next;
|
||||
free(tmp);
|
||||
tmp=NULL;
|
||||
}
|
||||
if (TempNode->next==NULL ){
|
||||
free(TempNode);
|
||||
TempNode=NULL;
|
||||
}
|
||||
hash_table_delete(table);
|
||||
}
|
||||
/*
|
||||
while (pch != NULL)
|
||||
{
|
||||
|
||||
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);
|
||||
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, " ");
|
||||
}
|
||||
head_node=head_node->next;
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
//search for node given id if exist
|
||||
|
||||
int
|
||||
find_node_info (int vid, int node_type)
|
||||
{
|
||||
node_info *search;
|
||||
if (list_head[node_type] != NULL)
|
||||
{
|
||||
search = list_head[node_type];
|
||||
while (search != NULL)
|
||||
{
|
||||
if (search->vid == vid)
|
||||
return search->g_id;
|
||||
search = search->next;
|
||||
}
|
||||
int *value1 = NULL;
|
||||
value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
|
||||
Exnode *value=(Exnode *)value1;
|
||||
while(value->next!=NULL){
|
||||
printf("checking reset %d %d\n",value->visit,value->vid);
|
||||
value=value->next;
|
||||
}
|
||||
printf("checking reset %d %d\n",value->visit,value->vid);
|
||||
return 0;
|
||||
}*/
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (list_head[node_type] == NULL)
|
||||
list_head[node_type] = new;
|
||||
else
|
||||
{
|
||||
node_info *temp, *save;
|
||||
temp = list_head[node_type];
|
||||
while (temp != NULL)
|
||||
{
|
||||
save = temp;
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
save->next = new;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E (OMG, "node info list creation failed\n");
|
||||
exit (-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
get_number_of_nodes (int node_type)
|
||||
{
|
||||
return table[node_type]->key_count;
|
||||
}
|
||||
|
||||
node_data *
|
||||
get_next_data (hash_table_t * table, int vid, int flag)
|
||||
{
|
||||
node_container *block = hash_table_lookup (table, vid);
|
||||
node_data *links = NULL, *save = NULL;
|
||||
|
||||
if (block != NULL)
|
||||
links = block->next;
|
||||
|
||||
if (links == NULL)
|
||||
LOG_E (OMG, "ERROR in reading-: NO data for node %d in this block \n",
|
||||
vid);
|
||||
|
||||
while (links != NULL)
|
||||
{
|
||||
if (links->visit == 0)
|
||||
break;
|
||||
save = links;
|
||||
links = links->next;
|
||||
}
|
||||
|
||||
if (links != NULL)
|
||||
{
|
||||
if (flag == DATA_AND_STATUS_CHANGE)
|
||||
{
|
||||
if (block->next != block->end)
|
||||
links->visit = 1;
|
||||
return links;
|
||||
}
|
||||
else if (flag == DATA_ONLY)
|
||||
{
|
||||
return save;
|
||||
}
|
||||
}
|
||||
else
|
||||
return links;
|
||||
}
|
||||
|
||||
@@ -41,62 +41,16 @@
|
||||
#ifndef MOBILITY_PARSER_H_
|
||||
#define MOBILITY_PARSER_H_
|
||||
|
||||
#include "omg_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
|
||||
#include "trace_hashtable.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* function just to initialize the head of the linked list to NULL, this can be removed later(check).
|
||||
*/
|
||||
struct Exnode* gen_list();
|
||||
|
||||
/**
|
||||
* Function to append the line content to build a linked list.
|
||||
* @param headRef is the pointer to the head of the existing list to which append has to be done
|
||||
* @param newNode , item to be appended
|
||||
*/
|
||||
void AppendNode(struct Exnode* headRef, struct Exnode* newNode);
|
||||
|
||||
/**
|
||||
* function just prints the linked list (need to be removed, used for testing)
|
||||
* @param pointer to the head of the linked list
|
||||
*/
|
||||
void print_list(struct Exnode* head);
|
||||
|
||||
/**
|
||||
/*
|
||||
* function reads each line and checks if vehicle has an entry in the hastable,
|
||||
* if so append append is called else a new linked list to the vehicle is created.
|
||||
* @param need mobility file to be given
|
||||
*/
|
||||
|
||||
void read_mobility_file(); // mobility file need to be given here, add in omg_param_list, get it from there
|
||||
void parse_data (char *trace_file, int node_type); // mobility file need to be given here, add in omg_param_list, get it from there
|
||||
|
||||
/**
|
||||
* function builds a linked list which holds vehicle id and its mapping pointer to
|
||||
@@ -105,23 +59,16 @@ void read_mobility_file(); // mobility file need to be given here, add in omg_pa
|
||||
* @param vid is the vehicle id
|
||||
* @param pointer to the head of the linked list to the vehicle entry in the hash table
|
||||
*/
|
||||
node_info* build_node_info(node_info* headRef, int vid, int *vid_addr);
|
||||
void add_node_info (int nid,int n_gid, int node_type);
|
||||
int find_node_info (int vid, int node_type);
|
||||
|
||||
/**
|
||||
* just counts the number of nodes in the mobility file
|
||||
*/
|
||||
int get_num_nodes();
|
||||
int get_number_of_nodes (int node_type);
|
||||
|
||||
|
||||
/**
|
||||
* these function are used since there might be a possibility if user provides a mobility
|
||||
* discription which is out of order.
|
||||
* @param hashtable
|
||||
* @param starting pointer for the vehicles linked list
|
||||
* @param ending pointer of the vehicles linked list
|
||||
*/
|
||||
|
||||
void sort_veh_movement(omg_hash_table_t *table);
|
||||
void quicksortlist(Exnode *pLeft, Exnode *pRight);
|
||||
|
||||
/**
|
||||
* function returns the node containing next position (just reads the linked list from the hashtable)
|
||||
@@ -129,10 +76,8 @@ void quicksortlist(Exnode *pLeft, Exnode *pRight);
|
||||
* @param hashtable from which the node is to be looked
|
||||
* @param node_id is the nodes whose next location need to be retrieved from the linked list
|
||||
*/
|
||||
Exnode* get_next_position(omg_hash_table_t *table,int node_id);
|
||||
node_data* get_next_data (hash_table_t* table, int vid, int flag);
|
||||
|
||||
void reset_visit_status(omg_hash_table_t *table, float time, int node_id);
|
||||
|
||||
void clear_llist();
|
||||
|
||||
#endif /* MOBILITY_PARSER_H_ */
|
||||
|
||||
+839
-643
File diff suppressed because it is too large
Load Diff
@@ -30,7 +30,7 @@
|
||||
/*! \file OMG.h
|
||||
* \brief Prototypes of OMG functions that may be called by OCG
|
||||
* \author M. Mahersi, N. Nikaein, J. Harri
|
||||
* \date 2011
|
||||
* \date 2011 - 2014
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email:
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "omg_constants.h"
|
||||
#include "defs.h"
|
||||
#include "omg_vars.h"
|
||||
|
||||
#if STANDALONE
|
||||
#define LOG_G(c, x...) printf(x)
|
||||
#define LOG_A(c, x...) printf(x)
|
||||
@@ -57,6 +58,8 @@
|
||||
|
||||
#else
|
||||
#include "UTIL/LOG/log.h"
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/** @defgroup _omg OpenAir Mobility Generation (OMG)
|
||||
@@ -195,14 +198,14 @@ void init_omg_global_params(void);
|
||||
* \brief Assign initial positions to all the nodes. To do so, call the start_generator..... function corresponding to each requested mobility generator
|
||||
* \param omg_param_list a structure that contains the main parameters needed to establish the random positions distribution
|
||||
*/
|
||||
void init_mobility_generator(omg_global_param omg_param_list);
|
||||
void init_mobility_generator(omg_global_param omg_param_list[]);
|
||||
|
||||
/**
|
||||
* \fn void stop_mobility_generator(int mobility_type)
|
||||
* \brief Call the destructor for the respective mobility type.
|
||||
* \param int mobility_type to stop and call destructor
|
||||
*/
|
||||
void stop_mobility_generator(int mobility_type);
|
||||
void stop_mobility_generator(omg_global_param* omg_param_list);
|
||||
|
||||
/**
|
||||
* \fn void update_nodes(double cur_time)
|
||||
@@ -220,9 +223,9 @@ void update_nodes(double cur_time);
|
||||
* \param cur_time a variable of type double that represents the current time
|
||||
* \return a Node_list structure that stores the basic information about the all the nodes of a given mobility model
|
||||
*/
|
||||
Node_list get_current_positions(int mobility_type, int node_type, double cur_time);
|
||||
|
||||
node_list* get_current_positions(int mobility_type, int node_type, double cur_time);
|
||||
|
||||
void get_nodes_positions (int mobility_type, double cur_time);
|
||||
|
||||
/**
|
||||
* \fn void set_new_mob_type(int nID, int node_type, int new_mob, double cur_time)
|
||||
|
||||
@@ -45,14 +45,29 @@ RWP, /*!< Random Way Point mobility model */
|
||||
RWALK, /*!< Random Walk mobility model */
|
||||
TRACE, /*!< Trace-based Mobility description file */
|
||||
SUMO, /*!< SUMO-based mobility model */
|
||||
STEADY_RWP, /*!steady state RWP*/
|
||||
MAX_NUM_MOB_TYPES /*!< The maximum number of mobility models. Used to adjust the length of the #Node_Vector */
|
||||
}mobility_types;
|
||||
|
||||
/*
|
||||
* this is a sub type of standard RWP (not steady_RWP)
|
||||
*/
|
||||
typedef enum {
|
||||
MIN_RWP_TYPES=0, /*!< STATIC mobility model */
|
||||
RESTIRICTED_RWP, /*!< Random Way Point mobility model */
|
||||
CONNECTED_DOMAIN, /*!< Random Walk mobility model */
|
||||
MAX_RWP_TYPES /*!< The maximum number of mobility models. Used to adjust the length of the #Node_Vector */
|
||||
}omg_rwp_types;
|
||||
|
||||
//#define RESTIRICTED_RWP 1
|
||||
//#define CONNECTED_DOMAIN 2
|
||||
|
||||
/*! The available nodes types */
|
||||
typedef enum {
|
||||
eNB=0, /*!< enhanced Node B */
|
||||
UE, /*!< User Equipement */
|
||||
ALL /*!< All the types. Used to perform the same operations to all the types of nodes */
|
||||
RELAY,
|
||||
MAX_NUM_NODE_TYPES /*!< All the types. Used to perform the same operations to all the types of nodes */
|
||||
}node_types;
|
||||
|
||||
|
||||
@@ -60,6 +75,11 @@ ALL /*!< All the types. Used to perform the same operations to all the types of
|
||||
/*! A constant used to compare two doubles */
|
||||
#define eps 0.10 //10.99
|
||||
|
||||
#define SLEEP 1
|
||||
#define GET_DATA 0
|
||||
#define GET_DATA_UPDATE 1
|
||||
|
||||
|
||||
#endif /* __OMG_H_ */
|
||||
|
||||
|
||||
|
||||
@@ -39,21 +39,29 @@
|
||||
#include "omg.h"
|
||||
|
||||
/*!A global variable used to store all the nodes information. It is an array in which every cell stocks the nodes information for a given mobility type. Its length is equal to the maximum number of mobility models that can exist in a single simulation scenario */
|
||||
Node_list Node_Vector[MAX_NUM_MOB_TYPES];
|
||||
node_list* node_vector[MAX_NUM_NODE_TYPES];
|
||||
node_list* node_vector_end[MAX_NUM_NODE_TYPES];
|
||||
|
||||
/*! A global variable which represents the length of the Node_Vector */
|
||||
int Node_Vector_len[MAX_NUM_MOB_TYPES];
|
||||
int node_vector_len[MAX_NUM_NODE_TYPES];
|
||||
/*!a global veriable used for event average computation*/
|
||||
int event_sum[100];
|
||||
int events[100];
|
||||
|
||||
/*!A global variable used to store the scheduled jobs, i.e (node, job_time) peers */
|
||||
Job_list Job_Vector;
|
||||
job_list* job_vector[MAX_NUM_MOB_TYPES];
|
||||
job_list* job_vector_end[MAX_NUM_MOB_TYPES];
|
||||
|
||||
/*! A global variable which represents the length of the Job_Vector */
|
||||
int Job_Vector_len;
|
||||
int job_vector_len[MAX_NUM_MOB_TYPES];
|
||||
|
||||
/*! A global variable used gather the fondamental parameters needed to launch a simulation scenario*/
|
||||
omg_global_param omg_param_list;
|
||||
omg_global_param omg_param_list[MAX_NUM_NODE_TYPES];
|
||||
|
||||
//double m_time;
|
||||
|
||||
|
||||
/*!A global variable used to store selected node position generation way*/
|
||||
int grid;
|
||||
double xloc_div;
|
||||
double yloc_div;
|
||||
#endif /* __OMG_VARS_H__ */
|
||||
|
||||
+450
-394
@@ -29,8 +29,8 @@
|
||||
|
||||
/*! \file rwalk.c
|
||||
* \brief random walk mobility generator
|
||||
* \author M. Mahersi, J. Harri, N. Nikaein,
|
||||
* \date 2011
|
||||
* \author S. Gashaw, N. Nikaein, J. Harri, M. Mahersi
|
||||
* \date 2014
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email:
|
||||
@@ -41,422 +41,478 @@
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "rwalk.h"
|
||||
#include "omg.h"
|
||||
#include "steadystaterwp.h"
|
||||
|
||||
|
||||
int start_rwalk_generator(omg_global_param omg_param_list) {
|
||||
|
||||
int n_id=0;
|
||||
//omg_omg_param_list.seed= time(NULL);
|
||||
srand(omg_param_list.seed + RWALK);
|
||||
|
||||
double cur_time = 0.0;
|
||||
NodePtr node = NULL;
|
||||
MobilityPtr mobility = NULL;
|
||||
|
||||
if (omg_param_list.nodes <= 0){
|
||||
LOG_W(OMG, "Number of nodes has not been set\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (omg_param_list.nodes_type == eNB) {
|
||||
LOG_I(OMG, "Node type has been set to eNB\n");
|
||||
} else if (omg_param_list.nodes_type == UE) {
|
||||
LOG_I(OMG, "Node type has been set to UE\n");
|
||||
}
|
||||
LOG_I(OMG, "Number of random walk nodes has been set to %d\n", omg_param_list.nodes);
|
||||
int
|
||||
start_rwalk_generator (omg_global_param omg_param_list)
|
||||
{
|
||||
|
||||
|
||||
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;
|
||||
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 ++;
|
||||
int id;
|
||||
static int n_id = 0;
|
||||
double cur_time = 0.0, pause_p, mean_pause, mean_travel;
|
||||
node_struct *node = NULL;
|
||||
mobility_struct *mobility = NULL;
|
||||
pair_struct *pair = NULL;
|
||||
|
||||
if (Job_Vector == NULL)
|
||||
LOG_E(OMG, "Job Vector is NULL\n");
|
||||
}
|
||||
return(0);
|
||||
srand (omg_param_list.seed + RWALK);
|
||||
|
||||
mean_pause = (omg_param_list.max_sleep - omg_param_list.min_sleep) / 2;
|
||||
mean_travel =
|
||||
(omg_param_list.max_journey_time - omg_param_list.min_journey_time) / 2;
|
||||
pause_p = mean_pause / (mean_travel + mean_pause);
|
||||
|
||||
LOG_I (OMG, "#RWALK mobility model for %d %d nodes\n", omg_param_list.nodes,
|
||||
omg_param_list.nodes_type);
|
||||
|
||||
for (id = n_id; id < (omg_param_list.nodes + n_id); id++)
|
||||
{
|
||||
|
||||
node = create_node ();
|
||||
mobility = create_mobility ();
|
||||
|
||||
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
|
||||
|
||||
pair = (pair_struct *) malloc (sizeof (struct pair_struct));
|
||||
pair->b = node;
|
||||
// sleep_rwalk_node (pair, cur_time); //sleep
|
||||
//pause probability...some of the nodes start at pause & the other on move
|
||||
|
||||
if (randomgen (0, 1) < pause_p)
|
||||
sleep_steadystaterwp_node (pair, cur_time); //sleep
|
||||
else
|
||||
move_steadystaterwp_node (pair, cur_time);
|
||||
|
||||
|
||||
job_vector_end[RWALK] = add_job (pair, job_vector_end[RWALK]);
|
||||
|
||||
if (job_vector[RWALK] == NULL)
|
||||
job_vector[RWALK] = job_vector_end[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);
|
||||
}
|
||||
|
||||
|
||||
void place_rwalk_node(NodePtr node) {
|
||||
void
|
||||
place_rwalk_node (node_struct * node)
|
||||
{
|
||||
node->x_pos =
|
||||
(double) ((int)
|
||||
(randomgen
|
||||
(omg_param_list[node->type].min_x,
|
||||
omg_param_list[node->type].max_x) * 100)) / 100;
|
||||
node->mob->x_from = node->x_pos;
|
||||
node->mob->x_to = node->x_pos;
|
||||
node->y_pos =
|
||||
(double) ((int)
|
||||
(randomgen
|
||||
(omg_param_list[node->type].min_y,
|
||||
omg_param_list[node->type].max_y) * 100)) / 100;
|
||||
node->mob->y_from = node->y_pos;
|
||||
node->mob->y_to = node->y_pos;
|
||||
node->mob->speed = 0.0;
|
||||
node->mob->journey_time = 0.0;
|
||||
|
||||
node->X_pos = (double) ((int) (randomGen(omg_param_list.min_X, omg_param_list.max_X)*100))/ 100;
|
||||
node->mob->X_from = node->X_pos;
|
||||
node->mob->X_to = node->X_pos;
|
||||
node->Y_pos = (double) ((int) (randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100;
|
||||
node->mob->Y_from = node->Y_pos;
|
||||
node->mob->Y_to = node->Y_pos;
|
||||
// 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->mob->speed = 0.0;
|
||||
node->mob->journey_time = 0.0;
|
||||
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]++;
|
||||
|
||||
LOG_D(OMG, " INITIALIZE RWALK NODE\n ");
|
||||
LOG_I(OMG, "Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = 0.0\n", node->ID, node->type, node->X_pos, node->Y_pos);
|
||||
Node_Vector[RWALK] = (Node_list) add_entry(node, Node_Vector[RWALK]);
|
||||
Node_Vector_len[RWALK]++;
|
||||
//Initial_Node_Vector_len[RWALK]++;
|
||||
}
|
||||
|
||||
|
||||
Pair sleep_rwalk_node(NodePtr node, double cur_time){
|
||||
node->mobile = 0;
|
||||
node->mob->speed = 0.0;
|
||||
node->mob->X_from = node->mob->X_to;
|
||||
node->mob->Y_from = node->mob->Y_to;
|
||||
node->X_pos = node->mob->X_to;
|
||||
node->Y_pos = node->mob->Y_to;
|
||||
Pair pair = malloc(sizeof(Pair)) ;
|
||||
void
|
||||
sleep_rwalk_node (pair_struct * pair, double cur_time)
|
||||
{
|
||||
node_struct *node;
|
||||
node = pair->b;
|
||||
node->mobile = 0;
|
||||
node->mob->speed = 0.0;
|
||||
node->mob->x_from = node->mob->x_to;
|
||||
node->mob->y_from = node->mob->y_to;
|
||||
node->x_pos = node->mob->x_to;
|
||||
node->y_pos = node->mob->y_to;
|
||||
if (node->event_num == 0)
|
||||
node->event_num++;
|
||||
|
||||
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->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);
|
||||
|
||||
node->mob->start_journey = cur_time;
|
||||
pair->a = node->mob->start_journey + node->mob->sleep_duration; //when to wake up
|
||||
LOG_D(OMG, "to wake up at time: cur_time + sleep_duration : %.2f\n", pair->a);
|
||||
pair->b = node;
|
||||
|
||||
return pair;
|
||||
}
|
||||
|
||||
Pair move_rwalk_node(NodePtr node, double cur_time) {
|
||||
Pair pair = malloc(sizeof(Pair));
|
||||
LOG_D(OMG, "MOVE RWALK NODE ID: %d\n",node->ID);
|
||||
|
||||
node->X_pos = node->mob->X_to;
|
||||
node->Y_pos = node->mob->Y_to;
|
||||
node->mob->X_from = node->X_pos;
|
||||
node->mob->Y_from = node->Y_pos;
|
||||
node->mobile = 1;
|
||||
double speed_next = randomGen(omg_param_list.min_speed, omg_param_list.max_speed);
|
||||
node->mob->speed = speed_next;
|
||||
LOG_D(OMG, "speed_next: %f\n", speed_next); //m/s
|
||||
|
||||
double azimuth_next = randomGen(omg_param_list.min_azimuth, omg_param_list.max_azimuth);
|
||||
node->mob->azimuth = azimuth_next;
|
||||
LOG_D(OMG, "azimuth_next: %f\n", node->mob->azimuth);
|
||||
|
||||
double journeyTime_next = randomGen(omg_param_list.min_journey_time, omg_param_list.max_journey_time);
|
||||
node->mob->journey_time = journeyTime_next;
|
||||
LOG_D(OMG, "journey_time_next: %f\n", node->mob->journey_time);
|
||||
|
||||
double distance = node->mob->speed * node->mob->journey_time;
|
||||
LOG_D(OMG, "distance = speed * journey_time: %f\n", distance);
|
||||
|
||||
double dX = distance * cos(node->mob->azimuth*M_PI/180);
|
||||
LOG_D(OMG, "dX = distance * cos(azimuth): %f\n", dX);
|
||||
double dY = distance * sin(node->mob->azimuth*M_PI/180);
|
||||
LOG_D(OMG, "dY = distance * sin(azimuth): %f\n", dY);
|
||||
|
||||
LOG_D(OMG, "from: (%.2f, %.2f)\n", node->X_pos, node->Y_pos);
|
||||
double X_next = (double) ((int)((node->X_pos + dX) *100))/ 100;
|
||||
double Y_next = (double) ((int)((node->X_pos + dY) *100))/ 100;
|
||||
LOG_D(OMG, "theoritical_destination: (%f, %f)\n", X_next, Y_next);
|
||||
|
||||
/*if (X_next<param_list.min_X){ // first method
|
||||
node->mob->X_to = param_list.min_X;
|
||||
}
|
||||
else if (X_next>param_list.max_X){
|
||||
node->mob->X_to = param_list.max_X;
|
||||
}
|
||||
else {
|
||||
node->mob->X_to = X_next;
|
||||
}
|
||||
|
||||
if (Y_next<param_list.min_Y){
|
||||
node->mob->Y_to = param_list.min_Y;
|
||||
}
|
||||
else if (Y_next>param_list.max_Y){
|
||||
node->mob->Y_to = param_list.max_Y;
|
||||
}
|
||||
else {
|
||||
node->mob->Y_to = Y_next;
|
||||
}*/
|
||||
if (X_next < omg_param_list.min_X){
|
||||
while (X_next < omg_param_list.min_X){
|
||||
X_next = X_next + omg_param_list.max_X;
|
||||
}
|
||||
node->mob->X_to = X_next;
|
||||
}
|
||||
else if (X_next > omg_param_list.max_X){
|
||||
while (X_next > omg_param_list.max_X){
|
||||
X_next = X_next - omg_param_list.max_X;
|
||||
}
|
||||
node->mob->X_to = X_next;
|
||||
}
|
||||
else {
|
||||
node->mob->X_to = X_next;
|
||||
}
|
||||
|
||||
if (Y_next < omg_param_list.min_Y){
|
||||
while (Y_next < omg_param_list.min_Y){
|
||||
Y_next = Y_next + omg_param_list.max_Y;
|
||||
}
|
||||
node->mob->Y_to = Y_next;
|
||||
}
|
||||
else if (Y_next > omg_param_list.max_Y){
|
||||
while (Y_next > omg_param_list.max_Y){
|
||||
Y_next = Y_next - omg_param_list.max_Y;
|
||||
}
|
||||
node->mob->Y_to = Y_next;
|
||||
}
|
||||
else {
|
||||
node->mob->Y_to = Y_next;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
move_rwalk_node (pair_struct * pair, double cur_time)
|
||||
{
|
||||
double distance, x_next, y_next, journeytime_next;
|
||||
int i = 0;
|
||||
double dx, dy, x_now, y_now;
|
||||
double alpha, distancex, distancey;
|
||||
node_struct *node;
|
||||
node = pair->b;
|
||||
//LOG_D (OMG, "MOVE RWALK NODE ID: %d\n", node->ID);
|
||||
node->mob->x_from = node->mob->x_to;
|
||||
node->mob->y_from = node->mob->y_to;
|
||||
node->x_pos = node->mob->x_to;
|
||||
node->y_pos = node->mob->y_to;
|
||||
node->mobile = 1;
|
||||
|
||||
node->mob->speed =
|
||||
randomgen (omg_param_list[node->type].min_speed,
|
||||
omg_param_list[node->type].max_speed);
|
||||
|
||||
node->mob->azimuth =
|
||||
randomgen (omg_param_list[node->type].min_azimuth,
|
||||
omg_param_list[node->type].max_azimuth);
|
||||
if (node->event_num == 0)
|
||||
{
|
||||
node->mob->journey_time = residualtime (omg_param_list[node->type]);
|
||||
node->event_num++;
|
||||
}
|
||||
else
|
||||
{
|
||||
node->mob->journey_time =
|
||||
randomgen (omg_param_list[node->type].min_journey_time,
|
||||
omg_param_list[node->type].max_journey_time);
|
||||
}
|
||||
distance = node->mob->speed * node->mob->journey_time;
|
||||
|
||||
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 > omg_param_list[node->type].max_x)
|
||||
{
|
||||
distancex =
|
||||
(omg_param_list[node->type].max_x - x_now) / cos (alpha);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
distancex = distance;
|
||||
}
|
||||
|
||||
if (y_next < omg_param_list[node->type].min_y)
|
||||
{
|
||||
distancey =
|
||||
(omg_param_list[node->type].min_y - y_now) / sin (alpha);
|
||||
|
||||
}
|
||||
else if (y_next > omg_param_list[node->type].max_y)
|
||||
{
|
||||
distancey =
|
||||
(omg_param_list[node->type].max_y - y_now) / sin (alpha);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
distancey = distance;
|
||||
}
|
||||
|
||||
|
||||
if ((distancex == distance && distancey == distance))
|
||||
break;
|
||||
|
||||
|
||||
|
||||
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 (distancey < distancex)
|
||||
{
|
||||
|
||||
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
|
||||
x_now = distancey * cos (alpha) + x_now;
|
||||
y_now = distancey * sin (alpha) + y_now;
|
||||
distance = distance - distancey;
|
||||
|
||||
dx = distance * cos (2 * M_PI - alpha);
|
||||
dy = distance * sin (2 * M_PI - alpha);
|
||||
|
||||
x_next = x_now + dx;
|
||||
y_next = y_now + dy;
|
||||
|
||||
alpha = 2 * M_PI - alpha;
|
||||
|
||||
}
|
||||
else if (distancex < distancey)
|
||||
{
|
||||
|
||||
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++;
|
||||
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
double
|
||||
residualtime (omg_global_param omg_param)
|
||||
{
|
||||
double u;
|
||||
u = randomgen (0, 1);
|
||||
if (u <
|
||||
(2 * omg_param.min_sleep /
|
||||
(omg_param.max_journey_time + omg_param.min_journey_time)))
|
||||
return u * (omg_param.max_journey_time + omg_param.min_journey_time) / 2;
|
||||
else
|
||||
return omg_param.max_journey_time -
|
||||
sqrtf ((1 - u) * (pow (omg_param.max_journey_time, 2) -
|
||||
pow (omg_param.min_sleep, 2)));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
update_rwalk_nodes (double cur_time)
|
||||
{
|
||||
int done = 0;
|
||||
job_list *tmp = job_vector[RWALK];
|
||||
node_struct *my_node;
|
||||
while (tmp != NULL && done == 0)
|
||||
{
|
||||
my_node = (node_struct *) tmp->pair->b;
|
||||
|
||||
//case1:time to next event equals to current time
|
||||
if (tmp->pair != NULL
|
||||
&& ((double) tmp->pair->next_event_t >= cur_time - eps)
|
||||
&& ((double) tmp->pair->next_event_t <= cur_time + eps))
|
||||
{
|
||||
if (my_node->mobile == 1)
|
||||
sleep_rwalk_node (tmp->pair, cur_time);
|
||||
else
|
||||
move_rwalk_node (tmp->pair, cur_time);
|
||||
|
||||
}
|
||||
//case2: current time is greater than the time to next event
|
||||
|
||||
else if (tmp->pair != NULL
|
||||
&& (cur_time - eps) > tmp->pair->next_event_t)
|
||||
{
|
||||
|
||||
while (cur_time >= tmp->pair->next_event_t)
|
||||
{
|
||||
if (my_node->mobile == 1)
|
||||
sleep_rwalk_node (tmp->pair, cur_time);
|
||||
else
|
||||
move_rwalk_node (tmp->pair, cur_time);
|
||||
|
||||
}
|
||||
}
|
||||
//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[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)
|
||||
{
|
||||
|
||||
if (tmp->pair->b->mobile == 1 && tmp->pair->next_event_t >= cur_time)
|
||||
{
|
||||
|
||||
len =
|
||||
tmp->pair->b->mob->speed * (cur_time -
|
||||
tmp->pair->b->mob->start_journey);
|
||||
|
||||
dx = len * cos (tmp->pair->b->mob->azimuth * M_PI / 180);
|
||||
dy = len * sin (tmp->pair->b->mob->azimuth * M_PI / 180);
|
||||
|
||||
x_next =
|
||||
(double) ((int) ((tmp->pair->b->mob->x_from + dx) * 100)) / 100;
|
||||
y_next =
|
||||
(double) ((int) ((tmp->pair->b->mob->y_from + dy) * 100)) / 100;
|
||||
|
||||
|
||||
alpha = (tmp->pair->b->mob->azimuth * M_PI / 180); //in radian
|
||||
x_now = tmp->pair->b->mob->x_from;
|
||||
y_now = tmp->pair->b->mob->y_from;
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
||||
if (x_next < omg_param_list[tmp->pair->b->type].min_x)
|
||||
{
|
||||
distancex =
|
||||
(omg_param_list[tmp->pair->b->type].min_x -
|
||||
x_now) / cos (alpha);
|
||||
}
|
||||
else {
|
||||
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 X_now=0.0;
|
||||
double Y_now=0.0;
|
||||
LOG_D(OMG,"--------GET RWALK POSITIONS--------\n");
|
||||
Pair my_pair = Job_Vector->pair;
|
||||
if ( my_pair ==NULL) {
|
||||
LOG_E(OMG, "my_pair ==NULL");
|
||||
}
|
||||
else if ( (my_pair !=NULL) && (cur_time <= my_pair->a ) ){
|
||||
LOG_D(OMG," %.2f <= %.2f \n",cur_time, my_pair->a);
|
||||
Job_list tmp = Job_Vector;
|
||||
while (tmp != NULL){
|
||||
if (tmp->pair->b->generator == RWALK){
|
||||
if (tmp->pair->b->mobile == 0){ //node is sleeping
|
||||
LOG_T(OMG,"node number %d is sleeping at location: (%.2f, %.2f)\n", tmp->pair->b->ID, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
|
||||
LOG_T(OMG,"Nothing to do, node is sleeping\n");
|
||||
}
|
||||
else if (tmp->pair->b->mobile == 1){ //node is moving
|
||||
LOG_T(OMG,"Node_number %d\n", tmp->pair->b->ID);
|
||||
LOG_T(OMG, "destination not yet reached\tfrom (%.2f, %.2f)\tto (%.2f, %.2f)\tspeed %.2f\t(X_pos %.2f\tY_pos %.2f)\n", tmp->pair->b->mob->X_from, tmp->pair->b->mob->Y_from,tmp->pair->b->mob->X_to, tmp->pair->b->mob->Y_to,tmp->pair->b->mob->speed, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
|
||||
|
||||
double len = sqrtf(pow(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to,2)+pow(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to,2));
|
||||
double dx = fabs(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to) / len;
|
||||
|
||||
double dy = fabs(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to) / len;
|
||||
LOG_D(OMG,"len %f\tdx %f\tdy %f\n", len, dx, dy);
|
||||
if (tmp->pair->b->mob->X_from < tmp->pair->b->mob->X_to ){
|
||||
X_now = tmp->pair->b->mob->X_from + (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey) ) );
|
||||
}
|
||||
else{
|
||||
X_now = tmp->pair->b->mob->X_from - (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
|
||||
}
|
||||
|
||||
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)));
|
||||
}
|
||||
|
||||
|
||||
LOG_D(OMG,"X_now %f\tY_now %f\n", X_now, Y_now);
|
||||
|
||||
if (X_now < omg_param_list.min_X){
|
||||
while (X_now < omg_param_list.min_X){
|
||||
X_now = X_now + omg_param_list.max_X;
|
||||
}
|
||||
}
|
||||
else if (X_now > omg_param_list.max_X){
|
||||
while (X_now > omg_param_list.max_X){
|
||||
X_now = X_now - omg_param_list.max_X;
|
||||
}
|
||||
}
|
||||
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 if (x_next > omg_param_list[tmp->pair->b->type].max_x)
|
||||
{
|
||||
distancex =
|
||||
(omg_param_list[tmp->pair->b->type].max_x -
|
||||
x_now) / cos (alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
distancex = len;
|
||||
}
|
||||
|
||||
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 {
|
||||
LOG_E(OMG,"ERROR current time %f > first job_time %f\n", cur_time, my_pair->a);
|
||||
}
|
||||
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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*void update_rwalk_nodes(double cur_time) {// need to implement an out-of-area check as well as a rebound function to stay in the area
|
||||
|
||||
LOG_D(OMG,"--------UPDATE--------\n");
|
||||
int l = 0;
|
||||
|
||||
Job_list tmp = Job_Vector;
|
||||
while (l < Job_Vector_len){
|
||||
LOG_D(OMG,"l == %d \n", l);
|
||||
Pair my_pair = tmp->pair;
|
||||
LOG_D(OMG,"%.2f\n ",my_pair->a);
|
||||
if((my_pair !=NULL) && ( (double)my_pair->a >= cur_time - eps) && ( (double)my_pair->a <= cur_time + eps)) {
|
||||
LOG_D(OMG,"%.2f == %.2f \n ",my_pair->a, cur_time );
|
||||
if (my_pair->b->generator == RWALK) {
|
||||
LOG_D(OMG," UPDATE RWALK \n ");
|
||||
NodePtr my_node= (NodePtr)my_pair->b;
|
||||
//if(my_node->mobile == 1) {
|
||||
// LOG_D(OMG," move again \n" );
|
||||
// // stop node and let it sleep
|
||||
// my_node->mobile = 0;
|
||||
// Pair pair = malloc(sizeof(Pair));
|
||||
// pair = sleep_rwalk_node(my_node, cur_time);
|
||||
// Job_Vector->pair = pair;
|
||||
//}
|
||||
if ((my_node->mobile ==0) ||( my_node->mobile == 1)) {
|
||||
LOG_D(OMG," ...let's move again \n" );
|
||||
// ...let's move again
|
||||
my_node->mobile = 1;
|
||||
Pair pair = malloc(sizeof(Pair));
|
||||
pair = move_rwalk_node(my_node, cur_time);
|
||||
Job_Vector->pair = pair;
|
||||
}
|
||||
else{
|
||||
LOG_E(OMG, "update_generator: unsupported node state - mobile : %d \n", my_node->mobile);
|
||||
}
|
||||
//sorting the new entries
|
||||
LOG_D(OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
|
||||
display_job_list(Job_Vector);
|
||||
Job_Vector = quick_sort (Job_Vector); //////////
|
||||
LOG_D(OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
|
||||
display_job_list(Job_Vector);
|
||||
tmp = tmp->next;
|
||||
l++;
|
||||
}
|
||||
else {
|
||||
LOG_D(OMG, " (first_job_time) %.2f == %.2f(cur_time) but (generator %d) != (RWALK %d)\n ",my_pair->a, cur_time, my_pair->b->generator, RWALK );
|
||||
tmp = tmp->next;
|
||||
l++;
|
||||
}
|
||||
}
|
||||
else if ( (my_pair !=NULL) && (cur_time < my_pair->a ) && (my_pair->b->generator == RWALK) ){
|
||||
LOG_D(OMG," %.2f < %.2f\n ",cur_time, my_pair->a);
|
||||
l = Job_Vector_len;
|
||||
LOG_D(OMG,"Nothing to do\n");
|
||||
}
|
||||
else {
|
||||
l = Job_Vector_len;
|
||||
//LOG_D(OMG,"(generator=%d) != (RWALK=%d)\n", my_pair->b->generator, RWALK );
|
||||
LOG_E(OMG, " %.2f > %.2f \n", cur_time,my_pair->a);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ int start_rwalk_generator(omg_global_param omg_param_list) ;
|
||||
* \brief Called by the function start_rwalk_generator(), it generates a random position ((X,Y) coordinates) for a node and add it to the corresponding Node_Vector_Rwp
|
||||
* \param node a pointer of type NodePtr that represents the node to which the random position is assigned
|
||||
*/
|
||||
void place_rwalk_node(NodePtr node) ;
|
||||
void place_rwalk_node(node_struct* node) ;
|
||||
|
||||
/**
|
||||
* \fn Pair sleep_rwalk_node(NodePtr node, double cur_time)
|
||||
@@ -58,7 +58,7 @@ void place_rwalk_node(NodePtr node) ;
|
||||
* \param cur_time a variable of type double that represents the current time
|
||||
* \return A Pair structure containing the node and the time when it is reaching the destination
|
||||
*/
|
||||
Pair sleep_rwalk_node(NodePtr node, double cur_time) ;
|
||||
void sleep_rwalk_node(pair_struct* pair, double cur_time) ;
|
||||
|
||||
|
||||
/**
|
||||
@@ -68,7 +68,7 @@ Pair sleep_rwalk_node(NodePtr node, double cur_time) ;
|
||||
* \param cur_time a variable of type double that represents the current time
|
||||
* \return A Pair structure containing the node structure and the arrival time at the destination
|
||||
*/
|
||||
Pair move_rwalk_node(NodePtr node, double cur_time) ;
|
||||
void move_rwalk_node(pair_struct* pair, double cur_time) ;
|
||||
|
||||
/**
|
||||
* \fn void update_rwalk_nodes(double cur_time)
|
||||
@@ -87,4 +87,7 @@ void update_rwalk_nodes(double cur_time) ; // need to implement an out-of-area c
|
||||
*/
|
||||
void get_rwalk_positions_updated(double cur_time) ;
|
||||
|
||||
/*for perfect simulation of random walk*/
|
||||
double residualtime(omg_global_param omg_param);
|
||||
|
||||
#endif /* RWALK_H_ */
|
||||
|
||||
+370
-294
@@ -29,7 +29,7 @@
|
||||
|
||||
/*! \file rwp.c
|
||||
* \brief random waypoint mobility generator
|
||||
* \author M. Mahersi, J. Harri, N. Nikaein,
|
||||
* \author M. Mahersi, N. Nikaein, J. Harri
|
||||
* \date 2011
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
@@ -43,329 +43,405 @@
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include "rwp.h"
|
||||
#include "omg.h"
|
||||
|
||||
|
||||
int start_rwp_generator(omg_global_param omg_param_list) {
|
||||
|
||||
int n_id=0;
|
||||
//omg_omg_param_list.seed= time(NULL);
|
||||
srand(omg_param_list.seed + RWP);
|
||||
|
||||
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");
|
||||
int
|
||||
start_rwp_generator (omg_global_param omg_param_list)
|
||||
{
|
||||
static int n_id = 0;
|
||||
int id;
|
||||
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;
|
||||
|
||||
|
||||
|
||||
if (job_vector[RWP] == NULL)
|
||||
LOG_E (OMG, "[RWP] Job Vector is NULL\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
place_rwp_node (node_struct * node)
|
||||
{
|
||||
|
||||
int loc_num;
|
||||
double block_xmin, block_ymin;
|
||||
|
||||
|
||||
if (omg_param_list[node->type].rwp_type == RESTIRICTED_RWP)
|
||||
{
|
||||
loc_num = (int) randomgen (0, omg_param_list[node->type].max_vertices);
|
||||
node->x_pos =
|
||||
(double) vertice_xpos (loc_num, omg_param_list[node->type]);
|
||||
node->y_pos =
|
||||
(double) vertice_ypos (loc_num, omg_param_list[node->type]);
|
||||
//LOG_D(OMG,"location number %d x pos %.2f y pos %.2f \n\n",loc_num,node->x_pos,node->y_pos);
|
||||
}
|
||||
else if (omg_param_list[node->type].rwp_type == CONNECTED_DOMAIN)
|
||||
{
|
||||
node->block_num =
|
||||
(int) randomgen (0, omg_param_list[node->type].max_block_num);
|
||||
block_xmin = area_minx (node->block_num, omg_param_list[node->type]);
|
||||
block_ymin = area_miny (node->block_num, omg_param_list[node->type]);
|
||||
|
||||
node->x_pos =
|
||||
(double) ((int) (randomgen (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]++;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sleep_rwp_node (pair_struct * pair, double cur_time)
|
||||
{
|
||||
node_struct *node;
|
||||
node = pair->b;
|
||||
node->mobile = 0;
|
||||
node->mob->speed = 0.0;
|
||||
node->mob->x_from = node->mob->x_to;
|
||||
node->mob->y_from = node->mob->y_to;
|
||||
node->x_pos = node->mob->x_to;
|
||||
node->y_pos = node->mob->y_to;
|
||||
|
||||
node->mob->sleep_duration =
|
||||
(double) ((int)
|
||||
(randomgen
|
||||
(omg_param_list[node->type].min_sleep,
|
||||
omg_param_list[node->type].max_sleep) * 100)) / 100;
|
||||
/*LOG_D (OMG, "#[RWP] node: %d \tsleep duration : %.2f\n", node->id,
|
||||
node->mob->sleep_duration); */
|
||||
|
||||
node->mob->start_journey = cur_time;
|
||||
pair->next_event_t = cur_time + node->mob->sleep_duration; //when to wake up
|
||||
// LOG_D (OMG, "[RWP] wake up at time: cur_time + sleep_duration : %.2f\n",
|
||||
// pair->a);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
move_rwp_node (pair_struct * pair, double cur_time)
|
||||
{
|
||||
int loc_num;
|
||||
double distance, journeytime_next;
|
||||
double pr, block_xmin, block_ymin;
|
||||
//LOG_D (OMG, "[RWP] move node: %d\n", node->ID);
|
||||
node_struct *node;
|
||||
node = pair->b;
|
||||
node->mob->x_from = node->mob->x_to;
|
||||
node->mob->y_from = node->mob->y_to;
|
||||
node->x_pos = node->mob->x_to;
|
||||
node->y_pos = node->mob->y_to;
|
||||
node->mobile = 1;
|
||||
|
||||
|
||||
if (omg_param_list[node->type].rwp_type == RESTIRICTED_RWP)
|
||||
{
|
||||
do
|
||||
{
|
||||
loc_num =
|
||||
(int) randomgen (0, omg_param_list[node->type].max_vertices);
|
||||
node->mob->x_to =
|
||||
(double) vertice_xpos (loc_num, omg_param_list[node->type]);
|
||||
node->mob->y_to =
|
||||
(double) vertice_ypos (loc_num, omg_param_list[node->type]);
|
||||
|
||||
|
||||
}
|
||||
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 ++;
|
||||
while (node->mob->x_to == node->mob->x_from
|
||||
&& node->mob->y_to == node->mob->y_from);
|
||||
|
||||
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);
|
||||
distance = fabs (node->mob->x_to - node->mob->x_from) +
|
||||
fabs (node->mob->y_to - node->mob->y_from);
|
||||
|
||||
/* LOG_D(OMG,"#location number %d x pos to %.2f y pos to %.2f x pos from %.2f y pos from %.2f\n\n",loc_num,node->mob->x_to,node->mob->y_to,node->mob->x_from,node->mob->y_from); */
|
||||
|
||||
}
|
||||
else if (omg_param_list[node->type].rwp_type == CONNECTED_DOMAIN)
|
||||
{
|
||||
pr = randomgen (0, 1);
|
||||
|
||||
if (pr <= 0.50)
|
||||
/*node->block_num =
|
||||
(int) randomgen (0, omg_param_list[node->type].max_block_num); */
|
||||
node->block_num =
|
||||
(int) next_block (node->block_num, omg_param_list[node->type]);
|
||||
|
||||
block_xmin = area_minx (node->block_num, omg_param_list[node->type]);
|
||||
block_ymin = area_miny (node->block_num, omg_param_list[node->type]);
|
||||
|
||||
node->mob->x_to =
|
||||
(double) ((int) (randomgen (block_xmin, xloc_div + block_xmin) * 100))
|
||||
/ 100;
|
||||
|
||||
node->mob->y_to =
|
||||
(double) ((int) (randomgen (block_ymin, yloc_div + block_ymin) * 100))
|
||||
/ 100;
|
||||
|
||||
distance =
|
||||
(double) ((int) (sqrtf
|
||||
(pow (node->mob->x_from - node->mob->x_to, 2) +
|
||||
pow (node->mob->y_from - node->mob->y_to,
|
||||
2)) * 100)) / 100;
|
||||
|
||||
node->mob->azimuth = atan2 (node->mob->y_to - node->mob->y_from, node->mob->x_to - node->mob->x_from); //radian
|
||||
}
|
||||
else
|
||||
{
|
||||
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 place_rwp_node(NodePtr node) {
|
||||
/*update RWP nodes position*/
|
||||
|
||||
node->X_pos = (double) ((int) (randomGen(omg_param_list.min_X, omg_param_list.max_X)*100))/ 100;
|
||||
node->mob->X_from = node->X_pos;
|
||||
node->mob->X_to = node->X_pos;
|
||||
node->Y_pos = (double) ((int) (randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100;
|
||||
node->mob->Y_from = node->Y_pos;
|
||||
node->mob->Y_to = node->Y_pos;
|
||||
void
|
||||
update_rwp_nodes (double cur_time)
|
||||
{
|
||||
|
||||
node->mob->speed = 0.0;
|
||||
node->mob->journey_time = 0.0;
|
||||
int done = 0;
|
||||
job_list *tmp = job_vector[RWP];
|
||||
node_struct *my_node;
|
||||
while (tmp != NULL && done == 0)
|
||||
{
|
||||
my_node = (node_struct *) tmp->pair->b;
|
||||
|
||||
LOG_I(OMG, "[RWP] Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = 0.0\n ", node->ID, node->type, node->X_pos, node->Y_pos);
|
||||
Node_Vector[RWP] = (Node_list) add_entry(node, Node_Vector[RWP]);
|
||||
Node_Vector_len[RWP]++;
|
||||
//Initial_Node_Vector_len[RWP]++;
|
||||
}
|
||||
//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);
|
||||
|
||||
|
||||
Pair sleep_rwp_node(NodePtr node, double cur_time){
|
||||
node->mobile = 0;
|
||||
node->mob->speed = 0.0;
|
||||
node->mob->X_from = node->mob->X_to;
|
||||
node->mob->Y_from = node->mob->Y_to;
|
||||
node->X_pos = node->mob->X_to;
|
||||
node->Y_pos = node->mob->Y_to;
|
||||
Pair pair = malloc(sizeof(Pair)) ;
|
||||
|
||||
node->mob->sleep_duration = (double) ((int) (randomGen(omg_param_list.min_sleep, omg_param_list.max_sleep)*100))/ 100;
|
||||
LOG_D(OMG, "[RWP] node: %d \tsleep duration : %.2f\n",node->ID, node->mob->sleep_duration);
|
||||
|
||||
node->mob->start_journey = cur_time;
|
||||
pair->a = node->mob->start_journey + node->mob->sleep_duration; //when to wake up
|
||||
LOG_D(OMG, "[RWP] wake up at time: cur_time + sleep_duration : %.2f\n", pair->a);
|
||||
pair->b = node;
|
||||
|
||||
return pair;
|
||||
}
|
||||
|
||||
|
||||
Pair move_rwp_node(NodePtr node, double cur_time) {
|
||||
|
||||
Pair pair = malloc(sizeof(Pair));
|
||||
LOG_D(OMG, "[RWP] move node: %d\n",node->ID );
|
||||
node->mob->X_from = node->X_pos;
|
||||
node->mob->Y_from = node->Y_pos;
|
||||
LOG_D(OMG, "[RWP] Current Position: (%.2f, %.2f)\n", node->mob->X_from, node->mob->Y_from);
|
||||
|
||||
node->mobile = 0;
|
||||
double X_next = (double) ((int)(randomGen(omg_param_list.min_X,omg_param_list.max_X)*100))/ 100;
|
||||
node->mob->X_to = X_next;
|
||||
double Y_next = (double) ((int)(randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100;
|
||||
node->mob->Y_to = Y_next;
|
||||
LOG_D(OMG, "[RWP] destination: (%.2f, %.2f)\n", node->mob->X_to, node->mob->Y_to);
|
||||
|
||||
double speed_next = (double) ((int)(randomGen(omg_param_list.min_speed, omg_param_list.max_speed)*100))/ 100;
|
||||
node->mob->speed = speed_next;
|
||||
LOG_D(OMG, "[RWP] speed_next %.2f\n", speed_next); //m/s
|
||||
double distance = (double) ((int)(sqrtf(pow(node->mob->X_from - X_next, 2) + pow(node->mob->Y_from - Y_next, 2))*100))/ 100;
|
||||
LOG_D(OMG, "[RWP] distance %.2f\n", distance); //m
|
||||
|
||||
double journeyTime_next = (double) ((int)(distance/speed_next*100))/ 100; //duration to get to dest
|
||||
////node->mob->journey_time = journeyTime_next;
|
||||
node->mobile = 1;
|
||||
LOG_D(OMG, "[RWP] mob->journey_time_next %.2f\n",journeyTime_next );
|
||||
|
||||
node->mob->start_journey = cur_time;
|
||||
LOG_D(OMG, "[RWP] start_journey %.2f\n", node->mob->start_journey );
|
||||
pair->a = node->mob->start_journey + journeyTime_next; //when to reach the destination
|
||||
LOG_D(OMG, "[RWP] reaching the destination at time : start journey + journey_time next =%.2f\n", pair->a);
|
||||
|
||||
pair->b = node;
|
||||
return pair;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void update_rwp_nodes(double cur_time) {
|
||||
Job_list tmp = Job_Vector;
|
||||
int done = 0; //
|
||||
while ((tmp != NULL) && (done == 0)){
|
||||
// if (tmp->pair == NULL){LOG_E(OMG, "UPDATE RWP : tmp->pair ==NULL\n" );}
|
||||
// if (tmp->pair != NULL){LOG_E(OMG, "UPDATE RWP : tmp->pair !=NULL\n" );}
|
||||
LOG_D(OMG, "[RWP] cur_time %f reaching the destination at %f\n", cur_time, tmp->pair->a );
|
||||
|
||||
if((tmp->pair !=NULL) && ( (double)tmp->pair->a >= cur_time - eps) && ( (double)tmp->pair->a <= cur_time + eps) ) {
|
||||
if (tmp->pair->b->generator == RWP){
|
||||
LOG_D(OMG, "[RWP](first_job_time) %.2f == %.2f (cur_time) \n ",tmp->pair->a, cur_time );
|
||||
NodePtr my_node = (NodePtr)tmp->pair->b;
|
||||
if(my_node->mobile == 1) {
|
||||
LOG_D(OMG, "[RWP] node %d goes to sleep\n", my_node->ID);
|
||||
my_node->mobile = 0;
|
||||
Pair pair = malloc(sizeof(Pair));
|
||||
pair = sleep_rwp_node(my_node, cur_time);
|
||||
tmp->pair = pair;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
else if (my_node->mobile ==0) {
|
||||
LOG_D(OMG, "[RWP] node %d starts to move again \n", my_node->ID);
|
||||
my_node->mobile = 1;
|
||||
Pair pair = malloc(sizeof(Pair));
|
||||
pair = move_rwp_node(my_node, cur_time);
|
||||
tmp->pair = pair;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
else{
|
||||
LOG_E(OMG,"[RWP] update_generator: unsupported node state - mobile : %d \n", my_node->mobile);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG_D(OMG, "[RWP](first_job_time) %.2f == %.2f(cur_time) but (generator=%d) != (RWP=%d)\n ",tmp->pair->a, cur_time, tmp->pair->b->generator, RWP );
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
else if ( (tmp->pair != NULL) && (cur_time < tmp->pair->a ) ){ //&& (tmp->pair->b->generator == RWP)
|
||||
LOG_D(OMG, "[RWP] Nothing to do as current time %.2f is less than the time to reach the destination %.2f \n",cur_time, tmp->pair->a);
|
||||
done = 1; //quit the loop
|
||||
}
|
||||
else {
|
||||
LOG_E(OMG,"[RWP] current time %.2f is %f greater than the time to reach the destination %.2f\n", cur_time, eps, tmp->pair->a );
|
||||
done = 1; //quit the loop
|
||||
// exit(-1);
|
||||
}
|
||||
}
|
||||
//sorting the new entries
|
||||
LOG_D(OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
|
||||
display_job_list(Job_Vector);
|
||||
Job_Vector = quick_sort (Job_Vector);///////////
|
||||
LOG_D(OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
|
||||
display_job_list(Job_Vector);
|
||||
}
|
||||
|
||||
void get_rwp_positions_updated(double cur_time){
|
||||
|
||||
double X_now=0.0;
|
||||
double Y_now=0.0;
|
||||
LOG_D(OMG, "--------GET RWP POSITIONS--------\n");
|
||||
|
||||
Pair my_pair = Job_Vector->pair;
|
||||
if ( (my_pair !=NULL) && (cur_time <= my_pair->a +eps)){
|
||||
LOG_D(OMG, "[RWP] current time %.2f <= time when reaching the destination %.2f\n ",cur_time, my_pair->a);
|
||||
Job_list tmp = Job_Vector;
|
||||
while (tmp != NULL){
|
||||
if (tmp->pair->b->generator == RWP){
|
||||
if (tmp->pair->b->mobile == 0){ //node is sleeping
|
||||
LOG_D(OMG, "[RWP] node number %d is sleeping at location: (%.2f, %.2f)\n", tmp->pair->b->ID, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
|
||||
}
|
||||
else if (tmp->pair->b->mobile == 1){ //node is moving
|
||||
LOG_D(OMG, "[RWP] destination not yet reached for node %d from (%.2f, %.2f)\tto (%.2f, %.2f)\tspeed %.2f\t(X_pos %.2f\tY_pos %.2f)\n",
|
||||
tmp->pair->b->ID, tmp->pair->b->mob->X_from, tmp->pair->b->mob->Y_from,tmp->pair->b->mob->X_to,
|
||||
tmp->pair->b->mob->Y_to,tmp->pair->b->mob->speed, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
|
||||
|
||||
double len = sqrtf(pow(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to,2)+pow(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to,2));
|
||||
double dx = fabs(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to) / len;
|
||||
|
||||
double dy = fabs(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to) / len;
|
||||
//LOG_D(OMG, "len %f\tdx %f\tdy %f\n", len, dx, dy);
|
||||
if (tmp->pair->b->mob->X_from < tmp->pair->b->mob->X_to ){
|
||||
X_now = tmp->pair->b->mob->X_from + (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey) ) );
|
||||
}
|
||||
else{
|
||||
X_now = tmp->pair->b->mob->X_from - (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
|
||||
}
|
||||
|
||||
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;
|
||||
//tmp->pair->b->mob->X_from = tmp->pair->b->X_pos;
|
||||
//tmp->pair->b->mob->Y_from = tmp->pair->b->Y_pos;
|
||||
//tmp->pair->b->mob->start_journey = cur_time;
|
||||
LOG_D(OMG, "[RWP] Updated_position of node number %d is :(%.2f, %.2f)\n", tmp->pair->b->ID, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
|
||||
}
|
||||
else{
|
||||
LOG_E(OMG, "[RWP] Update_generator: unsupported node state - mobile : %d \n", tmp->pair->b->mobile);
|
||||
return;
|
||||
}
|
||||
}
|
||||
//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;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG_E(OMG, "ERROR (current time) %f > %f (first job_time) \n", cur_time ,my_pair->a );
|
||||
}
|
||||
|
||||
//sorting the new entries
|
||||
//LOG_D (OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
|
||||
// display_job_list (job_vector);
|
||||
job_vector[RWP] = quick_sort (job_vector[RWP]); ///////////
|
||||
// LOG_D (OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
|
||||
//display_job_list (job_vector[RWP]);
|
||||
}
|
||||
|
||||
|
||||
/*void update_rwp_nodes(double cur_time) {
|
||||
LOG_D(OMG, "--------UPDATE--------\n");
|
||||
int l = 0;
|
||||
|
||||
Job_list tmp = Job_Vector;
|
||||
void
|
||||
get_rwp_positions_updated (double cur_time)
|
||||
{
|
||||
|
||||
while (l < Job_Vector_len){
|
||||
LOG_D(OMG, "l == %d \n", l);
|
||||
double x_now = 0.0, y_now = 0.0;
|
||||
double len, dx, dy;
|
||||
job_list *tmp = job_vector[RWP];
|
||||
|
||||
//Pair my_pair = malloc (sizeof(Pair));
|
||||
//my_pair = tmp->pair;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
|
||||
if (tmp->pair == NULL){LOG_E(OMG, "UPDATE RWP : tmp->pair ==NULL\n" );}
|
||||
if (tmp->pair != NULL){LOG_E(OMG, "UPDATE RWP : tmp->pair ==NULL\n" );}
|
||||
if (tmp->pair->b->mobile == 1 && tmp->pair->next_event_t >= cur_time)
|
||||
{
|
||||
|
||||
LOG_D(OMG, "cur_time %f\n", cur_time );
|
||||
LOG_D(OMG, "tmp->pair->a %f\n", tmp->pair->a );
|
||||
if (omg_param_list[tmp->pair->b->type].rwp_type == RESTIRICTED_RWP)
|
||||
{
|
||||
len =
|
||||
tmp->pair->b->mob->speed * (cur_time -
|
||||
tmp->pair->b->mob->start_journey);
|
||||
dx = fabs (tmp->pair->b->mob->x_from - tmp->pair->b->mob->x_to);
|
||||
|
||||
if((tmp->pair !=NULL) && ( (double)tmp->pair->a >= cur_time - eps) && ( (double)tmp->pair->a <= cur_time + eps) ) {
|
||||
if (tmp->pair->b->generator == RWP){
|
||||
LOG_D(OMG, " (first_job_time) %.2f == %.2f (cur_time) \n ",tmp->pair->a, cur_time );
|
||||
LOG_D(OMG, " UPDATE RWP \n ");
|
||||
NodePtr my_node = (NodePtr)tmp->pair->b;
|
||||
if(my_node->mobile == 1) {
|
||||
LOG_D(OMG, " stop node and let it sleep \n" );
|
||||
my_node->mobile = 0;
|
||||
Pair pair = malloc(sizeof(Pair));
|
||||
pair = sleep_rwp_node(my_node, cur_time);
|
||||
tmp->pair = pair;
|
||||
}
|
||||
else if (my_node->mobile ==0) {
|
||||
LOG_D(OMG, " node %d slept enough...let's move again \n", my_node->ID);
|
||||
my_node->mobile = 1;
|
||||
Pair pair = malloc(sizeof(Pair));
|
||||
pair = move_rwp_node(my_node, cur_time);
|
||||
tmp->pair = pair;
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
if (dx < len)
|
||||
{
|
||||
tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
|
||||
tmp->pair->b->y_pos =
|
||||
tmp->pair->b->mob->y_from + (len -
|
||||
dx) *
|
||||
((tmp->pair->b->mob->y_to -
|
||||
tmp->pair->b->mob->y_from) /
|
||||
fabs (tmp->pair->b->mob->y_to -
|
||||
tmp->pair->b->mob->y_from));
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp->pair->b->y_pos = tmp->pair->b->mob->y_from;
|
||||
tmp->pair->b->x_pos = tmp->pair->b->mob->x_from + len *
|
||||
((tmp->pair->b->mob->x_to - tmp->pair->b->mob->x_from)
|
||||
/ fabs (tmp->pair->b->mob->x_to -
|
||||
tmp->pair->b->mob->x_from));
|
||||
}
|
||||
else {
|
||||
LOG_E(OMG, "\n %.2f > %.2f", cur_time,tmp->pair->a ); //LOG_D(OMG, " (generator=%d) != (RWP=%d) \n", tmp->pair->b->generator, RWP );
|
||||
l = Job_Vector_len;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
len =
|
||||
tmp->pair->b->mob->speed * (cur_time -
|
||||
tmp->pair->b->mob->start_journey);
|
||||
|
||||
|
||||
dx = len * cos (tmp->pair->b->mob->azimuth);
|
||||
dy = len * sin (tmp->pair->b->mob->azimuth);
|
||||
|
||||
x_now = tmp->pair->b->mob->x_from + dx;
|
||||
y_now = tmp->pair->b->mob->y_from + dy;
|
||||
|
||||
tmp->pair->b->x_pos = (double) ((int) (x_now * 100)) / 100;
|
||||
tmp->pair->b->y_pos = (double) ((int) (y_now * 100)) / 100;
|
||||
|
||||
|
||||
|
||||
} //grid
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
|
||||
tmp->pair->b->y_pos = tmp->pair->b->mob->y_to;
|
||||
}
|
||||
|
||||
/*if(tmp->pair->b->id==2 && ((int)(cur_time*1000)% 100)==0)
|
||||
LOG_D (OMG, "# %d %.2f %.2f \n\n",tmp->pair->b->id,tmp->pair->b->x_pos,tmp->pair->b->y_pos); */
|
||||
tmp = tmp->next;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#define RWP_H_
|
||||
|
||||
#include "omg.h"
|
||||
|
||||
#include "grid.h"
|
||||
|
||||
/**
|
||||
* \fn void start_rwp_generator(omg_global_param omg_param_list)
|
||||
@@ -51,7 +51,7 @@ int start_rwp_generator(omg_global_param omg_param_list) ;
|
||||
* \brief Called by the function start_rwp_generator(), it generates a random position ((X,Y) coordinates) for a node and add it to the Node_Vector_Rwp
|
||||
* \param node a pointer of type NodePtr that represents the node to which the random position is assigned
|
||||
*/
|
||||
void place_rwp_node(NodePtr node);
|
||||
void place_rwp_node(node_struct* node);
|
||||
|
||||
/**
|
||||
* \fn Pair sleep_rwp_node(NodePtr node, double cur_time)
|
||||
@@ -61,7 +61,7 @@ void place_rwp_node(NodePtr node);
|
||||
* \param cur_time a variable of type double that represents the current time
|
||||
* \return A Pair structure containing the node and the time when it is reaching the destination
|
||||
*/
|
||||
Pair sleep_rwp_node(NodePtr node, double cur_time) ;
|
||||
void sleep_rwp_node(pair_struct* pair, double cur_time) ;
|
||||
|
||||
/**
|
||||
* \fn Pair move_rwp_node(NodePtr node, double cur_time)
|
||||
@@ -71,7 +71,7 @@ Pair sleep_rwp_node(NodePtr node, double cur_time) ;
|
||||
* \param cur_time a variable of type double that represents the current time
|
||||
* \return A Pair structure containing the node structure and the arrival time at the destination
|
||||
*/
|
||||
Pair move_rwp_node(NodePtr node, double cur_time) ;
|
||||
void move_rwp_node(pair_struct* pair, double cur_time);
|
||||
|
||||
/**
|
||||
* \fn void update_rwp_nodes(double cur_time)
|
||||
|
||||
@@ -77,17 +77,17 @@ int connection_(char *, int);
|
||||
void sendExact(int);
|
||||
|
||||
/**
|
||||
* \fn recieveExact();
|
||||
* \fn recieveExact(void);
|
||||
* \brief Pack the data to storage from buf after reading from socket
|
||||
* Returns storage pointer
|
||||
*/
|
||||
storage* receiveExact();
|
||||
storage* receiveExact(void);
|
||||
|
||||
|
||||
/**
|
||||
* \fn close_connection();
|
||||
* \fn close_connection(void);
|
||||
* \brief close socket connection
|
||||
*/
|
||||
void close_connection();
|
||||
void close_connection(void);
|
||||
|
||||
#endif
|
||||
|
||||
+92
-68
@@ -29,11 +29,11 @@
|
||||
|
||||
/*! \file rwalk.c
|
||||
* \brief static mobility generator
|
||||
* \author M. Mahersi, J. Harri, N. Nikaein, Andre Gomes (One source)
|
||||
* \author M. Mahersi, N. Nikaein, J. Harri
|
||||
* \date 2011
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email: openair_tech@eurecom.fr
|
||||
* \email:
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
@@ -41,79 +41,103 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "static.h"
|
||||
|
||||
#include "omg.h"
|
||||
void place_static_node(NodePtr node);
|
||||
|
||||
void start_static_generator(omg_global_param omg_param_list) {
|
||||
|
||||
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++){
|
||||
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;
|
||||
|
||||
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) {
|
||||
if (omg_param_list.fixed_X <= omg_param_list.max_X && omg_param_list.fixed_X >= omg_param_list.min_X)
|
||||
node->X_pos = omg_param_list.fixed_X;
|
||||
else
|
||||
node->X_pos = (double) ((int) (randomGen(omg_param_list.min_X, omg_param_list.max_X)*100))/ 100;
|
||||
node->mob->X_from = node->X_pos;
|
||||
node->mob->X_to = node->X_pos;
|
||||
if (omg_param_list.fixed_Y <= omg_param_list.max_Y && omg_param_list.fixed_Y >= omg_param_list.min_Y)
|
||||
node->Y_pos = omg_param_list.fixed_Y;
|
||||
else
|
||||
node->Y_pos = (double) ((int) (randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100;
|
||||
node->mob->Y_from = node->Y_pos;
|
||||
node->mob->Y_to = node->Y_pos;
|
||||
}
|
||||
else {
|
||||
node->X_pos = (double) ((int) (randomGen(omg_param_list.min_X, omg_param_list.max_X)*100))/ 100;
|
||||
node->mob->X_from = node->X_pos;
|
||||
node->mob->X_to = node->X_pos;
|
||||
node->Y_pos = (double) ((int) (randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100;
|
||||
node->mob->Y_from = node->Y_pos;
|
||||
node->mob->Y_to = node->Y_pos;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
place_static_node (node_struct * node)
|
||||
{
|
||||
if (omg_param_list[node->type].user_fixed && node->type == eNB)
|
||||
{
|
||||
if (omg_param_list[node->type].fixed_x <=
|
||||
omg_param_list[node->type].max_x
|
||||
&& omg_param_list[node->type].fixed_x >=
|
||||
omg_param_list[node->type].min_x)
|
||||
node->x_pos = omg_param_list[node->type].fixed_x;
|
||||
else
|
||||
node->x_pos =
|
||||
(double) ((int)
|
||||
(randomgen
|
||||
(omg_param_list[node->type].min_x,
|
||||
omg_param_list[node->type].max_x) * 100)) / 100;
|
||||
node->mob->x_from = node->x_pos;
|
||||
node->mob->x_to = node->x_pos;
|
||||
if (omg_param_list[node->type].fixed_y <=
|
||||
omg_param_list[node->type].max_y
|
||||
&& omg_param_list[node->type].fixed_y >=
|
||||
omg_param_list[node->type].min_y)
|
||||
node->y_pos = omg_param_list[node->type].fixed_y;
|
||||
else
|
||||
node->y_pos =
|
||||
(double) ((int)
|
||||
(randomgen
|
||||
(omg_param_list[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->journey_time = 0.0;
|
||||
|
||||
LOG_I(OMG, "[STATIC] Initial position of node ID: %d type(UE, eNB): %d (X = %.2f, Y = %.2f) speed = 0.0\n", node->ID, node->type, node->X_pos, node->Y_pos);
|
||||
Node_Vector[STATIC] = (Node_list) add_entry(node, Node_Vector[STATIC]);
|
||||
Node_Vector_len[STATIC]++;
|
||||
//Initial_Node_Vector_len[STATIC]++;
|
||||
|
||||
}
|
||||
|
||||
LOG_I (OMG,
|
||||
"[STATIC] Initial position of node ID: %d type(%d): (X = %.2f, Y = %.2f) speed = 0.0\n",
|
||||
node->id, node->type, node->x_pos, node->y_pos);
|
||||
node_vector_end[node->type] =
|
||||
(node_list *) add_entry (node, node_vector_end[node->type]);
|
||||
|
||||
if (node_vector[node->type] == NULL)
|
||||
node_vector[node->type] = node_vector_end[node->type];
|
||||
|
||||
node_vector_len[node->type]++;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,6 @@ void start_static_generator(omg_global_param omg_param_list);
|
||||
* \brief Generates a random position ((X,Y) coordinates) and assign it to the node passed as argument. This latter node is then added to the Node_Vector[STATIC]
|
||||
* \param node a pointer of type NodePtr that represents the node to which the random position is assigned
|
||||
*/
|
||||
void place_static_node(NodePtr node);
|
||||
void place_static_node(node_struct* node);
|
||||
|
||||
#endif /* STATIC_H_ */
|
||||
|
||||
@@ -0,0 +1,659 @@
|
||||
/*******************************************************************************
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Eurecom OpenAirInterface
|
||||
Copyright(c) 1999 - 2011 Eurecom
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
version 2, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
The full GNU General Public License is included in this distribution in
|
||||
the file called "COPYING".
|
||||
|
||||
Contact Information
|
||||
Openair Admin: openair_admin@eurecom.fr
|
||||
Openair Tech : openair_tech@eurecom.fr
|
||||
Forums : http://forums.eurecom.fsr/openairinterface
|
||||
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
/*! \file steadystaterwp.h
|
||||
* \brief random waypoint mobility generator
|
||||
* \date 2014
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email:
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifndef STEADYSTATERWP_H_
|
||||
#define STEADYSTATERWP_H_
|
||||
|
||||
|
||||
int start_steadystaterwp_generator (omg_global_param omg_param_list);
|
||||
|
||||
void place_steadystaterwp_node (node_struct* node);
|
||||
|
||||
void sleep_steadystaterwp_node (pair_struct* pair, double cur_time);
|
||||
|
||||
void move_steadystaterwp_node (pair_struct* pair, double cur_time);
|
||||
|
||||
double pause_probability(omg_global_param omg_param);
|
||||
|
||||
|
||||
double initial_pause(omg_global_param omg_param);
|
||||
|
||||
double initial_speed(omg_global_param omg_param);
|
||||
|
||||
void update_steadystaterwp_nodes (double cur_time);
|
||||
|
||||
void get_steadystaterwp_positions_updated (double cur_time);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -204,12 +204,12 @@ void writeString(char *s){
|
||||
|
||||
}
|
||||
|
||||
String_list readStringList(String_list vector){
|
||||
string_list* readStringList(string_list* vector){
|
||||
|
||||
int i=0;
|
||||
int len = readInt();
|
||||
descLen = len;
|
||||
String_list entry = NULL;
|
||||
string_list* entry = NULL;
|
||||
|
||||
for (; i < len; i++) {
|
||||
if (vector->string == NULL) {
|
||||
@@ -218,14 +218,14 @@ String_list readStringList(String_list vector){
|
||||
vector->string = tmp;//readString();
|
||||
}
|
||||
else {
|
||||
entry = (String_list)malloc(sizeof(String_list));
|
||||
entry = (string_list*) malloc(sizeof(string_list));
|
||||
char *tmp = readString();
|
||||
//printf("OMG - SUMO ID: %s \n",tmp);
|
||||
entry->string = tmp;//readString();
|
||||
entry->next = NULL;
|
||||
|
||||
if(vector !=NULL) {
|
||||
String_list tmp = vector;
|
||||
string_list* tmp = vector;
|
||||
while (tmp->next != NULL){
|
||||
tmp = tmp->next;
|
||||
}
|
||||
@@ -238,11 +238,11 @@ String_list readStringList(String_list vector){
|
||||
}
|
||||
|
||||
|
||||
void writeStringList(String_list vector){
|
||||
void writeStringList(string_list* vector){
|
||||
|
||||
|
||||
int count=0;
|
||||
String_list tmp = vector;
|
||||
string_list* tmp = vector;
|
||||
// JHNote: a better solution would be to save the pointer to the reference of this Int and replace the value with count at the end....
|
||||
if (tmp->string !=NULL)
|
||||
count++;
|
||||
@@ -463,9 +463,9 @@ void freeStorage(storage * freePtr){
|
||||
freePtr = NULL; // finally, mark as empty list.
|
||||
}
|
||||
|
||||
void reset_String_list(String_list vector) {
|
||||
String_list entry = vector;
|
||||
String_list tmp;
|
||||
void reset_String_list(string_list* vector) {
|
||||
string_list* entry = vector;
|
||||
string_list* tmp;
|
||||
|
||||
while (entry->next != NULL) {
|
||||
tmp = entry;
|
||||
|
||||
@@ -58,7 +58,7 @@ union n{
|
||||
} un ;
|
||||
|
||||
|
||||
void check_endianness();
|
||||
void check_endianness(void);
|
||||
|
||||
//----------------STORAGE------------------------------------
|
||||
struct Storage {
|
||||
@@ -78,36 +78,36 @@ int descLen;
|
||||
|
||||
extern int msgLength;
|
||||
|
||||
void reset();
|
||||
void reset(void);
|
||||
int storageLength(storage *);
|
||||
|
||||
void rearange();
|
||||
unsigned char readChar();
|
||||
void rearange(void);
|
||||
unsigned char readChar(void);
|
||||
void writeChar(unsigned char);
|
||||
|
||||
int readByte() ;
|
||||
int readByte(void) ;
|
||||
void writeByte(int) ;
|
||||
|
||||
|
||||
int readUnsignedByte();
|
||||
int readUnsignedByte(void);
|
||||
void writeUnsignedByte(int);
|
||||
|
||||
char * readString() ;
|
||||
char * readString(void) ;
|
||||
void writeString(char *);
|
||||
|
||||
String_list readStringList(String_list) ;
|
||||
void writeStringList(String_list);
|
||||
string_list* readStringList(string_list*) ;
|
||||
void writeStringList(string_list*);
|
||||
|
||||
int readShort() ;
|
||||
int readShort(void) ;
|
||||
void writeShort(int);
|
||||
|
||||
int readInt() ;
|
||||
int readInt(void) ;
|
||||
void writeInt(int);
|
||||
|
||||
float readFloat() ;
|
||||
float readFloat(void) ;
|
||||
void writeFloat( float );
|
||||
|
||||
double readDouble() ;
|
||||
double readDouble(void) ;
|
||||
void writeDouble( double );
|
||||
|
||||
storage* writePacket(unsigned char*, int);
|
||||
|
||||
+369
-287
@@ -52,361 +52,443 @@
|
||||
#include "client_traci_OMG.h"
|
||||
|
||||
|
||||
int start_sumo_generator(omg_global_param omg_param_list) {
|
||||
int
|
||||
start_sumo_generator (omg_global_param omg_param_list)
|
||||
{
|
||||
|
||||
char sumo_line[300];
|
||||
int n_id;
|
||||
static int id = 0;
|
||||
|
||||
// sprintf(sumo_line, "%s -c %s -b %d -e %d --remote-port %d --step-length %d -v ",omg_param_list.sumo_command, omg_param_list.sumo_config, omg_param_list.sumo_start, omg_param_list.sumo_end, omg_param_list.sumo_port, omg_param_list.sumo_step);
|
||||
|
||||
sprintf(sumo_line, "%s -c %s ",omg_param_list.sumo_command, omg_param_list.sumo_config);
|
||||
sprintf (sumo_line, "%s -c %s ", omg_param_list.sumo_command,
|
||||
omg_param_list.sumo_config);
|
||||
|
||||
printf ("%s\n", sumo_line);
|
||||
|
||||
if ((pid = fork ()) == 0)
|
||||
{
|
||||
// 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
|
||||
|
||||
|
||||
// Talk to SUMO
|
||||
|
||||
targetTime = 1;
|
||||
|
||||
departed = NULL;
|
||||
|
||||
departed = NULL;
|
||||
arrived = NULL;
|
||||
|
||||
// switch on error to return to OAI
|
||||
handshake(omg_param_list.sumo_host,omg_param_list.sumo_port);
|
||||
|
||||
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
|
||||
handshake (omg_param_list.sumo_host, omg_param_list.sumo_port);
|
||||
|
||||
// printf("received Number of nodes %d\n", max_node_SUMO);
|
||||
init (omg_param_list.sumo_end - omg_param_list.sumo_start);
|
||||
|
||||
int max_node_SUMO = 100; //commandGetMaxSUMONodesVariable(); TODO method not implemented in TraCI server..must find another solution
|
||||
|
||||
// printf("received Number of nodes %d\n", max_node_SUMO);
|
||||
|
||||
// create the OAI/SUMO ID manager
|
||||
id_manager = create_IDManager();
|
||||
id_manager = create_IDManager ();
|
||||
|
||||
NodePtr node = NULL;
|
||||
MobilityPtr mobility = NULL;
|
||||
|
||||
active_nodes = NULL; // container to return a subset of only ACTIVE OAI nodes in SUMO
|
||||
node_struct *node = NULL;
|
||||
mobility_struct *mobility = NULL;
|
||||
|
||||
active_nodes = NULL; // container to return a subset of only ACTIVE OAI nodes in SUMO
|
||||
|
||||
last_update_time = 0.0;
|
||||
|
||||
// just check for faulty values
|
||||
if (omg_param_list.nodes <= 0){
|
||||
#ifdef STANDALONE
|
||||
printf("Number of nodes has not been set\n");
|
||||
#else
|
||||
LOG_W(OMG, "Number of nodes has not been set\n");
|
||||
#endif
|
||||
return(-1);
|
||||
}
|
||||
#ifdef STANDALONE
|
||||
printf("Number of OAI-equipped nodes in SUMO has been set to %d\n", omg_param_list.nodes);
|
||||
printf("Number of SUMO simulated nodes has been set to %d\n", max_node_SUMO);
|
||||
#else
|
||||
LOG_I(OMG, "Number of OAI-equipped nodes in SUMO has been set to %d\n", omg_param_list.nodes);
|
||||
LOG_I(OMG, "Number of SUMO simulated nodes has been set to %d\n", max_node_SUMO);
|
||||
#endif
|
||||
if (omg_param_list.nodes <= 0)
|
||||
{
|
||||
#ifdef STANDALONE
|
||||
printf ("Number of nodes has not been set\n");
|
||||
#else
|
||||
LOG_W (OMG, "Number of nodes has not been set\n");
|
||||
#endif
|
||||
return (-1);
|
||||
}
|
||||
#ifdef STANDALONE
|
||||
printf ("Number of OAI-equipped nodes in SUMO has been set to %d\n",
|
||||
omg_param_list.nodes);
|
||||
printf ("Number of SUMO simulated nodes has been set to %d\n",
|
||||
max_node_SUMO);
|
||||
#else
|
||||
LOG_I (OMG, "Number of OAI-equipped nodes in SUMO has been set to %d\n",
|
||||
omg_param_list.nodes);
|
||||
LOG_I (OMG, "Number of SUMO simulated nodes has been set to %d\n",
|
||||
max_node_SUMO);
|
||||
#endif
|
||||
// check and match number of nodes in mobility file provided
|
||||
if (omg_param_list.nodes > max_node_SUMO){
|
||||
#ifdef STANDALONE
|
||||
printf("Not all OAI nodes will be moving according to SUMO.\n");
|
||||
#else
|
||||
LOG_I(OMG, "Not all OAI nodes will be moving according to SUMO.\n");
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
#ifdef STANDALONE
|
||||
printf("OAI nodes will be mapped to a subset of SUMO nodes\n");
|
||||
#else
|
||||
LOG_I(OMG, "OAI nodes will be mapped to a subset of SUMO nodes\n");
|
||||
#endif
|
||||
}
|
||||
if (omg_param_list.nodes > max_node_SUMO)
|
||||
{
|
||||
#ifdef STANDALONE
|
||||
printf ("Not all OAI nodes will be moving according to SUMO.\n");
|
||||
#else
|
||||
LOG_I (OMG, "Not all OAI nodes will be moving according to SUMO.\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef STANDALONE
|
||||
printf ("OAI nodes will be mapped to a subset of SUMO nodes\n");
|
||||
#else
|
||||
LOG_I (OMG, "OAI nodes will be mapped to a subset of SUMO nodes\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (omg_param_list.nodes_type == eNB) {
|
||||
#ifdef STANDALONE
|
||||
printf("Node type has been set to eNB\n");
|
||||
#else
|
||||
LOG_I(OMG, "Node type has been set to eNB\n");
|
||||
#endif
|
||||
}
|
||||
else if (omg_param_list.nodes_type == UE) {
|
||||
|
||||
#ifdef STANDALONE
|
||||
printf("Node type has been set to UE\n");
|
||||
#else
|
||||
LOG_I(OMG, "Node type has been set to UE\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
int n_id = 0;
|
||||
for ( n_id = 0; n_id< omg_param_list.nodes; n_id++) {
|
||||
|
||||
node = (NodePtr) create_node();
|
||||
mobility = (MobilityPtr) create_mobility();
|
||||
node->mobile = 0; // 0 means inactive in SUMO; 1 means active in SUMO; as long as a mapping between OAI-SUMO has not been created, nodes are inactive and do not move
|
||||
node->ID = n_id; // this is OAI ID, not SUMO
|
||||
node->type = omg_param_list.nodes_type; // UE eNB...
|
||||
node->generator = omg_param_list.mobility_type; // SUMO
|
||||
node->mob = mobility;
|
||||
if (omg_param_list.nodes_type == eNB)
|
||||
{
|
||||
#ifdef STANDALONE
|
||||
printf ("Node type has been set to eNB\n");
|
||||
#else
|
||||
LOG_I (OMG, "Node type has been set to eNB\n");
|
||||
#endif
|
||||
}
|
||||
else if (omg_param_list.nodes_type == UE)
|
||||
{
|
||||
|
||||
Node_Vector[SUMO] = (Node_list) add_entry(node, Node_Vector[SUMO]);
|
||||
}
|
||||
|
||||
update_IDs(); // update the mapping between departed and arrived nodes in SUMO.
|
||||
#ifdef STANDALONE
|
||||
printf ("Node type has been set to UE\n");
|
||||
#else
|
||||
LOG_I (OMG, "Node type has been set to UE\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
return(0);
|
||||
for (n_id = id; n_id < omg_param_list.nodes + id; n_id++)
|
||||
{
|
||||
|
||||
node = create_node ();
|
||||
mobility = create_mobility ();
|
||||
node->mobile = 0; // 0 means inactive in SUMO; 1 means active in SUMO; as long as a mapping between OAI-SUMO has not been created, nodes are inactive and do not move
|
||||
node->id = n_id; // this is OAI ID, not SUMO
|
||||
node->type = omg_param_list.nodes_type; // UE eNB...
|
||||
node->generator = SUMO; // SUMO
|
||||
node->mob = mobility;
|
||||
|
||||
node_vector_end[SUMO] =
|
||||
(node_list *) add_entry (node, node_vector_end[SUMO]);
|
||||
|
||||
if (node_vector[SUMO] == NULL)
|
||||
node_vector[SUMO] = node_vector_end[SUMO];
|
||||
}
|
||||
|
||||
id += omg_param_list.nodes;
|
||||
|
||||
update_IDs (); // update the mapping between departed and arrived nodes in SUMO.
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void update_IDs() {
|
||||
#ifdef STANDALONE
|
||||
printf("Updating the ID mapping between SUMO and OAI\n");
|
||||
#else
|
||||
LOG_D(OMG, "Updating the ID mapping between SUMO and OAI\n");
|
||||
#endif
|
||||
String_list tmp_arrived, tmp_departed;
|
||||
|
||||
if(arrived == NULL) {
|
||||
printf("arrived vehicles is NULL \n");
|
||||
return;
|
||||
}
|
||||
void
|
||||
update_IDs (void)
|
||||
{
|
||||
#ifdef STANDALONE
|
||||
printf ("Updating the ID mapping between SUMO and OAI\n");
|
||||
#else
|
||||
LOG_D (OMG, "Updating the ID mapping between SUMO and OAI\n");
|
||||
#endif
|
||||
string_list *tmp_arrived, *tmp_departed;
|
||||
|
||||
if (arrived == NULL)
|
||||
{
|
||||
printf ("arrived vehicles is NULL \n");
|
||||
return;
|
||||
}
|
||||
|
||||
tmp_arrived = arrived;
|
||||
tmp_departed = departed;
|
||||
|
||||
if(departed == NULL) {
|
||||
printf("departed vehicles is NULL \n");
|
||||
return;
|
||||
}
|
||||
if (departed == NULL)
|
||||
{
|
||||
printf ("departed vehicles is NULL \n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(tmp_departed->string !=NULL) {
|
||||
char * tmp_string = malloc(sizeof(strlen(tmp_departed->string)));
|
||||
strcpy(tmp_string, tmp_departed->string);
|
||||
//printf("OMG - 2 head is not null and value is: %s\n",tmp_string);
|
||||
int OAI_ID = get_oaiID_by_SUMO(tmp_string, id_manager);
|
||||
if (OAI_ID ==-1) {
|
||||
if (!activate_and_map(tmp_string)) {
|
||||
// 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) {
|
||||
// printf("OMG - 2 main is not null \n");
|
||||
//char tmp_string [strlen(tmp_departed->string)];
|
||||
char * tmp_string = malloc(sizeof(strlen(tmp_departed->string)));
|
||||
strcpy(tmp_string, tmp_departed->string);
|
||||
//char *tmp_string = tmp_departed->string;
|
||||
int OAI_ID = get_oaiID_by_SUMO(tmp_string, id_manager);
|
||||
if (OAI_ID ==-1) {
|
||||
if (!activate_and_map(tmp_string)) {
|
||||
//printf("Reached the Maximum of OAI nodes to be mapped to SUMO\n");
|
||||
//LOG_I(OMG, "Reached the Maximum of OAI nodes to be mapped to SUMO\n");
|
||||
return; // stopping mapping as the maximum of OAI nodes has been reached;
|
||||
}
|
||||
}
|
||||
tmp_departed = tmp_departed->next;
|
||||
}
|
||||
if (tmp_departed->string != NULL)
|
||||
{
|
||||
char *tmp_string = malloc (sizeof (strlen (tmp_departed->string)));
|
||||
strcpy (tmp_string, tmp_departed->string);
|
||||
//printf("OMG - 2 head is not null and value is: %s\n",tmp_string);
|
||||
int OAI_ID = get_oaiID_by_SUMO (tmp_string, id_manager);
|
||||
if (OAI_ID == -1)
|
||||
{
|
||||
if (!activate_and_map (tmp_string))
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
departed = clear_String_list(departed);
|
||||
}
|
||||
}
|
||||
while (tmp_departed->next != NULL)
|
||||
{
|
||||
// printf("OMG - 2 main is not null \n");
|
||||
//char tmp_string [strlen(tmp_departed->string)];
|
||||
char *tmp_string = malloc (sizeof (strlen (tmp_departed->string)));
|
||||
strcpy (tmp_string, tmp_departed->string);
|
||||
//char *tmp_string = tmp_departed->string;
|
||||
int OAI_ID = get_oaiID_by_SUMO (tmp_string, id_manager);
|
||||
if (OAI_ID == -1)
|
||||
{
|
||||
if (!activate_and_map (tmp_string))
|
||||
{
|
||||
//printf("Reached the Maximum of OAI nodes to be mapped to SUMO\n");
|
||||
//LOG_I(OMG, "Reached the Maximum of OAI nodes to be mapped to SUMO\n");
|
||||
return; // stopping mapping as the maximum of OAI nodes has been reached;
|
||||
}
|
||||
}
|
||||
tmp_departed = tmp_departed->next;
|
||||
}
|
||||
|
||||
departed = clear_string_list (departed);
|
||||
|
||||
if (tmp_arrived->string != NULL)
|
||||
{
|
||||
char *tmp_string = tmp_arrived->string;
|
||||
//printf("OMG - 3 head is not null and value is: %s\n",tmp_arrived->string);
|
||||
|
||||
if (!desactivate_and_unmap (tmp_string))
|
||||
{
|
||||
printf ("Could not locate the OAI node ID %s \n", tmp_string);
|
||||
//LOG_I(OMG, "Could not locate the OAI node ID %s \n", tmp_string);
|
||||
}
|
||||
|
||||
if(tmp_arrived->string !=NULL) {
|
||||
char *tmp_string = tmp_arrived->string;
|
||||
//printf("OMG - 3 head is not null and value is: %s\n",tmp_arrived->string);
|
||||
|
||||
if(!desactivate_and_unmap(tmp_string)) {
|
||||
printf("Could not locate the OAI node ID %s \n", tmp_string);
|
||||
//LOG_I(OMG, "Could not locate the OAI node ID %s \n", tmp_string);
|
||||
}
|
||||
|
||||
}
|
||||
while (tmp_arrived->next != NULL) {
|
||||
char *tmp_string = tmp_arrived->string;
|
||||
if(!desactivate_and_unmap(tmp_string)) {
|
||||
printf("Could not locate the OAI node\n");
|
||||
// LOG_I(OMG, "Could not locate the OAI node\n");
|
||||
while (tmp_arrived->next != NULL)
|
||||
{
|
||||
char *tmp_string = tmp_arrived->string;
|
||||
if (!desactivate_and_unmap (tmp_string))
|
||||
{
|
||||
printf ("Could not locate the OAI node\n");
|
||||
// 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) {
|
||||
#ifdef STANDALONE
|
||||
printf("desactivating node %s \n",sumo_id);
|
||||
#else
|
||||
LOG_I(OMG, "desactivating node %s \n",sumo_id);
|
||||
#endif
|
||||
int OAI_ID = get_oaiID_by_SUMO(sumo_id, id_manager);
|
||||
remove_oaiID_by_SUMO(sumo_id, id_manager);
|
||||
if (OAI_ID !=-1) {
|
||||
bool
|
||||
desactivate_and_unmap (char *sumo_id)
|
||||
{
|
||||
#ifdef STANDALONE
|
||||
printf ("desactivating node %s \n", sumo_id);
|
||||
#else
|
||||
LOG_I (OMG, "desactivating node %s \n", sumo_id);
|
||||
#endif
|
||||
int OAI_ID = get_oaiID_by_SUMO (sumo_id, id_manager);
|
||||
remove_oaiID_by_SUMO (sumo_id, id_manager);
|
||||
if (OAI_ID != -1)
|
||||
{
|
||||
//TODO generalize to UE and eNB (must change the method)
|
||||
NodePtr node = find_node(Node_Vector[SUMO], OAI_ID, UE);
|
||||
if (node == NULL)
|
||||
node = find_node(Node_Vector[SUMO], OAI_ID, eNB);
|
||||
node_struct *node = find_node (node_vector[SUMO], OAI_ID, UE);
|
||||
if (node == NULL)
|
||||
node = find_node (node_vector[SUMO], OAI_ID, eNB);
|
||||
|
||||
if(node !=NULL) {
|
||||
node->mobile = 0; // this node is now inactive;
|
||||
active_nodes = remove_node_entry(node, active_nodes);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
if (node != NULL)
|
||||
{
|
||||
node->mobile = 0; // this node is now inactive;
|
||||
active_nodes = remove_node_entry (node, active_nodes);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef STANDALONE
|
||||
printf("Could not desactive an OAI node, as the SUMO-OAI mapping could not be found for the SUMO node ID %s \n", sumo_id);
|
||||
#else
|
||||
LOG_I(OMG, "Could not desactive an OAI node, as the SUMO-OAI mapping could not be found for the SUMO node ID %s \n", sumo_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
return false;
|
||||
#ifdef STANDALONE
|
||||
printf
|
||||
("Could not desactive an OAI node, as the SUMO-OAI mapping could not be found for the SUMO node ID %s \n",
|
||||
sumo_id);
|
||||
#else
|
||||
LOG_I (OMG,
|
||||
"Could not desactive an OAI node, as the SUMO-OAI mapping could not be found for the SUMO node ID %s \n",
|
||||
sumo_id);
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool activate_and_map(char *sumo_id) {
|
||||
MapPtr map = create_map();
|
||||
#ifdef STANDALONE
|
||||
printf("activating node %s \n",sumo_id);
|
||||
#else
|
||||
LOG_I(OMG, "activating node %s \n",sumo_id);
|
||||
#endif
|
||||
// TODO: So far, only UE can be SUMO mobile, but could change
|
||||
NodePtr active_node = get_first_inactive_OAI_node(Node_Vector[SUMO], UE);
|
||||
if(active_node != NULL) { // found an inactive OAI node; will be mapped to SUMO
|
||||
active_node->mobile = 1; // now node is active in SUMO
|
||||
bool
|
||||
activate_and_map (char *sumo_id)
|
||||
{
|
||||
MapPtr map = create_map ();
|
||||
#ifdef STANDALONE
|
||||
printf ("activating node %s \n", sumo_id);
|
||||
#else
|
||||
LOG_I (OMG, "activating node %s \n", sumo_id);
|
||||
#endif
|
||||
// TODO: So far, only UE can be SUMO mobile, but could change
|
||||
node_struct *active_node =
|
||||
get_first_inactive_OAI_node (node_vector[SUMO], UE);
|
||||
if (active_node != NULL)
|
||||
{ // found an inactive OAI node; will be mapped to SUMO
|
||||
active_node->mobile = 1; // now node is active in SUMO
|
||||
|
||||
active_nodes = add_entry(active_node, active_nodes);
|
||||
|
||||
map->oai_id = active_node->ID;
|
||||
map->sumo_id = malloc(sizeof((int)strlen(sumo_id)));
|
||||
strcpy(map->sumo_id, sumo_id);
|
||||
|
||||
#ifdef STANDALONE
|
||||
printf("added a mapping between oai ID: %d and SUMO ID: %s \n",map->oai_id, map->sumo_id);
|
||||
#else
|
||||
LOG_I(OMG, "added a mapping between oai ID: %d and SUMO ID: %s \n",map->oai_id, map->sumo_id);
|
||||
#endif
|
||||
|
||||
// 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
|
||||
active_nodes = add_entry (active_node, active_nodes);
|
||||
|
||||
return true;
|
||||
map->oai_id = active_node->id;
|
||||
map->sumo_id = malloc (sizeof ((int) strlen (sumo_id)));
|
||||
strcpy (map->sumo_id, sumo_id);
|
||||
|
||||
}
|
||||
#ifdef STANDALONE
|
||||
printf ("added a mapping between oai ID: %d and SUMO ID: %s \n",
|
||||
map->oai_id, map->sumo_id);
|
||||
#else
|
||||
LOG_I (OMG, "added a mapping between oai ID: %d and SUMO ID: %s \n",
|
||||
map->oai_id, map->sumo_id);
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
last_update_time = cur_time; // keeps track of the last update time to get the update interval
|
||||
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;
|
||||
}
|
||||
|
||||
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(cur_time);// Advance the SUMO simulation by cur_time units
|
||||
|
||||
LOG_I(OMG, "--------Updated SUMO positions by %f [ms]--------\n",cur_time);
|
||||
update_IDs(); // both are in the traCI client
|
||||
|
||||
|
||||
commandSimulationStep (cur_time); // Advance the SUMO simulation by cur_time units
|
||||
|
||||
LOG_I (OMG, "--------Updated SUMO positions by %f [ms]--------\n",
|
||||
cur_time);
|
||||
update_IDs (); // both are in the traCI client
|
||||
|
||||
|
||||
}
|
||||
|
||||
void update_sumo_positions(NodePtr node){
|
||||
void
|
||||
update_sumo_positions (node_struct * node)
|
||||
{
|
||||
|
||||
|
||||
|
||||
#ifdef STANDALONE
|
||||
printf("--------GET SUMO Mobility for a single node--------\n");
|
||||
#else
|
||||
LOG_D(OMG, "--------GET SUMO Mobility for a single node--------\n");
|
||||
#endif
|
||||
|
||||
Map_list tmp = id_manager->map_oai2sumo;
|
||||
char *sumo_id = get_sumo_entry(node->ID, tmp);
|
||||
|
||||
if(sumo_id !=NULL) {
|
||||
//printf(" OAI ID is: %d and SUMO ID is %s \n",node->ID, sumo_id);
|
||||
GetPosition(node, sumo_id);
|
||||
GetSpeed(node, sumo_id);
|
||||
}
|
||||
}
|
||||
|
||||
Node_list get_sumo_positions_updated(double cur_time) {
|
||||
|
||||
|
||||
#ifdef STANDALONE
|
||||
printf("--------GET SUMO Mobility for a group of ACTIVE OAI nodes--------\n");
|
||||
#else
|
||||
LOG_I(OMG, "--------GET SUMO Mobility for a group of ACTIVE OAI nodes--------\n");
|
||||
#endif
|
||||
|
||||
if (Node_Vector[SUMO] != NULL){
|
||||
Node_list tmp = Node_Vector[SUMO];
|
||||
while (tmp != NULL){
|
||||
if ((tmp->node->generator == SUMO) && (tmp->node->mobile == 1)) { // OAI node MUST be active
|
||||
LOG_I(OMG, "found an active node with id %d \n", tmp->node->ID);
|
||||
LOG_I(OMG, "Old Positions \n");
|
||||
//printf("Old Positions \n");
|
||||
display_node_position(tmp->node->ID, tmp->node->generator, tmp->node->type ,tmp->node->mobile, tmp->node->X_pos, tmp->node->Y_pos );
|
||||
|
||||
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;
|
||||
#ifdef STANDALONE
|
||||
printf ("--------GET SUMO Mobility for a single node--------\n");
|
||||
#else
|
||||
LOG_D (OMG, "--------GET SUMO Mobility for a single node--------\n");
|
||||
#endif
|
||||
|
||||
Map_list tmp = id_manager->map_oai2sumo;
|
||||
char *sumo_id = get_sumo_entry (node->id, tmp);
|
||||
|
||||
if (sumo_id != NULL)
|
||||
{
|
||||
//printf(" OAI ID is: %d and SUMO ID is %s \n",node->ID, sumo_id);
|
||||
GetPosition (node, sumo_id);
|
||||
GetSpeed (node, sumo_id);
|
||||
}
|
||||
}
|
||||
|
||||
node_list *
|
||||
get_sumo_positions_updated (double cur_time)
|
||||
{
|
||||
|
||||
|
||||
#ifdef STANDALONE
|
||||
printf
|
||||
("--------GET SUMO Mobility for a group of ACTIVE OAI nodes--------\n");
|
||||
#else
|
||||
LOG_I (OMG,
|
||||
"--------GET SUMO Mobility for a group of ACTIVE OAI nodes--------\n");
|
||||
#endif
|
||||
|
||||
if (node_vector[SUMO] != NULL)
|
||||
{
|
||||
node_list *tmp = node_vector[SUMO];
|
||||
while (tmp != NULL)
|
||||
{
|
||||
if ((tmp->node->generator == SUMO) && (tmp->node->mobile == 1))
|
||||
{ // OAI node MUST be active
|
||||
LOG_I (OMG, "found an active node with id %d \n",
|
||||
tmp->node->id);
|
||||
LOG_I (OMG, "Old Positions \n");
|
||||
//printf("Old Positions \n");
|
||||
display_node_position (tmp->node->id, tmp->node->generator,
|
||||
tmp->node->type, tmp->node->mobile,
|
||||
tmp->node->x_pos, tmp->node->y_pos);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
NodePtr get_first_inactive_OAI_node(Node_list list, int node_type) {
|
||||
Node_list current;
|
||||
node_struct *
|
||||
get_first_inactive_OAI_node (node_list * list, int node_type)
|
||||
{
|
||||
node_list *current;
|
||||
|
||||
if (list !=NULL) { //start search
|
||||
current = list;
|
||||
while (current->next != NULL) {
|
||||
if((current->node->mobile == 0) && (current->node->type == node_type)) {
|
||||
return current->node;
|
||||
}
|
||||
current = current->next;
|
||||
if (list != NULL)
|
||||
{ //start search
|
||||
current = list;
|
||||
while (current->next != NULL)
|
||||
{
|
||||
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() {
|
||||
#ifdef STANDALONE
|
||||
printf(" --------Destructor for SUMO: closing the TraCI socket and killing SUMO ---- \n");
|
||||
#else
|
||||
LOG_I(OMG, " --------Destructor for SUMO: closing the TraCI socket and killing SUMO ---- \n");
|
||||
#endif
|
||||
commandClose(); // closing the connection with SUMO via TraCI
|
||||
close_connection(); // closing the socket connection
|
||||
kill(pid,SIGKILL); // killing SUMO in case it could not close by itself
|
||||
bool
|
||||
stop_sumo_generator (void)
|
||||
{
|
||||
#ifdef STANDALONE
|
||||
printf
|
||||
(" --------Destructor for SUMO: closing the TraCI socket and killing SUMO ---- \n");
|
||||
#else
|
||||
LOG_I (OMG,
|
||||
" --------Destructor for SUMO: closing the TraCI socket and killing SUMO ---- \n");
|
||||
#endif
|
||||
commandClose (); // closing the connection with SUMO via TraCI
|
||||
close_connection (); // closing the socket connection
|
||||
kill (pid, SIGKILL); // killing SUMO in case it could not close by itself
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -50,11 +50,11 @@
|
||||
/*! A global variable used to store the SUMO process ID to later kill it smoothly when OAI askes OMG to stop SUMO*/
|
||||
pid_t pid;
|
||||
|
||||
/*! A sumo global variable representing the OMG-SUMO ID manager. It is created at the start_sumo_generator() and keep a mapping between SUMO and OAI IDs. */
|
||||
/*! A sumo global variable representing the OMG-SUMO ID manager. It is created at the start_sumo_generator(void) and keep a mapping between SUMO and OAI IDs. */
|
||||
IDManagerPtr id_manager;
|
||||
|
||||
/*! A Node_list intended to contain the list of OAI 'active' nodes in SUMO. replaces the return of the full Node_Vector when OAI requests the new positions of its nodes. The list is reset at each use, but the pointer to the respective nodes is just set to NULL*/
|
||||
Node_list active_nodes;
|
||||
node_list* active_nodes;
|
||||
|
||||
/*! A global variable keeping track of the last update time of SUMO, to be used to get the update interval when update_sumo_nodes(cur_time) is called */
|
||||
double last_update_time;
|
||||
@@ -79,7 +79,7 @@ void update_sumo_nodes(double cur_time) ;
|
||||
* \brief Get the current position and speed of a node from SUMO. Invokes TraCI
|
||||
* \param node the pointer to a node we want to synch with SUMO.
|
||||
*/
|
||||
void update_sumo_positions(NodePtr node);
|
||||
void update_sumo_positions(node_struct* node);
|
||||
|
||||
/**
|
||||
* \fn Node_list get_sumo_positions_updated(double cur_time);
|
||||
@@ -87,7 +87,7 @@ void update_sumo_positions(NodePtr node);
|
||||
* \param cur_time a variable of type double that represents the current time
|
||||
* \return the list of ACTIVE OAI nodes, which positions have been updated by SUMO
|
||||
*/
|
||||
Node_list get_sumo_positions_updated(double cur_time);
|
||||
node_list* get_sumo_positions_updated(double cur_time);
|
||||
|
||||
/**
|
||||
* \fn NodePtr get_first_inactive_OAI_node(Node_list list, int node_type)
|
||||
@@ -96,13 +96,13 @@ Node_list get_sumo_positions_updated(double cur_time);
|
||||
* \param node_type the type of node we would like to locate (here: SUMO)
|
||||
* \return the reference to the first inactive OAI node; returns NULL is none could be found (all OAI nodes are currently active)
|
||||
*/
|
||||
NodePtr get_first_inactive_OAI_node(Node_list list, int node_type);
|
||||
node_struct* get_first_inactive_OAI_node(node_list* list, int node_type);
|
||||
|
||||
/**
|
||||
* \fn void update_IDs(String_list *departed, String_list *arrived)
|
||||
* \brief Updates the mapping between SUMO and OAI nodes; Once a node departs in SUMO, it is mapped to a inactive OAI node. If none are found, the SUMO node will not have any mapping. Once a node arrives, the mapping is removed and the OAI node becomes inactive again. When an OAI node is inactive, it mobility parameters are invalid and MUST NOT be used/requested by OAI.
|
||||
*/
|
||||
void update_IDs();
|
||||
void update_IDs(void);
|
||||
|
||||
/**
|
||||
* \fn bool desactive_and_unmap(char *sumo_id)
|
||||
@@ -122,10 +122,10 @@ bool desactivate_and_unmap(char *sumo_id);
|
||||
bool activate_and_map(char *sumo_id);
|
||||
|
||||
/**
|
||||
* \fn int stop_sumo_generator()
|
||||
* \fn int stop_sumo_generator(void)
|
||||
* \brief stops SUMO, stop the socket and kills SUMO process in the child domain.
|
||||
* \return true in case of success; false otherwise
|
||||
*/
|
||||
bool stop_sumo_generator();
|
||||
bool stop_sumo_generator(void);
|
||||
|
||||
#endif /* SUMO_H_ */
|
||||
|
||||
+483
-411
@@ -29,11 +29,11 @@
|
||||
|
||||
/*! \file trace.c
|
||||
* \brief The trace-based mobility model for OMG/OAI (mobility is statically imported from a file)
|
||||
* \author S. Uppoor and Navid Nikaein
|
||||
* \date 2011
|
||||
* \author S. Gashaw, N. Nikaein, J. Harri
|
||||
* \date 2014
|
||||
* \version 0.1
|
||||
* \company INRIA
|
||||
* \email: sandesh.uppoor@inria.fr
|
||||
* \company EURECOM
|
||||
* \email:
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
@@ -41,443 +41,515 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <math.h>
|
||||
#include "trace.h"
|
||||
#include "omg.h"
|
||||
#define FIXED 1
|
||||
#define MOVING 0
|
||||
|
||||
extern node_info* head_node_info;
|
||||
extern hash_table_t* table;
|
||||
extern hash_table_t **table;
|
||||
extern node_info **list_head;
|
||||
//check if the next input data is the same as the previous
|
||||
|
||||
int start_trace_generator(omg_global_param omg_param_list) {
|
||||
|
||||
// MobilityPtr mobility = NULL;
|
||||
|
||||
//read the mobility file here
|
||||
read_mobility_file(omg_param_list.mobility_file); // JHNOTE: in order to debug, please give and change name here...
|
||||
LOG_I(OMG, "mobility file %s put in the table %p\n",omg_param_list.mobility_file, table );
|
||||
|
||||
sort_veh_movement(table);
|
||||
|
||||
if (omg_param_list.nodes <= 0){
|
||||
LOG_W(OMG, "Number of nodes has not been set\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
// check and match number of nodes in mobility file provided
|
||||
if (omg_param_list.nodes != get_num_nodes()){
|
||||
LOG_W(OMG, "Make sure all nodes have mobility description in mobility file (%d,%d)\n",
|
||||
omg_param_list.nodes, get_num_nodes());
|
||||
//return(-1);
|
||||
}
|
||||
|
||||
if (omg_param_list.nodes_type == eNB) {
|
||||
LOG_I(OMG, "Start trace driven mobility gen for %d eNBs\n",omg_param_list.nodes);
|
||||
} else if (omg_param_list.nodes_type == UE) {
|
||||
LOG_I(OMG, "Start trace driven mobility gen for %d UEs\n",omg_param_list.nodes);
|
||||
}
|
||||
|
||||
deploy_nodes();
|
||||
return(0);
|
||||
}
|
||||
int
|
||||
start_trace_generator (omg_global_param omg_param_list)
|
||||
{
|
||||
double cur_time = 0.0;
|
||||
int immobile = 0;
|
||||
int node_number;
|
||||
node_struct *node = NULL;
|
||||
mobility_struct *mobility = NULL;
|
||||
pair_struct *pair = NULL;
|
||||
node_info *temp;
|
||||
|
||||
int deploy_nodes() {
|
||||
|
||||
NodePtr node = NULL;
|
||||
parse_data (omg_param_list.mobility_file, omg_param_list.nodes_type); //read mobility file
|
||||
|
||||
// int count = 0;
|
||||
node_info * head_node = head_node_info;
|
||||
while (head_node!=NULL){
|
||||
|
||||
//if (count<omg_param_list.nodes){
|
||||
create_trace_node(node,head_node);
|
||||
//count++;
|
||||
head_node=head_node->next;
|
||||
//}else
|
||||
// break;
|
||||
|
||||
}
|
||||
//if (count!=omg_param_list.nodes)
|
||||
// create_trace_node(node,head_node);
|
||||
|
||||
return(0);
|
||||
}
|
||||
//LOG_I (OMG, "mobility file %s put in the table %p\n",omg_param_list.mobility_file, table);
|
||||
|
||||
node_number = get_number_of_nodes (omg_param_list.nodes_type);
|
||||
|
||||
if (node_number == 0)
|
||||
LOG_E (OMG, "[TRACE] empty input file \n");
|
||||
|
||||
|
||||
LOG_I (OMG, "TRACE mobility model for %d %d nodes\n", node_number,
|
||||
omg_param_list.nodes_type);
|
||||
temp = list_head[omg_param_list.nodes_type];
|
||||
|
||||
while (temp != NULL)
|
||||
{
|
||||
node_data *this_node =
|
||||
get_next_data (table[omg_param_list.nodes_type], temp->g_id, DATA_AND_STATUS_CHANGE);
|
||||
|
||||
if (this_node == NULL)
|
||||
{
|
||||
LOG_E (OMG, "[TRACE] Unexpected empty data entry\n");
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
|
||||
node = create_node ();
|
||||
mobility = create_mobility ();
|
||||
node->id = temp->vid;
|
||||
node->gid = temp->g_id;
|
||||
|
||||
/* if(this_node->type == -1) //if node type is given in the file set the defualt type UE
|
||||
node->type = UE; */
|
||||
node->type = omg_param_list.nodes_type;
|
||||
node->generator = TRACE;
|
||||
node->mob = mobility;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void place_trace_node(NodePtr node) {
|
||||
Exnode* next_loc=NULL ;
|
||||
next_loc=get_next_position(table,node->ID);
|
||||
|
||||
node->X_pos = next_loc->x;
|
||||
node->mob->X_from = node->X_pos;
|
||||
node->mob->X_to = node->X_pos;
|
||||
node->Y_pos = next_loc->y;
|
||||
node->mob->Y_from = node->Y_pos;
|
||||
node->mob->Y_to = node->Y_pos;
|
||||
|
||||
node->mob->speed = next_loc->speed;
|
||||
node->mob->journey_time = 0.0;
|
||||
reset_visit_status(table,next_loc->time,node->ID);
|
||||
|
||||
void
|
||||
place_trace_node (node_struct * node, node_data * n)
|
||||
{
|
||||
node_data *n_ptr = n;
|
||||
node->x_pos = (double) n_ptr->x_pos;
|
||||
node->mob->x_from = node->x_pos;
|
||||
node->mob->x_to = node->x_pos;
|
||||
|
||||
node->y_pos = (double) n_ptr->y_pos;
|
||||
node->mob->y_from = node->y_pos;
|
||||
node->mob->y_to = node->y_pos;
|
||||
|
||||
node->mob->speed = n_ptr->speed;
|
||||
node->mob->journey_time = 0.0;
|
||||
// node->start_journey=(double) n_ptr->time; //time of initial position
|
||||
// node->mob->target_time=(double) n_ptr->next->time; //time of next destination
|
||||
LOG_I (OMG,
|
||||
"[TRACE] Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = %.2f \n ",
|
||||
node->id, node->type, node->x_pos, node->y_pos, node->mob->speed);
|
||||
|
||||
node_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]++;
|
||||
|
||||
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
|
||||
Pair sleep_trace_node(NodePtr node, double cur_time,float sleep_duration){
|
||||
|
||||
node->mobile = 0;
|
||||
node->mob->speed = 0.0;
|
||||
node->mob->X_from = node->mob->X_to;
|
||||
node->mob->Y_from = node->mob->Y_to;
|
||||
node->X_pos = node->mob->X_to;
|
||||
node->Y_pos = node->mob->Y_to;
|
||||
Pair pair = malloc(sizeof(Pair)) ;
|
||||
|
||||
node->mob->sleep_duration = sleep_duration ;
|
||||
LOG_D(OMG, "node: %d \tsleep duration : %.2f\n",node->ID, node->mob->sleep_duration);
|
||||
|
||||
node->mob->start_journey = cur_time;
|
||||
|
||||
pair->a =(node->mob->start_journey + node->mob->sleep_duration);
|
||||
|
||||
LOG_D(OMG, "to wake up at time: cur_time %f + sleep_duration : %.2f\n", cur_time,pair->a);
|
||||
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->mob->speed = 0.0;
|
||||
|
||||
// jump is used to displace node to strictly follow mobility discription
|
||||
if (jump== 1){
|
||||
node->X_pos = node->mob->X_to;
|
||||
node->Y_pos = node->mob->Y_to;
|
||||
}else{
|
||||
node->mob->X_to = node->X_pos;
|
||||
node->mob->Y_to = node->Y_pos;
|
||||
}
|
||||
node->mob->X_from = node->mob->X_to;
|
||||
node->mob->Y_from = node->mob->Y_to;
|
||||
Pair pair = malloc(sizeof(Pair)) ;
|
||||
LOG_D(OMG, "Node: %d \tawake duration : %.2f\n",node->ID, duration);
|
||||
node->mob->speed = n_data->speed;
|
||||
node->mob->x_to = (double) n_data->next->x_pos;
|
||||
node->mob->y_to = (double) n_data->next->y_pos;
|
||||
node->mob->target_time = (double) n_data->next->time;
|
||||
|
||||
//if speed equals to zero compute the speed(i.e node was on sleep move it)
|
||||
if (node->mob->speed == 0)
|
||||
{
|
||||
cdistance =
|
||||
(double)
|
||||
sqrtf
|
||||
(pow (node->mob->x_from - node->mob->x_to, 2) +
|
||||
pow (node->mob->y_from - node->mob->y_to, 2));
|
||||
journeytime = node->mob->target_time - n_data->time;
|
||||
speed = (double) cdistance / journeytime;
|
||||
node->mob->speed = speed;
|
||||
}
|
||||
|
||||
|
||||
distance =
|
||||
(double)
|
||||
sqrtf
|
||||
(pow (node->mob->x_from - node->mob->x_to, 2) +
|
||||
pow (node->mob->y_from - node->mob->y_to, 2));
|
||||
|
||||
|
||||
journeytime_next = (double) distance / node->mob->speed; //time to get to destination
|
||||
|
||||
/* LOG_D (OMG,
|
||||
"[TRACE] mob->journey_time_next %.2f target time %.2f next time %.2f speed %.2f\n",
|
||||
journeytime_next, node->mob->target_time, n_data->time,
|
||||
node->mob->speed);*/
|
||||
|
||||
node->mob->start_journey = cur_time;
|
||||
|
||||
//node->mob->target_time= 9999.;
|
||||
pair->a = node->mob->start_journey + duration;
|
||||
LOG_D(OMG, "To start up at time: cur_time + awake_duration : %.2f\n", pair->a);
|
||||
pair->b = node;
|
||||
LOG_D(OMG, "Current Position in awake : (%.2f, %.2f)\n", node->mob->X_from, node->mob->Y_from);
|
||||
return pair;
|
||||
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;
|
||||
pair->next_event_t = n_data->time; //when to move this node
|
||||
//LOG_D (OMG, "[TRACE] Node will wake up at time: %.2f\n", pair->next_event_t);
|
||||
}
|
||||
|
||||
|
||||
Pair move_trace_node(NodePtr node, double cur_time) {
|
||||
|
||||
Exnode* next_loc=NULL;
|
||||
next_loc=get_next_position(table,node->ID);
|
||||
|
||||
if (next_loc==NULL) {//Option 1 : no job, I am awake
|
||||
LOG_D(OMG, "NULL detected\n");
|
||||
return keep_awake_trace_node(node,cur_time,9999,1);
|
||||
}
|
||||
else{ // location discription available
|
||||
// Job_list tmp1 = Job_Vector;
|
||||
LOG_D(OMG, "Location fetch : (%.2f, %.2f)\n", next_loc->x, next_loc->y);
|
||||
|
||||
double X_next;
|
||||
double Y_next;
|
||||
double journeyTime_next;
|
||||
|
||||
// This was used to remove duplicate entries, vehicle stays in the same position
|
||||
//while((next_loc->x==tmp1->pair->b->mob->X_to && next_loc->y==tmp1->pair->b->mob->Y_to) )//|| next_loc->speed==0)
|
||||
// next_loc=get_next_position(table,node->ID);
|
||||
|
||||
//Trace defined time varies with current time so keep the node awake till the next trip discription time.
|
||||
if (( node->mob->target_time - cur_time) >= eps && node->mob->speed !=0.0){
|
||||
reset_visit_status(table,next_loc->time,node->ID);
|
||||
float awake_duration=(node->mob->target_time-cur_time);
|
||||
return keep_awake_trace_node(node,cur_time,awake_duration,1);
|
||||
void
|
||||
sleep_trace_node (pair_struct * pair, node_data * n_data, double cur_time)
|
||||
{
|
||||
double journeytime, distance;
|
||||
node_struct *node = pair->b;
|
||||
node->mobile = 0;
|
||||
node->mob->speed = 0.0;
|
||||
node->mob->x_from = node->mob->x_to;
|
||||
node->mob->y_from = node->mob->y_to;
|
||||
node->x_pos = node->mob->x_to;
|
||||
node->y_pos = node->mob->y_to;
|
||||
//sleep duration
|
||||
|
||||
if (n_data->x_pos == n_data->next->x_pos &&
|
||||
n_data->y_pos == n_data->next->y_pos)
|
||||
{
|
||||
node->mob->sleep_duration = n_data->next->time - n_data->time;
|
||||
|
||||
}
|
||||
|
||||
Pair pair = malloc(sizeof(Pair));
|
||||
LOG_D(OMG, "MOVE TRACE NODE\n");
|
||||
LOG_D(OMG, "node: %d\n",node->ID );
|
||||
node->mob->X_from = node->X_pos;
|
||||
node->mob->Y_from = node->Y_pos;
|
||||
LOG_D(OMG, "Current Position: (%.2f, %.2f)\n", node->mob->X_from, node->mob->Y_from);
|
||||
|
||||
if (!(next_loc->x==node->X_pos && next_loc->y==node->Y_pos) && (next_loc->speed==0. && node->mob->speed==0.0) ){
|
||||
node->mob->X_to = node->X_pos;
|
||||
node->mob->Y_to = node->Y_pos;
|
||||
node->mob->speed = next_loc->speed;
|
||||
journeyTime_next = next_loc->time-cur_time;
|
||||
reset_visit_status(table,next_loc->time,node->ID);
|
||||
LOG_D(OMG, "Location fetch reset: (%.2f, %.2f)\n", next_loc->x, next_loc->y);
|
||||
}else{
|
||||
X_next = next_loc->x;
|
||||
node->mob->X_to = X_next;
|
||||
Y_next = next_loc->y;
|
||||
node->mob->Y_to = Y_next;
|
||||
LOG_I(OMG, "destination: (%.2f, %.2f)\n", node->mob->X_to, node->mob->Y_to);
|
||||
|
||||
double target_time;
|
||||
target_time = next_loc->time;
|
||||
node->mob->target_time= target_time;
|
||||
|
||||
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;
|
||||
}
|
||||
else
|
||||
{ //sleep case 2
|
||||
node->mob->target_time - (journeytime + node->mob->start_journey);
|
||||
|
||||
}
|
||||
|
||||
node->mob->start_journey = cur_time;
|
||||
pair->next_event_t = cur_time + node->mob->sleep_duration; //when to wake up
|
||||
/*LOG_D (OMG, "#[TRACE] node: %d \tsleep duration : %.2f\n", node->id,
|
||||
node->mob->sleep_duration);*/
|
||||
|
||||
}
|
||||
|
||||
void update_trace_nodes(double cur_time) {
|
||||
|
||||
LOG_D(OMG, "--------UPDATE--------\n");
|
||||
Job_list tmp = Job_Vector;
|
||||
int done = 0; //
|
||||
|
||||
display_job_list(Job_Vector);
|
||||
while ((tmp != NULL) && (done == 0)){
|
||||
// if (tmp->pair == NULL){LOG_E(OMG, "UPDATE TRACE : tmp->pair ==NULL\n" );}
|
||||
// if (tmp->pair != NULL){LOG_E(OMG, "UPDATE TRACE : tmp->pair !=NULL\n" );}
|
||||
LOG_D(OMG, "cur_time %f\n", cur_time );
|
||||
LOG_D(OMG, "tmp->pair->a %f %f %f\n", tmp->pair->a , cur_time - eps,cur_time + eps);
|
||||
|
||||
if((tmp->pair !=NULL) && ( (double)tmp->pair->a >= cur_time - eps) && ( (double)tmp->pair->a <= cur_time + eps) ) {
|
||||
if (tmp->pair->b->generator == TRACE){
|
||||
LOG_D(OMG, " (first_job_time) %.2f == %.2f (cur_time) \n ",tmp->pair->a, cur_time );
|
||||
|
||||
// update to a new location
|
||||
/*if((tmp->pair->b->mob->speed == 0.0) && (tmp->pair->b->mobile == 1) && (tmp->pair->b->mob->target_speed==0.0)){
|
||||
Exnode* next_loc=NULL;
|
||||
|
||||
next_loc=get_next_position(table,tmp->pair->b->ID);
|
||||
if (next_loc !=NULL){
|
||||
tmp->pair->b->X_pos = next_loc->x ;
|
||||
tmp->pair->b->Y_pos = next_loc->y ;
|
||||
}
|
||||
} */
|
||||
LOG_D(OMG, " UPDATE TRACE \n ");
|
||||
NodePtr my_node = (NodePtr)tmp->pair->b;
|
||||
void
|
||||
update_trace_nodes (double cur_time)
|
||||
{
|
||||
job_list *tmp;
|
||||
int done = 0;
|
||||
node_data *node_n;
|
||||
node_struct *my_node;
|
||||
|
||||
if (my_node->mobile == 1 || my_node->mobile == 0) { //only move no stop , put to sleep in move_trace_node() only for disconnected mobility
|
||||
LOG_D(OMG, " node %d ready to move to next destination \n", my_node->ID);
|
||||
|
||||
//my_node->mobile = 1;
|
||||
Pair pair = malloc(sizeof(Pair));
|
||||
pair = move_trace_node(my_node, cur_time);
|
||||
|
||||
tmp->pair = pair;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
else{
|
||||
LOG_E(OMG, "update_generator: unsupported node state - mobile : %d \n", my_node->mobile);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG_D(OMG, " (first_job_time) %.2f == %.2f(cur_time) but (generator=%d) != (TRACE=%d)\n ",tmp->pair->a, cur_time, tmp->pair->b->generator, TRACE );
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
}
|
||||
else if ( (tmp->pair != NULL) && (cur_time < tmp->pair->a ) ){ //&& (tmp->pair->b->generator == RWP)
|
||||
LOG_D(OMG, "%.2f < %.2f \n",cur_time, tmp->pair->a);
|
||||
if ((cur_time >= tmp->pair->b->mob->target_time-eps) && (cur_time<=tmp->pair->b->mob->target_time + eps)){
|
||||
|
||||
tmp->pair->b->X_pos = tmp->pair->b->mob->X_to;
|
||||
tmp->pair->b->Y_pos = tmp->pair->b->mob->Y_to;
|
||||
Pair pair = malloc(sizeof(Pair));
|
||||
//pair = keep_awake_trace_node(tmp->pair->b,cur_time,awake_duration,1);
|
||||
pair = move_trace_node(tmp->pair->b, cur_time);
|
||||
tmp->pair = pair;
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
else {
|
||||
LOG_E(OMG, "%.2f > %.2f\n", cur_time,tmp->pair->a ); //LOG_D(OMG, " (generator=%d) != (RWP=%d) \n", tmp->pair->b->generator, RWP );
|
||||
done = 1; //quit the loop
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
//sorting the new entries
|
||||
LOG_D(OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
|
||||
display_job_list(Job_Vector);
|
||||
Job_Vector = quick_sort (Job_Vector);///////////
|
||||
LOG_D(OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
|
||||
display_job_list(Job_Vector);
|
||||
|
||||
}
|
||||
|
||||
void get_trace_positions_updated(double cur_time){
|
||||
|
||||
double X_now=0.0;
|
||||
double Y_now=0.0;
|
||||
//LOG_D(OMG, "--------GET TRACE POSITIONS--------\n");
|
||||
tmp = job_vector[TRACE];
|
||||
if (tmp == NULL)
|
||||
LOG_D (OMG, "[TRACE] last data for all nodes\n");
|
||||
|
||||
Pair my_pair = Job_Vector->pair;
|
||||
|
||||
if ( (my_pair !=NULL) && (cur_time <= my_pair->a )){
|
||||
// LOG_D(OMG, "%.2f <= %.2f\n ",cur_time, my_pair->a);
|
||||
Job_list tmp = Job_Vector;
|
||||
|
||||
|
||||
while (tmp != NULL){
|
||||
if (tmp->pair->b->generator == TRACE){
|
||||
|
||||
if (tmp->pair->b->mobile == 0){ //node is sleeping
|
||||
LOG_T(OMG, "node number %d is sleeping at location: (%.2f, %.2f)\n", tmp->pair->b->ID, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
|
||||
LOG_T(OMG, "nothing to do\n");
|
||||
}
|
||||
else if (tmp->pair->b->mobile == 1){ //node is moving
|
||||
LOG_D(OMG,"Node %d is mobile at %f\n", tmp->pair->b->ID,cur_time);
|
||||
LOG_T(OMG, "Node_number %d\n", tmp->pair->b->ID);
|
||||
LOG_D(OMG, "destination not yet reached\tfrom (%.2f, %.2f)\tto (%.2f, %.2f)\tspeed %.2f\t(X_pos %.2f\tY_pos %.2f)\n", tmp->pair->b->mob->X_from, tmp->pair->b->mob->Y_from,tmp->pair->b->mob->X_to, tmp->pair->b->mob->Y_to,tmp->pair->b->mob->speed, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
|
||||
|
||||
double step=0.10;
|
||||
|
||||
if (tmp->pair->b->mob->speed == 0.0 ){
|
||||
|
||||
if (tmp->pair->b->mob->target_speed == 0.0 ){
|
||||
|
||||
if ((cur_time >= (tmp->pair->b->mob->target_time-step)-eps) && (cur_time<=(tmp->pair->b->mob->target_time + step)+eps)) {
|
||||
|
||||
Exnode* next_loc=NULL;
|
||||
next_loc=get_next_position(table,tmp->pair->b->ID);
|
||||
while (tmp != NULL && done != 1)
|
||||
{ //1
|
||||
my_node = tmp->pair->b;
|
||||
node_n = get_next_data (table[my_node->type], my_node->gid, DATA_ONLY);
|
||||
|
||||
if (next_loc !=NULL){
|
||||
tmp->pair->b->X_pos = next_loc->x ;
|
||||
tmp->pair->b->Y_pos = next_loc->y ;
|
||||
//tmp->pair->b->X_pos = tmp->pair->b->mob->X_to;
|
||||
//tmp->pair->b->Y_pos = tmp->pair->b->mob->Y_to;
|
||||
}
|
||||
}
|
||||
}
|
||||
// needed ?
|
||||
//tmp->pair->b->X_pos = tmp->pair->b->mob->X_from + 0.0;
|
||||
//tmp->pair->b->Y_pos = tmp->pair->b->mob->Y_from + 0.0;
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
double len = sqrtf(pow(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to,2)+pow(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to,2));
|
||||
double dx = fabs(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to) / len;
|
||||
|
||||
double dy = fabs(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to) / len;
|
||||
|
||||
if (tmp->pair->b->mob->X_from < tmp->pair->b->mob->X_to ){
|
||||
X_now = tmp->pair->b->mob->X_from + (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey) ) );
|
||||
}
|
||||
else{
|
||||
X_now = tmp->pair->b->mob->X_from - (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
|
||||
}
|
||||
|
||||
if (tmp->pair->b->mob->Y_from < tmp->pair->b->mob->Y_to ){
|
||||
Y_now = tmp->pair->b->mob->Y_from + (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
|
||||
}
|
||||
else{
|
||||
Y_now = tmp->pair->b->mob->Y_from - (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
|
||||
}
|
||||
|
||||
LOG_D(OMG, "X_now %f\tY_now %f\n", X_now, Y_now);
|
||||
tmp->pair->b->X_pos = (double) ((int) (X_now*100))/ 100;
|
||||
tmp->pair->b->Y_pos = (double) ((int) (Y_now*100))/ 100;
|
||||
//tmp->pair->b->mob->X_from = tmp->pair->b->X_pos;
|
||||
//tmp->pair->b->mob->Y_from = tmp->pair->b->Y_pos;
|
||||
//tmp->pair->b->mob->start_journey = cur_time;
|
||||
}
|
||||
LOG_D(OMG, "Updated_position of %s id %d to :(%.2f, %.2f)\n", (tmp->pair->b->type == 0) ? "eNB" : "UE", tmp->pair->b->ID, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
|
||||
}
|
||||
else{
|
||||
LOG_E(OMG, "Update_generator: unsupported node state - mobile : %d \n", tmp->pair->b->mobile);
|
||||
return;
|
||||
if (node_n->next->next == NULL)
|
||||
{
|
||||
tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
|
||||
tmp->pair->b->mob->x_from = tmp->pair->b->x_pos;
|
||||
tmp->pair->b->y_pos = tmp->pair->b->mob->y_to;
|
||||
tmp->pair->b->mob->y_from = tmp->pair->b->y_pos;
|
||||
tmp->pair->b->mobile = 0;
|
||||
tmp->pair->b->mob->speed = 0.0;
|
||||
// LOG_D (OMG, "[TRACE] last data for all nodes\n");
|
||||
tmp = tmp->next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//case1:time to next event equals to current time
|
||||
if (tmp->pair != NULL && tmp->pair->next_event_t >= cur_time - eps
|
||||
&& tmp->pair->next_event_t <= cur_time + eps)
|
||||
{
|
||||
//LOG_D (OMG, "[TRACE] last data for all nodes\n");
|
||||
if (my_node->mobile == 1)
|
||||
{
|
||||
if (my_node->mob->target_time > tmp->pair->next_event_t) //sleep node
|
||||
{
|
||||
sleep_trace_node (tmp->pair, node_n, cur_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
node_n =
|
||||
get_next_data (table[my_node->type], my_node->gid,
|
||||
DATA_AND_STATUS_CHANGE);
|
||||
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//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)
|
||||
{
|
||||
double x_now = 0.0, y_now = 0.0;
|
||||
double len, dx, dy;
|
||||
job_list *tmp = job_vector[TRACE];
|
||||
|
||||
while (tmp != NULL)
|
||||
{
|
||||
|
||||
if (tmp->pair->b->mobile == 1 && tmp->pair->next_event_t >= cur_time)
|
||||
{
|
||||
|
||||
//printf("hiiiiiiiiiii \n");
|
||||
len =
|
||||
sqrtf (pow
|
||||
(tmp->pair->b->mob->x_from -
|
||||
tmp->pair->b->mob->x_to,
|
||||
2) + pow (tmp->pair->b->mob->y_from -
|
||||
tmp->pair->b->mob->y_to, 2));
|
||||
if (len != 0)
|
||||
{
|
||||
dx =
|
||||
fabs (tmp->pair->b->mob->x_from -
|
||||
tmp->pair->b->mob->x_to) / len;
|
||||
dy =
|
||||
fabs (tmp->pair->b->mob->y_from -
|
||||
tmp->pair->b->mob->y_to) / len;
|
||||
//x coordinate
|
||||
if (tmp->pair->b->mob->x_from < tmp->pair->b->mob->x_to)
|
||||
{
|
||||
x_now =
|
||||
tmp->pair->b->mob->x_from +
|
||||
(dx *
|
||||
(tmp->pair->b->mob->speed *
|
||||
(cur_time - tmp->pair->b->mob->start_journey)));
|
||||
}
|
||||
else
|
||||
{
|
||||
x_now =
|
||||
tmp->pair->b->mob->x_from -
|
||||
(dx *
|
||||
(tmp->pair->b->mob->speed *
|
||||
(cur_time - tmp->pair->b->mob->start_journey)));
|
||||
}
|
||||
|
||||
//y coordinate
|
||||
if (tmp->pair->b->mob->y_from < tmp->pair->b->mob->y_to)
|
||||
{
|
||||
y_now =
|
||||
tmp->pair->b->mob->y_from +
|
||||
(dy *
|
||||
(tmp->pair->b->mob->speed *
|
||||
(cur_time - tmp->pair->b->mob->start_journey)));
|
||||
}
|
||||
else
|
||||
{
|
||||
y_now =
|
||||
tmp->pair->b->mob->y_from -
|
||||
(dy *
|
||||
(tmp->pair->b->mob->speed *
|
||||
(cur_time - tmp->pair->b->mob->start_journey)));
|
||||
}
|
||||
|
||||
tmp->pair->b->x_pos = (double) ((int) (x_now * 100)) / 100;
|
||||
tmp->pair->b->y_pos = (double) ((int) (y_now * 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;
|
||||
}
|
||||
|
||||
}
|
||||
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)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
+10
-53
@@ -42,65 +42,22 @@
|
||||
#define TRACE_H_
|
||||
//#include "defs.h"
|
||||
#include "omg.h"
|
||||
#include "hashtable.h"
|
||||
#include "trace_hashtable.h"
|
||||
#include "mobility_parser.h"
|
||||
|
||||
int start_trace_generator (omg_global_param omg_param_list);
|
||||
|
||||
/**
|
||||
* \fn void start_trace_generator(omg_global_param omg_param_list)
|
||||
* \brief Start the TRACE model by setting the initial positions of each node then letting it sleep for a random duration and adding this job to the Job_Vector
|
||||
* \param omg_param_list a structure that contains the main parameters needed to establish the random positions distribution
|
||||
*/
|
||||
int start_trace_generator(omg_global_param omg_param_list) ;
|
||||
void place_trace_node (node_struct* node, node_data* n);
|
||||
|
||||
/**
|
||||
* \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) ;
|
||||
void move_trace_node (pair_struct* pair, node_data* n_data, 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) ;
|
||||
void schedule_trace_node ( pair_struct* pair, node_data* n_data, 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 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_ */
|
||||
|
||||
@@ -0,0 +1,250 @@
|
||||
/*******************************************************************************
|
||||
|
||||
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 ()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/*******************************************************************************
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user