diff --git a/openair2/UTIL/FIFO/types.h b/openair2/UTIL/FIFO/types.h index 063bb1ed9d30f292a495ab33166f0e5b2f8fc945..0ea9915c7030b1edf2282a61f4397f7d9e6b92a6 100644 --- a/openair2/UTIL/FIFO/types.h +++ b/openair2/UTIL/FIFO/types.h @@ -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; diff --git a/openair2/UTIL/LOG/log.c b/openair2/UTIL/LOG/log.c index ad672d1859d241701845b367a7d14741eed1e6ae..3ea9d47b52090ce88e6bf3934403cda1c1c3e7a6 100755 --- a/openair2/UTIL/LOG/log.c +++ b/openair2/UTIL/LOG/log.c @@ -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; diff --git a/openair2/UTIL/Makefile.inc b/openair2/UTIL/Makefile.inc index efad62244fd1288ee60106aa3469c9133bfbe72a..fac8d7e9a17885e0f03f321217b69fa547f4ab78 100644 --- a/openair2/UTIL/Makefile.inc +++ b/openair2/UTIL/Makefile.inc @@ -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 diff --git a/openair2/UTIL/OCG/OCG.h b/openair2/UTIL/OCG/OCG.h index 69e66d9934d09ee46462545d0cdd4cb04e154ae5..fa2e88677787c0f1eda298c0601cd40ff45e4859 100644 --- a/openair2/UTIL/OCG/OCG.h +++ b/openair2/UTIL/OCG/OCG.h @@ -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 */ diff --git a/openair2/UTIL/OCG/OCG_parse_XML.c b/openair2/UTIL/OCG/OCG_parse_XML.c index d828a87a46d207fae2b6f41224b62d34dc816a04..b75e75ed90034884af9787ddd25256cc6abd13de 100644 --- a/openair2/UTIL/OCG/OCG_parse_XML.c +++ b/openair2/UTIL/OCG/OCG_parse_XML.c @@ -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_) { diff --git a/openair2/UTIL/OMG/TRACE/static_2ues.tr b/openair2/UTIL/OMG/TRACE/static_2ues.tr index b7e5a17789278b3330f95a790c361b8ece6ebf97..f669f8107350af6293803e2e261d0b63544e9818 100644 --- a/openair2/UTIL/OMG/TRACE/static_2ues.tr +++ b/openair2/UTIL/OMG/TRACE/static_2ues.tr @@ -1,2 +1,3 @@ 1 0 2050 1500 0 1 1 2150 1500 0 + diff --git a/openair2/UTIL/OMG/client_traci_OMG.c b/openair2/UTIL/OMG/client_traci_OMG.c index 63667b23e822207e3f44d90a09f0a1eaa1bd3674..f622b34fbf80ba3646c34f623529bb125fc1c8e1 100644 --- a/openair2/UTIL/OMG/client_traci_OMG.c +++ b/openair2/UTIL/OMG/client_traci_OMG.c @@ -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; } diff --git a/openair2/UTIL/OMG/client_traci_OMG.h b/openair2/UTIL/OMG/client_traci_OMG.h index df643d42a76dcc8e2cf53fc636b726258c8505c4..3384be1ca6a86f81916430ed5a737a6cb6ba19e1 100644 --- a/openair2/UTIL/OMG/client_traci_OMG.h +++ b/openair2/UTIL/OMG/client_traci_OMG.h @@ -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 diff --git a/openair2/UTIL/OMG/common.c b/openair2/UTIL/OMG/common.c index fb830654515aaac0d8f5efb54d05a3eac7d80f5b..f19f59aa423303f06a27b7301ed03bf55ec85781 100644 --- a/openair2/UTIL/OMG/common.c +++ b/openair2/UTIL/OMG/common.c @@ -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; + } + } + } } - } - 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; + 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 ); - - //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); +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_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; - } -} + else + { //start search + current = list; + while ((current != NULL) + && ((current->node->id != nid) + || (current->node->type != node_type))) + { + previous = current; // previous hobbles after + current = current->next; + } + //holds: current = NULL or type != node_type or.., but not both + if (current == NULL) + { + found = 1; + LOG_E (OMG, " Element to remove is not found\n "); + return NULL; + } //value not found + else + { + found = 0; // true value found + if (current == list) + { + list = current->next; + LOG_D (OMG, "Element to remove is found at beginning\n"); + } + + else + { + previous->next = current->next; + + } + delete_node_entry (current); // freeing memory + current = NULL; -int length(char* s){ - int count = 0; - while(s[count] != '\0'){ - ++count; } - return count; + return list; + } } -NodePtr find_node(Node_list list, int nID, int node_type){ - +int +length (char *s) +{ + int count = 0; + while (s[count] != '\0') + { + ++count; + } + return count; +} + +node_struct * +find_node (node_list * list, int nid, int node_type) +{ + int found; - 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; - - 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 - } +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 + } 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; - - 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... - } +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... + } 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 + +#endif diff --git a/openair2/UTIL/OMG/defs.h b/openair2/UTIL/OMG/defs.h index 6ee2b6c71f14285635a5ea16642afbaf7ebf29d9..118971d32e484ca121ccc4d5d64b061c61bbbc16 100644 --- a/openair2/UTIL/OMG/defs.h +++ b/openair2/UTIL/OMG/defs.h @@ -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() diff --git a/openair2/UTIL/OMG/grid.c b/openair2/UTIL/OMG/grid.c new file mode 100644 index 0000000000000000000000000000000000000000..9101b142c1d92281cab6572d902bff9f1e80c4d4 --- /dev/null +++ b/openair2/UTIL/OMG/grid.c @@ -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; + +} diff --git a/openair2/UTIL/OMG/grid.h b/openair2/UTIL/OMG/grid.h new file mode 100644 index 0000000000000000000000000000000000000000..a64b2f21a874bc599c27bc5d14c79cdec9b73998 --- /dev/null +++ b/openair2/UTIL/OMG/grid.h @@ -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 + diff --git a/openair2/UTIL/OMG/job.c b/openair2/UTIL/OMG/job.c index b1143ba363031c81fde6d272a557c49b83b92528..9d93e0a3c89f3cf0a8c2f7b066db1929e1540b7a 100644 --- a/openair2/UTIL/OMG/job.c +++ b/openair2/UTIL/OMG/job.c @@ -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; - - 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; - } - 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; +job_list * +add_job (pair_struct * job, job_list * job_vector) +{ + + job_list *tmp; + job_list *entry = (job_list *) malloc (sizeof (struct job_list_struct)); + entry->pair = job; + entry->next = NULL; + + if (job_vector != NULL) + { + + tmp = job_vector; + tmp->next = entry; } + + return entry; + } +//add_job2 + +job_list * +addjob (pair_struct * job, job_list * job_vector) +{ + + job_list *tmp; + job_list *entry = (job_list *) malloc (sizeof (struct job_list_struct)); + entry->pair = job; + entry->next = NULL; + + if (job_vector == NULL) + { + 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(Job_list Job_Vector){ +void +display_job_list (double curr_t, job_list * job_vector) +{ + + job_list *tmp = job_vector; + if (tmp == NULL) + { + LOG_D (OMG, "Empty Job_list\n"); + } + else + { + //LOG_D(OMG, "first_Job_time in Job_Vector %f\n", Job_Vector->pair->a); + while (tmp != NULL) + { + if ((tmp->pair != NULL) /*&& tmp->pair->b->id==0 */ ) + //LOG_D(OMG, "%.2f %.2f \n",tmp->pair->b->x_pos, tmp->pair->b->y_pos); + LOG_D (OMG, "%.2f %d %d %.2f %.2f %.2f\n", curr_t, tmp->pair->b->id,tmp->pair->b->gid, + tmp->pair->b->x_pos, tmp->pair->b->y_pos, + tmp->pair->b->mob->speed); - Job_list tmp = Job_Vector; - if (tmp == NULL){LOG_D(OMG, "Empty Job_list\n");} - else{ - //LOG_D(OMG, "first_Job_time in Job_Vector %f\n", Job_Vector->pair->a); - while (tmp != NULL){ - if ((tmp->pair != NULL)) - LOG_D(OMG, "node %d \ttime %.2f\n", tmp->pair->b->ID, tmp->pair->a); - tmp = tmp->next; + tmp = tmp->next; + } } - } +} + +//average nodes speed for each mobility type +unsigned int +nodes_avgspeed (job_list * job_vector) +{ + job_list *tmp = job_vector; + unsigned int avg = 0, cnt = 0; + if (tmp == NULL) + { + LOG_D (OMG, "Empty Job_list\n"); + return 0; + } + else + { + while (tmp != NULL) + { + if ((tmp->pair != NULL)) + { + avg += tmp->pair->b->mob->speed; + cnt++; + } + tmp = tmp->next; + } + } + return avg / cnt; } // quick sort of the linked list -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; +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->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; + return list; } -Job_list quick_sort (Job_list list) +job_list * +quick_sort (job_list * list) { - return job_list_sort(list, NULL); + return job_list_sort (list, NULL); } -Job_list remove_job(Job_list list, int nID, int node_type){ - - Job_list current, previous; - //int cond=0; - int i=0; - if (list == NULL){ - return NULL; - } - else{ //start search - current = list; - if ((current != NULL) && (current->pair->b->ID == nID) && (current->pair->b->type == node_type )){LOG_D(OMG, "(current != NULL) && (current->pair->b->ID != nID) && (current->pair->b->type != node_type ");} - while ( (current != NULL) && ((current->pair->b->ID != nID) || (current->pair->b->type != node_type ))){ - LOG_D(OMG, "current->pair->b->ID %d",current->pair->b->ID); - LOG_D(OMG, "nID %d",nID); - LOG_D(OMG, "current->pair->b->type %d",current->pair->b->type ); // UE, eNB 1 - LOG_D(OMG, "node_type %d",node_type ); //UE, eNB 0 - LOG_D(OMG, "current->pair->b->generator %d",current->pair->b->generator ); //static - - LOG_D(OMG, "i = %d", i); - previous = current; // previous hobbles after +job_list * +remove_job (job_list * list, int nid, int node_type) +{ + + job_list *current, *previous; + + current = list; + previous = NULL; + while (current != NULL) + { + if (current->pair->b->id == nid && current->pair->b->type == node_type) + { + if (current == list || previous == NULL) + list = current->next; + else + previous->next = current->next; + + 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; +} diff --git a/openair2/UTIL/OMG/makefile_standalone b/openair2/UTIL/OMG/makefile_standalone index 858c65cc912958274718c3a6d3bbd9fc39230128..68170543eedc73012c487ae70a3a9912485c9507 100644 --- a/openair2/UTIL/OMG/makefile_standalone +++ b/openair2/UTIL/OMG/makefile_standalone @@ -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 diff --git a/openair2/UTIL/OMG/mobility_parser.c b/openair2/UTIL/OMG/mobility_parser.c index fb1628ca34960f4b3cd0d3f550c43db829b6c06b..a97f38fa82967f58cc60b468dbb4ced405ee1845 100644 --- a/openair2/UTIL/OMG/mobility_parser.c +++ b/openair2/UTIL/OMG/mobility_parser.c @@ -29,11 +29,11 @@ /*! \file mobility_parser.c * \brief A parser for trace-based mobility information (parsed from a file) -* \author S. Uppoor -* \date 2011 +* \author S. Gashaw, N. Nikaein, J. Harri +* \date 2014 * \version 0.1 -* \company INRIA -* \email: sandesh.uppoor@inria.fr +* \company EURECOM +* \email: * \note * \warning */ @@ -42,442 +42,226 @@ #include <string.h> #include <stdlib.h> #include "mobility_parser.h" -#include "omg_hashtable.h" #include "omg.h" +#include <math.h> +extern hash_table_t **table; +extern node_info **list_head; -node_info* head_node_info =NULL; -omg_hash_table_t* table=NULL; +//read the mobility file and generates a hashtable of linked list +void +parse_data (char *trace_file, int node_type) +{ + FILE *fp; + char *pch, *p; + char str[128]; + int fmt, id = 0, gid; + node_container *value; -//need to be removed , used only once (old code) -struct Exnode* gen_list(){ - struct Exnode* head = NULL; - return head; -} + //if(table==NULL) + create_new_table (node_type); + if(list_head ==NULL) + list_head = (node_info **) calloc (MAX_NUM_NODE_TYPES, sizeof (node_info*)); -//read the mobility file and generates a hashtable of linked list with key pointing to vehicle id -void read_mobility_file(char* mobility_file[]){ - FILE *fp; - char str[128],*p; - if (table == NULL){ - table = hash_table_new(MODE_ALLREF); - } - - if((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); - } - } + 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; - } -} + if ((fp = fopen (trace_file, "r")) == NULL) + { + LOG_E (OMG, "[OMG]:Cannot open file %s\n", trace_file); + exit (1); + } + + + while (!feof (fp)) + { + if (fgets (str, 126, fp)) + { + fmt = 0; + p = str; + + while (*p == ' ' || *p == '\t' || *p == '\r') + p++; // skip whitespaces + + if (*p != '\n') //escape empty line + { + pch = strtok (p, " "); // the separator between the items in the list is a space + node_data *node = (node_data *) calloc (1, sizeof (node_data)); + node->type=-1; + + while (pch != NULL) + { + + switch (fmt) + { + case 0: + if (atof (pch) < 0) + LOG_E (OMG, "error: negative time input \n"); + node->time = fabs (atof (pch)); + LOG_D (OMG, "%.2f \n",node->time); + break; + case 1: + node->vid = atoi (pch); + LOG_D (OMG, "%d \n",node->vid); + break; + case 2: + node->x_pos = atof (pch); + LOG_D (OMG, "%.2f \n",node->x_pos); + break; + case 3: + node->y_pos = atof (pch); + LOG_D (OMG, "%.2f \n",node->y_pos); + break; + case 4: + if (atof (pch) < 0) + LOG_D (OMG, "error: negative speed input"); + node->speed = fabs (atof (pch)); + LOG_D (OMG, "speed %.2f \n",node->speed); + break; + /*case 5: + node->type = atof (pch); + break;*/ + default: + LOG_E (OMG, + "[Error in trance file]:incorrect data format \n"); + break; + } + + fmt += 1; + pch = strtok (NULL, " "); + } + + node->next = NULL; + node->visit = 0; + + // look for node in node info + gid = find_node_info (node->vid, node_type); + + if (gid == -1) + { + node->gid = id; + add_node_info (node->vid, node->gid, node_type); + //store node data in the table + hash_table_add (table[node_type], node, NULL); + id++; + } + else + { + node->gid = gid; + value = hash_table_lookup (table[node_type], node->gid); + hash_table_add (table[node_type], node, value); + } + + + + } + } + } + + fclose (fp); -//Just used for testing, it prints a linked list given the head pointer -void print_list(struct Exnode* head){ - - while(head->next !=NULL) - head=head->next; } -Exnode* get_next_position(omg_hash_table_t *table,int node_id){ - node_info* head_node=head_node_info; - while(head_node->next!=NULL){ - - if(head_node->vid==node_id){ - int *value1 = NULL; - value1 = (int *) HT_LOOKUP(table, head_node->vid_addr); - if (value1!=NULL){ - Exnode* value2=(Exnode *)value1; - while(value2->next!=NULL){ - if (value2->visit==1) value2=value2->next; - else { - value2->visit=1; - return value2; - } - } - if (value2->visit!=1){ - value2->visit=1; - return value2; - } - } - } - head_node=head_node->next; - } - // not to leave the last node with ->next=NULL - if(head_node->vid==node_id){ - int *value1 = NULL; - value1 = (int *) HT_LOOKUP(table, head_node->vid_addr); - if (value1!=NULL){ - Exnode* value2=(Exnode *)value1; - while(value2->next!=NULL){ - if (value2->visit==1) value2=value2->next; - else { - value2->visit=1; - return value2; +//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; } - } - if (value2->visit!=1){ - value2->visit=1; - return value2; - } } - } - return NULL; + + return -1; } +//builds linked list with each node holding vehicle id read from file & given id +void +add_node_info (int nid, int n_gid, int node_type) +{ + node_info *new = (node_info *) malloc (sizeof (node_info)); + if (new != NULL) + { + new->vid = nid; + new->g_id = n_gid; + new->next = NULL; -void reset_visit_status(omg_hash_table_t *table,float time, int node_id){ - 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; + 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; } - } } - 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; + else + { + LOG_E (OMG, "node info list creation failed\n"); + exit (-1); } - } - } -int get_num_nodes(){ - int count=1; //Last node also need to be counted - node_info * head_node=head_node_info; - while (head_node->next!=NULL){ - count += 1; - head_node=head_node->next; - } - return count; -} -void sort_veh_movement(omg_hash_table_t *table){ - node_info* head_node=head_node_info; - while(head_node->next!=NULL){ - int *value1 = NULL; - value1 = (int *) HT_LOOKUP(table, head_node->vid_addr); - Exnode* head_veh_node = (Exnode *)value1; - Exnode* value2 = (Exnode *)value1; - while (value2->next!=NULL){ - value2 = value2->next; - } - Exnode* tail_veh_node = (Exnode *)value2; - quicksortlist(head_veh_node, tail_veh_node); - head_node=head_node->next; - } - // come on !! use functions :-) - // last node with ->next == NULL - int *value1 = NULL; - value1 = (int *) HT_LOOKUP(table, head_node->vid_addr); - Exnode* head_veh_node = (Exnode *)value1; - Exnode* value2 = (Exnode *)value1; - while (value2->next!=NULL){ - value2 = value2->next; - } - Exnode* tail_veh_node = (Exnode *)value2; - quicksortlist(head_veh_node, tail_veh_node); -} -// quick sort list -void quicksortlist(Exnode *pLeft, Exnode *pRight){ - Exnode *pStart; - Exnode *pCurrent; - double swp_time; - int swp_vid; - double swp_x; - double swp_y; - double swp_speed; - int swp_visit; - - // If the left and right pointers are the same, then return - if (pLeft == pRight) return; - - // Set the Start and the Current item pointers - pStart = pLeft; - pCurrent = pStart->next; - // Loop forever (well until we get to the right) - while (1){ - if (pStart->time > pCurrent->time){ - // Swap the items,swapping address could be critical, head pointer change will disrupt - // so swapping values - swp_time = pCurrent->time; - swp_vid = pCurrent->vid; - swp_x = pCurrent->x; - swp_y = pCurrent->y; - swp_speed = pCurrent->speed; - swp_visit = pCurrent->visit; - - pCurrent->time = pStart->time; - pCurrent->vid = pStart->vid; - pCurrent->x = pStart->x; - pCurrent->y = pStart->y; - pCurrent->speed = pStart->speed; - pCurrent->visit = pStart->visit; - - pStart->time = swp_time; - pStart->vid = swp_vid; - pStart->x = swp_x; - pStart->y = swp_y; - pStart->speed = swp_speed; - pStart->visit = swp_visit; - } - - // Check if we have reached the end - if (pCurrent == pRight) break; - - // Move to the next item in the list - pCurrent = pCurrent->next; - } - quicksortlist(pStart->next,pCurrent); - + +int +get_number_of_nodes (int node_type) +{ + return table[node_type]->key_count; } -void clear_llist(){ - - node_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; +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; } - tmp=TempNode; - TempNode=TempNode->next; - free(tmp); - tmp=NULL; - } - if (TempNode->next==NULL ){ - free(TempNode); - TempNode=NULL; - } - hash_table_delete(table); -} -/* - -int main(){ - //char *mobility_file[50]; - Exnode* next_loc=NULL; - //mobility_file = (char*) malloc(256); - //mobility_file=strtok("regular.tr"); - omg_hash_table_t *table=read_mobility_file(); - sort_veh_movement(table); - printf("Number of nodes --> %d \n",get_num_nodes()); - next_loc=get_next_position(table,140392); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - //next_loc=NULL; - next_loc=get_next_position(table,140392); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - //next_loc=NULL; - next_loc=get_next_position(table,140392); - if (next_loc!=NULL){ - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - //next_loc=NULL; - }next_loc=get_next_position(table,140392); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - next_loc=get_next_position(table,140392); - //if (next_loc!=NULL){ - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - next_loc=get_next_position(table,140392); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - next_loc=get_next_position(table,140392); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - next_loc=get_next_position(table,140392); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - next_loc=get_next_position(table,140392); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - next_loc=get_next_position(table,140392); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - next_loc=get_next_position(table,140392); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - next_loc=get_next_position(table,140392); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - next_loc=get_next_position(table,140392); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - next_loc=get_next_position(table,140392); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - next_loc=get_next_position(table,140392); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - next_loc=get_next_position(table,140392); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - next_loc=get_next_position(table,140396); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - next_loc=get_next_position(table,140396); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - next_loc=get_next_position(table,140396); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - next_loc=get_next_position(table,140396); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - next_loc=get_next_position(table,140396); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - next_loc=get_next_position(table,140396); - printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid); - //reset_visit_status(table,20.0,11); - node_info* head_node=head_node_info; - - while(head_node->next!=NULL){ - - if(head_node->vid==140392){ - int *value1 = NULL; - value1 = (int *) HT_LOOKUP(table, head_node->vid_addr); - Exnode *value=(Exnode *)value1; - while(value->next!=NULL){ - printf("checking reset %d\n",value->visit); - value=value->next; - } - printf("checking reset %d\n",value->visit); - } - head_node=head_node->next; + if (links != NULL) + { + if (flag == DATA_AND_STATUS_CHANGE) + { + if (block->next != block->end) + links->visit = 1; + return links; } - int *value1 = NULL; - value1 = (int *) HT_LOOKUP(table, head_node->vid_addr); - Exnode *value=(Exnode *)value1; - while(value->next!=NULL){ - printf("checking reset %d %d\n",value->visit,value->vid); - value=value->next; - } - printf("checking reset %d %d\n",value->visit,value->vid); - return 0; -}*/ + else if (flag == DATA_ONLY) + { + return save; + } + } + else + return links; +} diff --git a/openair2/UTIL/OMG/mobility_parser.h b/openair2/UTIL/OMG/mobility_parser.h index 71aab536ae70a8cd76eb7b8dcf29c3b82f28ed82..71162a5977300335f871ef006416e97c92deebd9 100644 --- a/openair2/UTIL/OMG/mobility_parser.h +++ b/openair2/UTIL/OMG/mobility_parser.h @@ -41,62 +41,16 @@ #ifndef MOBILITY_PARSER_H_ #define MOBILITY_PARSER_H_ -#include "omg_hashtable.h" +#include "trace_hashtable.h" -/** - * @struct Simple struct to hold only few information - * @brief The entry in each node is a line from the external mobility file - */ -typedef struct Exnode { - double time; - int vid; - double x; - double y; - double speed; - int visit; - struct Exnode* next; - -}Exnode; - -/** - * @struct struct acts as gateway to hashtable - * @brief holds vehicle id and initial pointer to the head of the linked list in hastable - */ -typedef struct node_info { - int vid; - int *vid_addr; - struct node_info* next; - //struct node_info* prev; -}node_info; -// head pointer to a linked list containing vid,vid_addr - - - -/** - * function just to initialize the head of the linked list to NULL, this can be removed later(check). - */ -struct Exnode* gen_list(); -/** - * Function to append the line content to build a linked list. - * @param headRef is the pointer to the head of the existing list to which append has to be done - * @param newNode , item to be appended - */ -void AppendNode(struct Exnode* headRef, struct Exnode* newNode); - -/** - * function just prints the linked list (need to be removed, used for testing) - * @param pointer to the head of the linked list - */ -void print_list(struct Exnode* head); - -/** +/* * function reads each line and checks if vehicle has an entry in the hastable, * if so append append is called else a new linked list to the vehicle is created. * @param need mobility file to be given */ -void read_mobility_file(); // mobility file need to be given here, add in omg_param_list, get it from there +void parse_data (char *trace_file, int node_type); // mobility file need to be given here, add in omg_param_list, get it from there /** * function builds a linked list which holds vehicle id and its mapping pointer to @@ -105,23 +59,16 @@ void read_mobility_file(); // mobility file need to be given here, add in omg_pa * @param vid is the vehicle id * @param pointer to the head of the linked list to the vehicle entry in the hash table */ -node_info* build_node_info(node_info* headRef, int vid, int *vid_addr); +void add_node_info (int nid,int n_gid, int node_type); +int find_node_info (int vid, int node_type); /** * just counts the number of nodes in the mobility file */ -int get_num_nodes(); +int get_number_of_nodes (int node_type); + -/** - * these function are used since there might be a possibility if user provides a mobility - * discription which is out of order. - * @param hashtable - * @param starting pointer for the vehicles linked list - * @param ending pointer of the vehicles linked list - */ -void sort_veh_movement(omg_hash_table_t *table); -void quicksortlist(Exnode *pLeft, Exnode *pRight); /** * function returns the node containing next position (just reads the linked list from the hashtable) @@ -129,10 +76,8 @@ void quicksortlist(Exnode *pLeft, Exnode *pRight); * @param hashtable from which the node is to be looked * @param node_id is the nodes whose next location need to be retrieved from the linked list */ -Exnode* get_next_position(omg_hash_table_t *table,int node_id); +node_data* get_next_data (hash_table_t* table, int vid, int flag); -void reset_visit_status(omg_hash_table_t *table, float time, int node_id); -void clear_llist(); #endif /* MOBILITY_PARSER_H_ */ diff --git a/openair2/UTIL/OMG/omg.c b/openair2/UTIL/OMG/omg.c index dc22f1458321442d1d9c4bab4105e9cfef981eb3..1cca0b38fabdc67f0d79ef9ea11a1841bcc08537 100644 --- a/openair2/UTIL/OMG/omg.c +++ b/openair2/UTIL/OMG/omg.c @@ -29,8 +29,8 @@ /*! \file OMG.c * \brief Main function containing the OMG interface -* \author M. Mahersi, N. Nikaein, J. Harri -* \date 2011 +* \author S. Gashaw, N. Nikaein, J. Harri +* \date 2011 - 2014 * \version 0.1 * \company Eurecom * \email: @@ -51,738 +51,934 @@ #include "rwp.h" #include "rwalk.h" #include "trace.h" +#include "grid.h" +#include "steadystaterwp.h" #include "sumo.h" #include "../OMV/structures.h" //#define STANDALONE -int omv_write (int pfd, Node_list ue_node_list, Data_Flow_Unit omv_data); +float n_frames = 20.0; + +int omv_write (int pfd, node_list * ue_node_list, Data_Flow_Unit omv_data); void omv_end (int pfd, Data_Flow_Unit omv_data); int omv_enabled; -void init_omg_global_params(void){ //if we want to re initialize all - int i = 0; - Job_Vector_len=0; - Job_Vector = NULL; - for (i=0; i<MAX_NUM_MOB_TYPES; i++){ - Node_Vector[i] = NULL; - Node_Vector_len[i] = 0; - //Initial_Node_Vector_len[i] = 0; - } +/*initialze global parameters*/ +void +init_omg_global_params (void) +{ + int mob_t, node_t, i; + xloc_div = 10.0; + yloc_div = 10.0; + grid = 0; + for (mob_t = STATIC; mob_t < MAX_NUM_MOB_TYPES; mob_t++) + { + job_vector_len[mob_t] = 0; + job_vector[mob_t] = NULL; + job_vector_end[mob_t] = NULL; + } + + for (node_t = eNB; node_t < MAX_NUM_MOB_TYPES; node_t++) + { + node_vector[node_t] = NULL; + node_vector_end[node_t] = NULL; + node_vector_len[node_t] = 0; + } + for (i = 0; i < 100; i++) + { + event_sum[i] = 0; + events[i] = 0; + } } -// maybe remplace 'start_OMG(omg_global_param omg_param_list) -// of course, add 'stop_OMG(), which calls recursively -// stop_XX_generator(); -// -void init_mobility_generator(omg_global_param omg_param_list) { - switch (omg_param_list.mobility_type) { +/*initiate mobility generator*/ +void +init_mobility_generator (omg_global_param omg_param_list[]) +{ + int node_t, mobility_t; + + for (node_t = eNB; node_t < MAX_NUM_NODE_TYPES; node_t++) + { + + mobility_t = omg_param_list[node_t].mobility_type; + + switch (mobility_t) + { + + case STATIC: + start_static_generator (omg_param_list[node_t]); + break; + + case RWP: + start_rwp_generator (omg_param_list[node_t]); + break; + + case RWALK: + start_rwalk_generator (omg_param_list[node_t]); + break; + + case TRACE: + start_trace_generator (omg_param_list[node_t]); + break; + + case SUMO: + start_sumo_generator (omg_param_list[node_t]); + break; + + case STEADY_RWP: + start_steadystaterwp_generator (omg_param_list[node_t]); + break; + + default: + LOG_N (OMG, "Unsupported generator\n"); + } + + + } - case STATIC: - start_static_generator(omg_param_list); - break; - - case RWP: - start_rwp_generator(omg_param_list); - LOG_D(OMG," --------DISPLAY JOB LIST-------- \n"); - display_job_list(Job_Vector); - Job_Vector = quick_sort (Job_Vector); - LOG_D(OMG,"--------DISPLAY JOB LIST AFTER SORTING--------\n"); - display_job_list(Job_Vector); - break; - - case RWALK: - start_rwalk_generator(omg_param_list); - LOG_D(OMG," --------DISPLAY JOB LIST-------- \n"); - display_job_list(Job_Vector); - Job_Vector = quick_sort (Job_Vector); - LOG_D(OMG,"--------DISPLAY JOB LIST AFTER SORTING--------\n"); - display_job_list(Job_Vector); - break; - - case TRACE: - start_trace_generator(omg_param_list); - LOG_D(OMG," --------DISPLAY JOB LIST-------- \n"); - display_job_list(Job_Vector); - Job_Vector = quick_sort (Job_Vector); - LOG_D(OMG,"--------DISPLAY JOB LIST AFTER SORTING--------\n"); - display_job_list(Job_Vector); - LOG_D(OMG," --------OMG will load static mobility traces from user specified file-------- \n"); - - break; - - case SUMO: - start_sumo_generator(omg_param_list); - //LOG_D(OMG," --------OMG will interface with SUMO for mobility generation-------- \n"); - break; - - default: - LOG_N(OMG, "Unsupported generator %d \n", omg_param_list.mobility_type); - } } -void stop_mobility_generator(int mobility_type) { - switch (mobility_type) { - - case STATIC: - break; - case RWP: - break; - case RWALK: - break; - case TRACE: - clear_llist(); - break; - - case SUMO: - stop_sumo_generator(); - //LOG_D(OMG," --------OMG will interface with SUMO for mobility generation-------- \n"); - break; - - default: - LOG_N(OMG, "Unsupported generator %d \n", omg_param_list.mobility_type); - } +/**************************************************************************************/ +/*stop sumo mobiity generator*/ +void +stop_mobility_generator (omg_global_param * omg_param_list) +{ + int i; + for (i = 0; i < MAX_NUM_NODE_TYPES; i++) + { + switch (omg_param_list[i].mobility_type) + { + + case STATIC: + break; + case RWP: + break; + case RWALK: + break; + case TRACE: + clear_list (); + break; + case STEADY_RWP: + break; + case SUMO: + stop_sumo_generator (); + //LOG_D(OMG," --------OMG will interface with SUMO for mobility generation-------- \n"); + break; + + default: + LOG_N (OMG, "Unsupported generator\n"); + } + } + } -void update_nodes(double cur_time){ +/*****************************************************************************/ + +void +update_nodes (double cur_time) +{ //LOG_D(OMG, "UPDATE NODES" ); -int i = 0; -for (i=(STATIC+1); i<MAX_NUM_MOB_TYPES; i++){ - if (Node_Vector[i] != NULL){ - //printf(" Mob model to update is: %d \n ", i); - LOG_I(OMG, " Mob model to update is: %d \n ", i); - update_node_vector(i, cur_time); - } - } - + int i = 0; + for (i = (STATIC + 1); i < MAX_NUM_MOB_TYPES; i++) + { + if (job_vector[i] != NULL) + { + update_node_vector (i, cur_time); + } + } + } -void update_node_vector(int mobility_type, double cur_time){ +void +update_node_vector (int mobility_type, double cur_time) +{ //set_time(cur_time); - switch (mobility_type) { - case RWP: - update_rwp_nodes(cur_time); - break; - case RWALK: - update_rwalk_nodes(cur_time); - break; - case TRACE: - update_trace_nodes(cur_time); - break; - case SUMO: - // printf("in SUMO case \n"); - update_sumo_nodes(cur_time); - break; - - default: - //printf("STATIC or Unsupported generator %d \n", omg_param_list.mobility_type); - LOG_N(OMG, "STATIC or Unsupported generator %d \n", omg_param_list.mobility_type); - } -} - -Node_list get_current_positions(int mobility_type, int node_type, double cur_time){ - Node_list Vector = NULL; - if (Node_Vector[mobility_type] != NULL){ - switch (mobility_type) { - case STATIC: - Vector = (Node_list)Node_Vector[STATIC]; - LOG_T(OMG,"static vector %p is \n",Vector); - break; - case RWP: - get_rwp_positions_updated(cur_time); - Vector = Node_Vector[RWP]; + switch (mobility_type) + { + case RWP: + update_rwp_nodes (cur_time); break; case RWALK: - get_rwalk_positions_updated(cur_time); - Vector = Node_Vector[RWALK]; + update_rwalk_nodes (cur_time); break; case TRACE: - get_trace_positions_updated(cur_time); - Vector = Node_Vector[TRACE]; - break; + update_trace_nodes (cur_time); + break; case SUMO: - LOG_I(OMG,"getting positions from SUMO\n"); - //printf("getting positions from SUMO\n"); - Vector = get_sumo_positions_updated(cur_time); - // Vector = Node_Vector[SUMO]; + // printf("in SUMO case \n"); + update_sumo_nodes (cur_time); + break; + case STEADY_RWP: + update_steadystaterwp_nodes (cur_time); break; - default: - Vector = NULL; - LOG_N(OMG, " Unsupported generator %c \n", omg_param_list.mobility_type); + //printf("STATIC or Unsupported generator %d \n", omg_param_list.mobility_type); + LOG_N (OMG, "STATIC or Unsupported generator\n"); } - if (node_type != ALL){ - Vector = filter(Vector, node_type); - } - return Vector; - } - else { - LOG_T( OMG, " No node of mobility type %d is available \n", mobility_type); - return NULL; - } } +/*********************************************************************************/ -// get the position for a specific node -NodePtr get_node_position(int node_type, int nID){ - int found = 0; //not found - int i=0; - while ((i<MAX_NUM_MOB_TYPES) && (found == 0)){ - if (Node_Vector[i] != NULL){ - Node_list tmp = Node_Vector[i]; - while ((tmp != NULL) && (found == 0)){ - if ((tmp->node->ID == nID) && (tmp->node->type == node_type)) { - LOG_T(OMG, "found a node vector %d node id %d with type %d\n",i, tmp->node->ID, tmp->node->type); - found = 1; //found - display_node_position(tmp->node->ID, tmp->node->generator, tmp->node->type ,tmp->node->mobile, tmp->node->X_pos, tmp->node->Y_pos ); - return tmp->node; - } - tmp = tmp->next; - } - } - i++; - } - if (found == 0 ){ - LOG_N(OMG, "Node does not exist\n"); - } - return NULL; +/*return updated node position for a given node type*/ +node_list * +get_current_positions (int mobility_type, int node_type, double cur_time) +{ + + + get_nodes_positions (mobility_type, cur_time); + return node_vector[node_type]; + } -/*NodePtr get_node_position(int mobility_type, int node_type, int nID){ - if (Node_Vector[mobility_type] != NULL){ - Node_list Vector = NULL; - int done =1; - switch (mobility_type) { - case RWP: - Vector = Node_Vector[RWP]; +/*update current position of nodes for specific mobility type*/ +void +get_nodes_positions (int mobility_type, double cur_time) +{ + //printf("%d \n",mobility_type); + + switch (mobility_type) + { + case STATIC: break; - case STATIC: - Vector = Node_Vector[STATIC]; + case RWP: + get_rwp_positions_updated (cur_time); break; case RWALK: - Vector = Node_Vector[RWALK]; + get_rwalk_positions_updated (cur_time); + break; + case TRACE: + get_trace_positions_updated (cur_time); + break; + case SUMO: + LOG_I (OMG, "getting positions from SUMO\n"); + get_sumo_positions_updated (cur_time); + break; + case STEADY_RWP: + get_steadystaterwp_positions_updated (cur_time); break; default: - Vector = NULL; - LOG_E(OMG, "Static or Unsupported generator %c \n", omg_param_list.mobility_type); + LOG_E (OMG, " Unsupported generator \n"); } - if (Vector == NULL){ - LOG_D(OMG, "\n Vector == NULL"); - } - while (Vector != NULL){ - if (Vector->node->ID == nID && Vector->node->type == node_type){ - done =0; - - display_node_position(Vector->node->ID, Vector->node->generator, Vector->node->type ,Vector->node->mobile, Vector->node->X_pos, Vector->node->Y_pos ); - // LOG_I(OMG, "Node number %d is in position: (%.2f, %.2f) with mobility_type: %d\n",Vector->node->ID,Vector->node->X_pos,Vector->node->Y_pos,Vector->node->mobile); - return Vector->node; - } - Vector = Vector->next; + +} + +/***************************************************************/ + +// get the position for a specific node + +node_struct * +get_node_position (int node_type, int nid) +{ + node_list *tmp; + + tmp = node_vector[node_type]; + while (tmp != NULL) + { + if (tmp->node->id == nid) + return tmp->node; + tmp = tmp->next; } - if (done!= 0 ){LOG_N(OMG, "Node does not exist\n");} - return NULL; - } - else { - LOG_N( OMG, "No node of mobility type %d is available \n", mobility_type); + return NULL; - } -}*/ - - - -void set_new_mob_type(int nID, int node_type, int new_mob, double cur_time){ - double first_Job_time; - int err = 999; - int i = STATIC; - int old_mob = err; - int found = 0; //not found - while ((i<MAX_NUM_MOB_TYPES) && (found == 0)){ - if (Node_Vector[i] != NULL){ - Node_list tmp = Node_Vector[i]; - while ((tmp != NULL) && (found == 0)){ - if ((tmp->node->ID == nID) && (tmp->node->type == node_type)) { - found = 1; //found - old_mob = i; - LOG_D( OMG,"old mob %d\n", old_mob ); //LOG_N - if (old_mob == new_mob){ - LOG_D(OMG, "Nothing to change (%d == %d)\n",old_mob, new_mob); - return; - } - else { - LOG_D(OMG,"Node_Vector[%d] != NULL\n", old_mob); - //int done = 1; - //Node_list Vector = Node_Vector[old_mob]; - //NodePtr nd = NULL; - NodePtr nd = tmp->node; - if (new_mob == STATIC) { //OKEY // remove from Job_Vector - LOG_D(OMG, "new_mob == STATIC\n"); - nd->mobile = 0; - nd->mob->speed = 0.0; - - nd->mob->X_from = nd->X_pos; - nd->mob->Y_from = nd->Y_pos; - nd->mob->X_to = nd->X_pos; - nd->mob->Y_to = nd->Y_pos; - //nd->X_pos = nd->mob->X_to; - //nd->Y_pos = nd->mob->Y_to; - LOG_D(OMG, "Before remove"); - display_job_list( Job_Vector); - - if (Job_Vector != NULL){ - Job_Vector = remove_job(Job_Vector, nID, node_type); //nd->ID - //LOG_D(OMG, "After remove\n"); - Job_Vector_len--; - LOG_D(OMG, "After remove\n"); - display_job_list( Job_Vector); - } - else { - LOG_E(OMG, "ERROR, Job_Vector == NULL while there are mobile nodes"); - } - } - - Node_Vector[old_mob] = remove_node(Node_Vector[old_mob], nID, node_type); - Node_Vector_len[old_mob]--; - nd->ID = nID; //Node_Vector_len[new_mob]; - LOG_D(OMG, "Node_Vector_len[new_mob] %d\n", Node_Vector_len[new_mob]); - LOG_D(OMG, "nd->ID %d\n", nd->ID); - nd->generator = new_mob; // ---> it is changed in Job_Vector if new_mob is RWP or RWALK - - Node_Vector[new_mob] = add_entry(nd, Node_Vector[new_mob]); - Node_Vector_len[new_mob]++; - - if (old_mob == STATIC){ // add to Job_Vector , start by sleeping - LOG_D(OMG, "old_mob == STATIC\n"); - - if(Job_Vector == NULL){ - LOG_D(OMG, "Job_Vector == NULL\n"); - first_Job_time = cur_time; - } - else { - LOG_D(OMG, "Job_Vector != NULL\n"); - first_Job_time = Job_Vector->pair->a; - } - - LOG_D(OMG, "------------------------------------------------------------- first_Job_time %f\n", first_Job_time); - Pair pair = malloc(sizeof(Pair)) ; - - nd->mob->sleep_duration = (double) ((int) (randomGen(omg_param_list.min_sleep, omg_param_list.max_sleep)*100))/ 100; - LOG_D(OMG, "node: %d \tsleep duration : %.2f\n",nd->ID, nd->mob->sleep_duration); - pair->a = first_Job_time + 1 + nd->mob->sleep_duration; //when to wake up ???? - LOG_D(OMG, "to wake up at time: cur_time + sleep_duration : %.2f\n", pair->a); - - pair->b = nd; - Job_Vector = add_job(pair, Job_Vector); - Job_Vector_len++; - } - LOG_D(OMG," --------DISPLAY JOB LIST-------- \n"); - display_job_list(Job_Vector); - Job_Vector = quick_sort (Job_Vector); - LOG_D(OMG,"--------DISPLAY JOB LIST AFTER SORTING--------\n"); - display_job_list(Job_Vector); - - - LOG_D(OMG, "--------display Node_Vector[new_mob]--------\n"); - display_node_list(Node_Vector[new_mob]); - LOG_D(OMG, "--------display Node_Vector[old_mob]--------\n"); - display_node_list(Node_Vector[old_mob]); - return; - } - } - tmp = tmp->next; - } - } - i++; - } } -/*// openair emu will set this valut as a function of frame number -void set_time(double time) { - m_time = time; -} -double get_time() { - return m_time; -}*/ +/*set new mobility for a node*/ +void +set_new_mob_type (int id, int node_t, int mob_t, double cur_time) +{ + + int prev_mob; + node_list *tmp; + job_list *tmp2, *prev_job; + pair_struct *pair; + double pause_p; + +//find previous mobility type + tmp = node_vector[node_t]; + while (tmp != NULL) + { + if (tmp->node->id == id && tmp->node->type == node_t) + { + prev_mob = tmp->node->generator; + break; + } + tmp = tmp->next; + } + +//end + + if (tmp != NULL && prev_mob != mob_t) + { + +//initialize node position + if (mob_t == STATIC || mob_t == RWP || mob_t == RWALK || mob_t == STEADY_RWP) + { + tmp->node->x_pos = + (double) ((int) + (randomgen + (omg_param_list[node_t].min_x, + omg_param_list[node_t].max_x) * 100)) / 100; + tmp->node->mob->x_from = tmp->node->x_pos; + tmp->node->mob->x_to = tmp->node->x_pos; + tmp->node->y_pos = + (double) ((int) + (randomgen + (omg_param_list[node_t].min_y, + omg_param_list[node_t].max_y) * 100)) / 100; + tmp->node->mob->y_from = tmp->node->y_pos; + tmp->node->mob->y_to = tmp->node->y_pos; + tmp->node->mob->speed = 0.0; + tmp->node->generator = mob_t; + if (prev_mob != STATIC) + job_vector[prev_mob] = + remove_job (job_vector[prev_mob], id, node_t); + } + +//end + + switch (mob_t) + { + + case STATIC: + + break; + + case RWP: + pair = (pair_struct *) malloc (sizeof (struct pair_struct)); + pair->b = tmp->node; + sleep_rwp_node (pair, cur_time); + job_vector[RWP] = addjob (pair, job_vector[RWP]); + break; + + case RWALK: + pair = (pair_struct *) malloc (sizeof (struct pair_struct)); + pair->b = tmp->node; + sleep_rwalk_node (pair, cur_time); + job_vector[RWALK] = addjob (pair, job_vector[RWALK]); + break; + + case STEADY_RWP: + tmp->node->event_num = 0; + pair = (pair_struct *) malloc (sizeof (struct pair_struct)); + pair->b = tmp->node; + pause_p = pause_probability (omg_param_list[node_t]); + if (randomgen (0, 1) < pause_p) + sleep_steadystaterwp_node (pair, cur_time); + else + move_steadystaterwp_node (pair, cur_time); + break; + + case SUMO: + LOG_E (OMG, "not possible to change mobility type to sumo \n"); + break; + + case TRACE: + LOG_E (OMG, "not possible to change mobility type to trace \n"); + break; + + default: + LOG_E (OMG, " Unsupported generator \n"); + } + + } + + +} #ifdef STANDALONE -void usage(void){ - fprintf(stderr, "\n\t-X: assign maximum width of the simulation area (X_max)"\ - "\n\t-x: assign minimum width of the simulation area (X_min)"\ - "\n\t-Y: assign maximum height of the simulation area (Y_max)"\ - "\n\t-y: assign minimum height of the simulation area (Y_min)"\ - "\n\t-N: assign number of nodes"\ - "\n\t-n: assign number of frames" \ - "\n\t-B: assign maximum duration of sleep/pause time (max_break)" - "\n\t-b: assign minimum duration of sleep/pause time (min_break)"\ - "\n\t-J: assign maximum duration of journey (max_journey_time)"\ - "\n\t-j: assign minimum duration of journey (min_journey_time)"\ - "\n\t-S: assign maximum speed "\ - "\n\t-s: assign minimum speed"\ - "\n\t-g: choose generator (STATIC: 0x00, RWP: 0x01, RWALK: 0x02, TRACE: 0x03 or SUMO: 0x04)\n"\ - "\n\t-e: choose seed \n"\ - ); - exit(0); + +/************************** get options ************************************/ +void +usage (void) +{ + fprintf (stderr, + "\n\t-X: assign maximum width of the simulation area for UE nodes(X_max)" + "\n\t-x: assign minimum width of the simulation area for UE nodes(X_min)" + "\n\t-C: assign maximum width of the simulation area for eNB nodes(X_max)" + "\n\t-c: assign minimum width of the simulation area for eNB nodes(X_min)" + "\n\t-B: assign maximum width of the simulation area for relay nodes(X_max)" + "\n\t-b: assign minimum width of the simulation area for relay nodes(X_min)" + "\n\t-Y: assign maximum height of the simulation area for UE nodes(Y_max)" + "\n\t-y: assign minimum height of the simulation area for UE nodes (Y_min)" + "\n\t-Z: assign maximum height of the simulation area for eNB nodes(Y_max)" + "\n\t-z: assign minimum height of the simulation area for eNB nodes(Y_min)" + "\n\t-W: assign maximum height of the simulation area for relay nodes(Y_max)" + "\n\t-w: assign minimum height of the simulation area for relay nodes(Y_min)" + //"\n\t-N: assign number of nodes" "\n\t-n: assign number of frames" + "\n\t-S: assign maximum duration of sleep/pause time for UE nodes(max_break)" + "\n\t-s: assign minimum duration of sleep/pause time for UE nodes(min_break)" + "\n\t-L: assign maximum duration of sleep/pause time for eNB nodes(max_break)" + "\n\t-l: assign minimum duration of sleep/pause time for eNB nodes(min_break)" + "\n\t-P: assign maximum duration of sleep/pause time for relay nodes(max_break)" + "\n\t-p: assign minimum duration of sleep/pause time for relay nodes(min_break)" + "\n\t-J: assign maximum duration of journey for UE nodes(max_journey_time)" + "\n\t-j: assign minimum duration of journey for UE nodes(min_journey_time)" + "\n\t-J: assign maximum duration of journey for eNB nodes(max_journey_time)" + "\n\t-j: assign minimum duration of journey for eNB nodes(min_journey_time)" + "\n\t-J: assign maximum duration of journey for relay nodes(max_journey_time)" + "\n\t-j: assign minimum duration of journey for relay nodes(min_journey_time)" + "\n\t-D: assign maximum speed for UE nodes" + "\n\t-d: assign minimum speed for UE nodes" + "\n\t-I: assign maximum speed for eNB nodes" + "\n\t-i: assign minimum speed for eNB nodes" + "\n\t-A: assign maximum speed for relay nodes" + "\n\t-a: assign minimum speed for relay nodes" + //"\n\t-g: choose generator(STATIC: 0x00, RWP: 0x01, RWALK: 0x02,TRACE: 0x03 or SUMO:0x04, STEADY_RWP:0x05)\n" + "\n\t-g: choose to use map for random mobility" "\n\t-h: help" + "\n\t-U: specifiy number of UE nodes" + "\n\t-E: specifiy number of eNB nodes" + "\n\t-R: specifiy number of relay nodes" + "\n\t-u: choose mobility generator for UE nodes" + "\n\t-e: choose mobility generator for eNB nodes" + "\n\t-r: choose mobility generator for relay nodes" + "\n\t-f: choose seed \n"); + exit (0); } -float n_frames=200.0; -int get_options(int argc, char *argv[]){ - char tag; - while ((tag = getopt(argc, argv, "vj:J:g:B:b:S:s:Y:y:X:x:n:N:he:t:")) != EOF) { - - - switch (tag) { - - case 'N': - omg_param_list.nodes = atoi(optarg); - LOG_D(OMG, "Number of nodes : %d \n",omg_param_list.nodes); - break; - case 'n': - n_frames = atof(optarg); - LOG_D(OMG, "Number of frames : %f \n",n_frames ); - break; - case 't': - omg_param_list.nodes_type = atoi(optarg); - LOG_D(OMG, "Type of nodes : %d \n",omg_param_list.nodes_type); - break; - case 'b': - omg_param_list.min_sleep = atof(optarg); - LOG_D(OMG, "min sleep : %.2f \n",omg_param_list.min_sleep); - break; - - case 'B': - omg_param_list.max_sleep = atof(optarg); - LOG_D(OMG, "max_sleep : %.2f \n",omg_param_list.max_sleep); - break; - - case 's': - omg_param_list.min_speed = atof(optarg); - LOG_D(OMG, "min_speed : %.2f \n",omg_param_list.min_speed); - break; - - case 'S': - omg_param_list.max_speed = atof(optarg); - LOG_D(OMG, "max_speed : %.2f \n",omg_param_list.max_speed); - break; - case 'v': - omv_enabled = 1; - break; - case 'X': - omg_param_list.max_X = atof(optarg); - LOG_D(OMG, "X_max : %.2f \n",omg_param_list.max_X); - break; - case 'x': - omg_param_list.min_X = atof(optarg); - LOG_D(OMG, "X_min : %.2f \n",omg_param_list.min_X); - break; - - case 'Y': - omg_param_list.max_Y = atof(optarg); - LOG_D(OMG, "Y_max : %.2f \n",omg_param_list.max_Y); - break; - - case 'y': - omg_param_list.min_Y = atof(optarg); - LOG_D(OMG, "Y_min : %.2f \n",omg_param_list.min_Y); - break; - - case 'J': - omg_param_list.max_journey_time = atof(optarg); - LOG_D(OMG, "Journey_time_max : %.2f \n",omg_param_list.max_journey_time); - break; - - - case 'j': - omg_param_list.min_journey_time = atof(optarg); - LOG_D(OMG, "Journey_time_min : %.2f \n",omg_param_list.min_journey_time); - break; - - - case 'g': - omg_param_list.mobility_type = atoi(optarg); - LOG_D(OMG, "Mobility type is %d \n",omg_param_list.mobility_type); - break; - - case 'e': - omg_param_list.seed = atoi(optarg); - LOG_D(OMG, "Seed is %d \n",omg_param_list.seed ); - break; - case 'h': - usage(); - break; - - default: - usage(); - exit(1); - } + + + +int +get_options (int argc, char *argv[]) +{ + int node_t; + char tag; + while ((tag = + getopt (argc, argv, + "U:u:E:e:R:r:A:a:B:b:C:c:D:d:f:g:hI:i:J:j:k:L:l:N:n:P:p:S:s:T:t:vW:w:X:x:Y:y:Z:z:")) + != EOF) + { + + + switch (tag) + { + + case 'U': + if (atoi (optarg) < 0) + { + usage (); + exit (1); + } + omg_param_list[UE].nodes = atoi (optarg); + LOG_D (OMG, "#Number of UE nodes : %d \n", + omg_param_list[UE].nodes); + break; + + case 'E': + if (atoi (optarg) < 0) + { + usage (); + exit (1); + } + omg_param_list[eNB].nodes = atoi (optarg); + LOG_D (OMG, "#Number of eNB nodes : %d \n", + omg_param_list[eNB].nodes); + break; + + case 'R': + if (atoi (optarg) < 0) + { + usage (); + exit (1); + } + omg_param_list[RELAY].nodes = atoi (optarg); + LOG_D (OMG, "#Number of relay nodes : %d \n", + omg_param_list[RELAY].nodes); + break; + + case 'k': + if (atof (optarg) < 0) + LOG_E (OMG, "#Number of frames can not be negative \n"); + n_frames = abs (atof (optarg)); + LOG_D (OMG, "#Number of frames : %f \n", n_frames); + break; + + case 'u': + if (atoi (optarg) < 0 || atoi (optarg) >= MAX_NUM_MOB_TYPES) + { + usage (); + exit (1); + } + omg_param_list[UE].mobility_type = atoi (optarg); + LOG_D (OMG, "#UE nodes mobility type: %d \n", + omg_param_list[UE].mobility_type); + break; + + case 'e': + if (atoi (optarg) < 0 || atoi (optarg) >= MAX_NUM_MOB_TYPES) + { + usage (); + exit (1); + } + omg_param_list[eNB].mobility_type = atoi (optarg); + LOG_D (OMG, "#eNB nodes mobility type: %d \n", + omg_param_list[eNB].mobility_type); + break; + + case 'r': + if (atoi (optarg) < 0 || atoi (optarg) >= MAX_NUM_MOB_TYPES) + { + usage (); + exit (1); + } + omg_param_list[RELAY].mobility_type = atoi (optarg); + LOG_D (OMG, "#relay nodes mobility type: %d \n", + omg_param_list[RELAY].mobility_type); + break; + + case 's': + if (atof (optarg) < 0) + LOG_E (OMG, "#min sleep can not be negative \n"); + omg_param_list[UE].min_sleep = fabs (atof (optarg)); + LOG_D (OMG, "#UE min sleep is set to: %.2f \n", + omg_param_list[UE].min_sleep); + break; + + case 'S': + if (atof (optarg) < 0) + LOG_E (OMG, "#max_sleep can not be negative \n"); + omg_param_list[UE].max_sleep = fabs (atof (optarg)); + LOG_D (OMG, "#UE max_sleep is set to : %.2f \n", + omg_param_list[UE].max_sleep); + break; + + case 'l': + if (atof (optarg) < 0) + LOG_E (OMG, "#min sleep can not be negative or zero \n"); + if (atof (optarg) != 0) + omg_param_list[eNB].min_sleep = fabs (atof (optarg)); + LOG_D (OMG, "#eNB min sleep is set to : %.2f \n", + omg_param_list[eNB].min_sleep); + break; + + case 'L': + if (atof (optarg) <= 0) + LOG_E (OMG, "#max_sleep can not be negative or zero \n"); + if (atof (optarg) != 0) + omg_param_list[eNB].max_sleep = fabs (atof (optarg)); + LOG_D (OMG, "#eNB max_sleep is set to : %.2f \n", + omg_param_list[eNB].max_sleep); + break; + + case 'p': + if (atof (optarg) < 0) + LOG_E (OMG, "#min sleep can not be negative \n"); + omg_param_list[RELAY].min_sleep = fabs (atof (optarg)); + LOG_D (OMG, "#relay min sleep is set to: %.2f \n", + omg_param_list[RELAY].min_sleep); + break; + + case 'P': + if (atof (optarg) < 0) + LOG_E (OMG, "#max_sleep can not be negative \n"); + omg_param_list[RELAY].max_sleep = fabs (atof (optarg)); + LOG_D (OMG, "#relay max_sleep is set to : %.2f \n", + omg_param_list[RELAY].max_sleep); + break; + + case 'd': + if (atof (optarg) < 0) + LOG_E (OMG, "#min_speed can not be negative \n"); + if (atof (optarg) != 0) + omg_param_list[UE].min_speed = fabs (atof (optarg)); + LOG_D (OMG, "#UE min_speed is set to: %.2f \n", + omg_param_list[UE].min_speed); + break; + + case 'D': + if (atof (optarg) < 0) + LOG_E (OMG, "#max_speed can not be negative \n"); + omg_param_list[UE].max_speed = fabs (atof (optarg)); + LOG_D (OMG, "#UE max_speed is set to: %.2f \n", + omg_param_list[UE].max_speed); + break; + + case 'i': + if (atof (optarg) < 0) + LOG_E (OMG, "#min_speed can not be negative \n"); + if (atof (optarg) != 0) + omg_param_list[eNB].min_speed = fabs (atof (optarg)); + LOG_D (OMG, "#eNB min_speed is set to: %.2f \n", + omg_param_list[eNB].min_speed); + break; + + case 'I': + if (atof (optarg) < 0) + LOG_E (OMG, "#max_speed can not be negative \n"); + omg_param_list[eNB].max_speed = fabs (atof (optarg)); + LOG_D (OMG, "#eNB max_speed is set to : %.2f \n", + omg_param_list[eNB].max_speed); + break; + + case 'a': + if (atof (optarg) < 0) + LOG_E (OMG, "#min_speed can not be negative \n"); + if (atof (optarg) != 0) + omg_param_list[RELAY].min_speed = fabs (atof (optarg)); + LOG_D (OMG, "#relay min_speed is set to : %.2f \n", + omg_param_list[RELAY].min_speed); + break; + + case 'A': + if (atof (optarg) < 0) + LOG_E (OMG, "#max_speed can not be negative \n"); + omg_param_list[RELAY].max_speed = fabs (atof (optarg)); + LOG_D (OMG, "#relay max_speed is set to: %.2f \n", + omg_param_list[RELAY].max_speed); + break; + + case 'v': + omv_enabled = 1; + break; + + case 'X': + omg_param_list[UE].max_x = fabs (atof (optarg)); + LOG_D (OMG, "#UE X_max : %.2f \n", omg_param_list[UE].max_x); + break; + + case 'x': + omg_param_list[UE].min_x = fabs (atof (optarg)); + LOG_D (OMG, "#UE X_min : %.2f \n", omg_param_list[UE].min_x); + break; + + case 'C': + omg_param_list[eNB].max_x = fabs (atof (optarg)); + LOG_D (OMG, "#eNB X_max : %.2f \n", omg_param_list[eNB].max_x); + break; + + case 'c': + omg_param_list[eNB].min_x = fabs (atof (optarg)); + LOG_D (OMG, "#eNB X_min : %.2f \n", omg_param_list[eNB].min_x); + break; + + case 'B': + omg_param_list[RELAY].max_x = fabs (atof (optarg)); + LOG_D (OMG, "#relay X_max : %.2f \n", omg_param_list[RELAY].max_x); + break; + + case 'b': + omg_param_list[RELAY].min_x = fabs (atof (optarg)); + LOG_D (OMG, "#relay X_min : %.2f \n", omg_param_list[RELAY].min_x); + break; + + case 'Y': + omg_param_list[UE].max_y = fabs (atof (optarg)); + LOG_D (OMG, "#UE Y_max : %.2f \n", omg_param_list[UE].max_y); + break; + + case 'y': + omg_param_list[UE].min_y = fabs (atof (optarg)); + LOG_D (OMG, "#UE Y_min : %.2f \n", omg_param_list[UE].min_y); + break; + + case 'Z': + omg_param_list[eNB].max_y = fabs (atof (optarg)); + LOG_D (OMG, "#eNB Y_max : %.2f \n", omg_param_list[eNB].max_y); + break; + + case 'z': + omg_param_list[eNB].min_y = fabs (atof (optarg)); + LOG_D (OMG, "#eNB Y_min : %.2f \n", omg_param_list[eNB].min_y); + break; + + case 'W': + omg_param_list[RELAY].max_y = fabs (atof (optarg)); + LOG_D (OMG, "#relay Y_max : %.2f \n", omg_param_list[RELAY].max_y); + break; + + case 'w': + omg_param_list[RELAY].min_y = fabs (atof (optarg)); + LOG_D (OMG, "#relay Y_min : %.2f \n", omg_param_list[RELAY].min_y); + break; + + case 'J': + if (atof (optarg) < 0) + LOG_E (OMG, "#Journey_time_max can not be negative \n"); + omg_param_list[UE].max_journey_time = fabs (atof (optarg)); + LOG_D (OMG, "UE Journey_time_max : %.2f \n", + omg_param_list[UE].max_journey_time); + break; + + case 'j': + if (atof (optarg) < 0) + LOG_E (OMG, "#Journey_time_min can not be negative \n"); + omg_param_list[UE].min_journey_time = fabs (atof (optarg)); + LOG_D (OMG, "#UE Journey_time_min : %.2f \n", + omg_param_list[UE].min_journey_time); + break; + + case 'T': + if (atof (optarg) < 0) + LOG_E (OMG, "#Journey_time_max can not be negative \n"); + omg_param_list[eNB].max_journey_time = fabs (atof (optarg)); + LOG_D (OMG, "#eNB Journey_time_max : %.2f \n", + omg_param_list[eNB].max_journey_time); + break; + + case 't': + if (atof (optarg) < 0) + LOG_E (OMG, "#Journey_time_min can not be negative \n"); + omg_param_list[eNB].min_journey_time = fabs (atof (optarg)); + LOG_D (OMG, "#eNB Journey_time_min : %.2f \n", + omg_param_list[eNB].min_journey_time); + break; + + case 'N': + if (atof (optarg) < 0) + LOG_E (OMG, "#Journey_time_max can not be negative \n"); + omg_param_list[RELAY].max_journey_time = fabs (atof (optarg)); + LOG_D (OMG, "#relay Journey_time_max : %.2f \n", + omg_param_list[RELAY].max_journey_time); + break; + + case 'n': + if (atof (optarg) < 0) + LOG_E (OMG, "#Journey_time_min can not be negative \n"); + omg_param_list[RELAY].min_journey_time = fabs (atof (optarg)); + LOG_D (OMG, "#relay Journey_time_min : %.2f \n", + omg_param_list[RELAY].min_journey_time); + break; + + case 'f': + for (node_t = eNB; node_t < MAX_NUM_NODE_TYPES; node_t++) + { + omg_param_list[node_t].seed = atoi (optarg); + LOG_D (OMG, "#Seed is %d \n", omg_param_list[node_t].seed); + } + break; + case 'g': + if (atoi (optarg) < 1 || atoi (optarg) > 2) + { + LOG_E (OMG, "#value given for graph should be 1 or 2 \n"); + exit (-1); + } + grid = abs (atof (optarg)); + LOG_D (OMG, "#graph value is %d \n", grid); + break; + case 'h': + usage (); + break; + + default: + usage (); + exit (1); } - return 0; + } + return 1; } -int main(int argc, char *argv[]) { - int i; - double cur_time=0.0; - //srand(time(NULL)); - double ms=0.0; - Node_list Current_positions = NULL; - NodePtr my_node = NULL; - int my_ID = 0; - double emu_info_time; - //omv - char full_name[200]; - int pfd[2]; // fd for omv : fixme: this could be a local var +/**************************** main **********************************/ + +int +main (int argc, char *argv[]) +{ + int i, node_type; + double cur_time = 0.0; + double ms = 0.0; + node_list *current_positions = NULL; + node_struct *my_node = NULL; + int my_id = 0, time_s; + double emu_info_time; + char full_name[200]; + int pfd[2]; // fd for omv : fixme: this could be a local var char fdstr[10]; char frames[10]; char num_enb[10]; char num_ue[10]; //area_x, area_y and area_z for omv char x_area[20]; - char y_area[20]; + char y_area[20]; char z_area[20]; - char fname[64],vname[64]; - Data_Flow_Unit omv_data ; - //float n_frames=200.0; - omg_param_list.nodes = 200; - omg_param_list.min_X = 0; - omg_param_list.max_X = 1000; - omg_param_list.min_Y = 0; - omg_param_list.max_Y = 1000; - omg_param_list.min_speed = 0.1; - omg_param_list.max_speed = 20.0; - omg_param_list.min_journey_time = 0.1; - omg_param_list.max_journey_time = 10.0; - omg_param_list.min_azimuth = 0; - omg_param_list.max_azimuth = 360; - omg_param_list.min_sleep = 0.1; - omg_param_list.max_sleep = 5.0; - omg_param_list.mobility_file = "TRACE/example_trace.tr"; - omg_param_list.sumo_command = "sumo-gui"; - omg_param_list.sumo_config = "SUMO/SCENARIOS/traci.scen.sumo.cfg"; - // omg_param_list.sumo_config = "SUMO/SCENARIOS/traci.koln.sumo.cfg"; - omg_param_list.sumo_start = 0;//25900; - omg_param_list.sumo_end = 200;//26200; - omg_param_list.sumo_step = 1; - omg_param_list.sumo_host = "localhost"; - omg_param_list.sumo_port = 8890; - omg_param_list.mobility_type = STATIC; - omg_param_list.nodes_type = UE; - // overwrite the default params if defined - get_options(argc, argv); - - // check if we are out of range - if(omg_param_list.max_X == 0.0 || omg_param_list.max_Y == 0.0 ) { - usage(); - exit(1); - } + char fname[64], vname[64]; + Data_Flow_Unit omv_data; + +//default parameters + for (node_type = eNB; node_type < MAX_NUM_NODE_TYPES; node_type++) + { + + + if (node_type == UE) + omg_param_list[node_type].nodes = 5; + else + omg_param_list[node_type].nodes = 0; + omg_param_list[node_type].min_x = 0; + omg_param_list[node_type].max_x = 100; + omg_param_list[node_type].min_y = 0; + omg_param_list[node_type].max_y = 100; + omg_param_list[node_type].min_speed = 0.1; + omg_param_list[node_type].max_speed = 20.0; + omg_param_list[node_type].min_journey_time = 0.1; + omg_param_list[node_type].max_journey_time = 20.0; + omg_param_list[node_type].min_azimuth = 0; + omg_param_list[node_type].max_azimuth = 360; + omg_param_list[node_type].min_sleep = 0.1; + omg_param_list[node_type].max_sleep = 5.0; + omg_param_list[node_type].mobility_file = "TRACE/mobility_3ues.tr"; + omg_param_list[node_type].mobility_type = STATIC; + omg_param_list[node_type].nodes_type = node_type; + //omg_param_list.sumo_config = "SUMO/SCENARIOS/traci.koln.sumo.cfg"; + omg_param_list[node_type].sumo_command = "sumo-gui"; + omg_param_list[node_type].sumo_config = + "SUMO/SCENARIOS/traci.scen.sumo.cfg"; + omg_param_list[node_type].sumo_start = 0; //25900; + omg_param_list[node_type].sumo_end = 200; //26200; + omg_param_list[node_type].sumo_step = 1; + omg_param_list[node_type].sumo_host = "localhost"; + omg_param_list[node_type].sumo_port = 8890; + } - -//char sumo_line[300]; + init_omg_global_params (); //initialize global paramaters -//printf("TEST %s \n", sumo_line); + get_options (argc, argv); // overwrite the default params if any input parameter -// sprintf(sumo_line, "%s -c %s -b %d -e %d --remote-port %d --step-length %d -v ",omg_param_list.sumo_command, omg_param_list.sumo_config, omg_param_list.sumo_start, omg_param_list.sumo_end, omg_param_list.sumo_port, omg_param_list.sumo_step); - -//printf("%s \n",sumo_line); + for (node_type = eNB; node_type < MAX_NUM_NODE_TYPES; node_type++) + { + omg_param_list[node_type].max_vertices = + max_vertices_ongrid (omg_param_list[node_type]); -//pid_t pid; -//pid_t cpid; - // char *sumo_arg[] = { omg_param_list.sumo_command, sumo_line, NULL }; -//char *sumo_arg[] = { "ls -la", NULL }; -// char *sumo_env[] = { NULL }; + omg_param_list[node_type].max_block_num = + max_connecteddomains_ongrid (omg_param_list[node_type]); -//printf("%s \n",omg_param_list.sumo_command); + } - //execve("ls -la",sumo_arg, sumo_env); - //execve(omg_param_list.sumo_command, sumo_arg, sumo_env); - //exec(omg_param_list.sumo_command); -// if ( (pid = fork()) == 0) -// { - // Start SUMO in the child process - //execve(omg_param_list.sumo_command, sumo_arg, sumo_env);// starts SUMO in a child proces -// system("sumo-gui"); - - //childs addresss space -// } -//printf("%d \n",pid); -//pid++; -//pid++; -//printf("%d \n",pid); -//printf("%d \n",cpid); + init_mobility_generator (omg_param_list); //initialize choosen mobility generator -//char kill_line[300]; + // ****************init omv******************** + if (omv_enabled == 1) + { + if (pipe (pfd) == -1) + perror ("pipe error \n"); -//printf("TEST %s \n", sumo_line); + sprintf (full_name, "%s/UTIL/OMV/OMV", getenv ("OPENAIR2_DIR")); + LOG_I (EMU, "Stating the OMV path %s pfd[0] %d pfd[1] %d \n", full_name, + pfd[0], pfd[1]); -//sprintf(kill_line, "kill(%d)",cpid); - -//printf("%s \n",kill_line); -//system(kill_line); - init_omg_global_params(); //initialization de Node_Vector et Job_Vector - init_mobility_generator(omg_param_list); // initial positions + sleep /// need to indicate time of initialization - //LOG_I(OMG, "*****DISPLAY NODE LIST********\n"); - //display_node_list(Node_Vector[0]); - - /*LOG_T(OMG, "********DISPLAY JOB LIST********\n"); - display_job_list(Job_Vector); - Job_Vector = quick_sort (Job_Vector); - LOG_T(OMG, "**********DISPLAY JOB LIST AFTER SORTING**********\n"); - display_job_list(Job_Vector); -*/ - // omg_param_list.mobility_type = RWP; - // omg_param_list.nodes_type = UE; - // init_mobility_generator(omg_param_list); // initial positions + sleep /// need to indicate time of initialization - - - //omg_param_list.mobility_type = RWALK; - //omg_param_list.nodes_type = UE; - //init_mobility_generator(omg_param_list); // initial positions + sleep /// need to indicate time of initialization - - - //omg_param_list.mobility_type = STATIC; - //omg_param_list.nodes_type = UE; - //init_mobility_generator(omg_param_list); // initial positions + sleep /// need to indicate time of initialization - - //LOG_I(OMG, "*****DISPLAY NODE LIST********\n"); - //display_node_list(Node_Vector[0]); - /*LOG_T(OMG, "********DISPLAY JOB LIST********\n"); - display_job_list(Job_Vector); - Job_Vector = quick_sort (Job_Vector); - LOG_T(OMG, "**********DISPLAY JOB LIST AFTER SORTING**********\n"); - display_job_list(Job_Vector);*/ - - /*init_omg_global_params(); //re-initialization de Node_Vector et Job_Vector - LOG_I(OMG, "*****DISPLAY NODE LIST********\n"); - display_node_list(Node_Vector[0]); - LOG_T(OMG, "********DISPLAY JOB LIST********\n"); - display_job_list(Job_Vector); - Job_Vector = quick_sort (Job_Vector); - LOG_T(OMG, "**********DISPLAY JOB LIST AFTER SORTING**********\n"); - display_job_list(Job_Vector);*/ - - /////////////// to call by OCG - // init omv - if (omv_enabled == 1) { - if(pipe(pfd) == -1) - perror("pipe error \n"); - - sprintf(full_name, "%s/UTIL/OMV/OMV",getenv("OPENAIR2_DIR")); - LOG_I(EMU,"Stating the OMV path %s pfd[0] %d pfd[1] %d \n", full_name, pfd[0],pfd[1]); - - switch(fork()) { - case -1 : - perror("fork failed \n"); - break; - case 0 : - if(close(pfd[1]) == -1 ) - perror("close on write\n" ); - sprintf(fdstr, "%d", pfd[0] ); - sprintf(num_enb, "%d", 1); - sprintf(num_ue, "%d", omg_param_list.nodes); - sprintf(x_area, "%f", omg_param_list.max_X ); - sprintf(y_area, "%f", omg_param_list.max_Y); - sprintf(z_area, "%f", 200.0 ); - sprintf(frames, "%d", (int) n_frames); - - execl(full_name,"OMV", fdstr, frames, num_enb, num_ue, x_area, y_area, z_area, NULL ); - perror( "error in execl the OMV" ); - } - //parent - if(close( pfd[0] ) == -1 ) - perror("close on read\n" ); + switch (fork ()) + { + case -1: + perror ("fork failed \n"); + break; + case 0: + if (close (pfd[1]) == -1) + perror ("close on write\n"); + sprintf (fdstr, "%d", pfd[0]); + sprintf (num_enb, "%d", 1); + sprintf (num_ue, "%d", omg_param_list[UE].nodes); + sprintf (x_area, "%f", omg_param_list[UE].max_x); + sprintf (y_area, "%f", omg_param_list[UE].max_y); + sprintf (z_area, "%f", 200.0); + sprintf (frames, "%d", (int) n_frames); + + execl (full_name, "OMV", fdstr, frames, num_enb, num_ue, x_area, + y_area, z_area, NULL); + perror ("error in execl the OMV"); } - - for (emu_info_time = 0.0 ; emu_info_time <= n_frames; emu_info_time+=0.1){ - //printf("updating node positions\n"); - // update_nodes(emu_info_time*1000); - update_nodes(emu_info_time); - //double emu_info.time += 1.0/100; // emu time in ms - /* for (i=(STATIC+1); i<MAX_NUM_MOB_TYPES; i++){ // - if (Node_Vector[i] != NULL){ - LOG_D(OMG, " mob model %d \n ", i); - update_nodes(i ,emu_info_time); - } - else {LOG_D( "nodes are STATIC\n"); } - }*/ - printf(" **********asking for positions in %d **********\n ", omg_param_list.mobility_type); - Current_positions = get_current_positions(omg_param_list.mobility_type, - omg_param_list.nodes_type, - emu_info_time); // type: enb, ue, all - - if(Current_positions !=NULL) { - printf(" **********Current_positions at time %f**********\n ",emu_info_time); - display_node_list(Current_positions); - printf(" **********DONE**********\n "); - if (omv_enabled == 1) - omv_write(pfd[1], Current_positions, omv_data); - } - - } - stop_mobility_generator(omg_param_list.mobility_type); - - /*LOG_D(OMG, " **********DISPLAY JOB LIST**********\n "); - display_job_list(Job_Vector); - emu_info_time = 10.0;*/ + //parent + if (close (pfd[0]) == -1) + perror ("close on read\n"); + } + +//****************************** + + for (emu_info_time = 0.0; emu_info_time <= n_frames; emu_info_time += 0.1) + { + + update_nodes (emu_info_time); + time_s = round (emu_info_time * 1000.0); + //printf("%d \n",time_s); + for (node_type = eNB; node_type < MAX_NUM_NODE_TYPES; node_type++) + { + current_positions = + get_current_positions (omg_param_list[node_type].mobility_type, + node_type, emu_info_time); + + if (current_positions != NULL) + + display_job_list (emu_info_time, + job_vector[omg_param_list + [node_type].mobility_type]); + + /*if(current_positions!= NULL && time_s %1000==0) + LOG_D(OMG, "%.2f %d\n",emu_info_time, + nodes_avgspeed(job_vector[omg_param_list [node_type].mobility_type])); */ + } + + + //display current postion of nodes + if (omv_enabled == 1) + omv_write (pfd[1], node_vector[SUMO], omv_data); - //Current_positions = get_current_positions(SUMO, emu_info_time); // type: enb, ue, all - //LOG_D(OMG, " **********Current_positions**********\n "); - //display_node_list(Current_positions); - //if (Current_positions == NULL) - // {LOG_D(OMG, " Cur_pos == NULL\n");} - //my_node = (NodePtr) get_node_position( RWP, UE, my_ID); - //LOG_D(OMG, "********At %.2f, Node number %d is in position: (%.2f, %.2f) with mobility_type: %d\n",emu_info_time, my_ID,my_node->X_pos,my_node->Y_pos,my_node->mobile); - if (omv_enabled == 1 ) - omv_end(pfd[1],omv_data); + } + /*LOG_I(OMG,"#-----event average-----\n"); + for (i=0;i<100;i++) + { + if(events[i]!=0) + LOG_D(OMG,"%d %d \n",i,event_sum[i]/events[i]); + } */ + + stop_mobility_generator (omg_param_list); + if (omv_enabled == 1) + omv_end (pfd[1], omv_data); + //clear_mem(); return 0; } -int omv_write (int pfd, Node_list ue_node_list, Data_Flow_Unit omv_data){ - int i=0,j; - omv_data.end=0; +/**********************************sumo****************************/ +int +omv_write (int pfd, node_list * ue_node_list, Data_Flow_Unit omv_data) +{ + int i = 0, j; + omv_data.end = 0; // enb omv_data.geo[i].x = 0.0; omv_data.geo[i].y = 0.0; omv_data.geo[i].z = 1.0; omv_data.geo[i].mobility_type = 0; - omv_data.geo[i].node_type = 0; //eNB - omv_data.geo[i].Neighbors=0; - - for (i=1;i<omg_param_list.nodes+1;i++) { - if (ue_node_list != NULL) { - omv_data.geo[i].x =(int) (ue_node_list->node->X_pos < 0.0) ? 0.0 : ue_node_list->node->X_pos; - omv_data.geo[i].y = (int) (ue_node_list->node->Y_pos < 0.0) ? 0.0 : ue_node_list->node->Y_pos; - omv_data.geo[i].z = 1.0; - omv_data.geo[i].mobility_type = omg_param_list.mobility_type; - omv_data.geo[i].node_type = 1; //UE - ue_node_list = ue_node_list->next; - omv_data.geo[i].Neighbors=0; - printf("node %d at (%d, %d)\n", i, omv_data.geo[i].x ,omv_data.geo[i].y ); + omv_data.geo[i].node_type = 0; //eNB + omv_data.geo[i].Neighbors = 0; + + for (i = 1; i < omg_param_list[SUMO].nodes + 1; i++) + { + if (ue_node_list != NULL) + { + omv_data.geo[i].x = + (int) (ue_node_list->node->x_pos < + 0.0) ? 0.0 : ue_node_list->node->x_pos; + omv_data.geo[i].y = + (int) (ue_node_list->node->y_pos < + 0.0) ? 0.0 : ue_node_list->node->y_pos; + omv_data.geo[i].z = 1.0; + omv_data.geo[i].mobility_type = omg_param_list[SUMO].mobility_type; + omv_data.geo[i].node_type = 1; //UE + ue_node_list = ue_node_list->next; + omv_data.geo[i].Neighbors = 0; + printf ("node %d at (%d, %d)\n", i, omv_data.geo[i].x, + omv_data.geo[i].y); + } } - } - - if( write( pfd, &omv_data, sizeof(struct Data_Flow_Unit) ) == -1 ) - perror( "write omv failed" ); + + if (write (pfd, &omv_data, sizeof (struct Data_Flow_Unit)) == -1) + perror ("write omv failed"); return 1; } -void omv_end (int pfd, Data_Flow_Unit omv_data) { - omv_data.end=1; - if( write( pfd, &omv_data, sizeof(struct Data_Flow_Unit) ) == -1 ) - perror( "write omv failed" ); -} -#endif - - - - - - - +void +omv_end (int pfd, Data_Flow_Unit omv_data) +{ + omv_data.end = 1; + if (write (pfd, &omv_data, sizeof (struct Data_Flow_Unit)) == -1) + perror ("write omv failed"); +} +#endif diff --git a/openair2/UTIL/OMG/omg.h b/openair2/UTIL/OMG/omg.h index 5e7b978edbbe38b2c28dc598389af1e54a76127c..75274a06fc1defe324ca58728c920e116aa7d13e 100644 --- a/openair2/UTIL/OMG/omg.h +++ b/openair2/UTIL/OMG/omg.h @@ -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) diff --git a/openair2/UTIL/OMG/omg_constants.h b/openair2/UTIL/OMG/omg_constants.h index 63eb751d837d4fa5a11c16ab773809ec44199535..e1322c10298dd01e17851f6bba54c7d66b9952b3 100644 --- a/openair2/UTIL/OMG/omg_constants.h +++ b/openair2/UTIL/OMG/omg_constants.h @@ -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_ */ diff --git a/openair2/UTIL/OMG/omg_vars.h b/openair2/UTIL/OMG/omg_vars.h index 5b2b4a3b1038dec4d1b864b5d8cda30f5850f372..ea2c6a5e8463758e4d8e164a2654f2db94467441 100644 --- a/openair2/UTIL/OMG/omg_vars.h +++ b/openair2/UTIL/OMG/omg_vars.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__ */ diff --git a/openair2/UTIL/OMG/rwalk.c b/openair2/UTIL/OMG/rwalk.c index 2dbddc2841d7f588d6662d198bf7217c6d6a17eb..918e34514c44997f3c21c7e113ec58286ab20ac2 100644 --- a/openair2/UTIL/OMG/rwalk.c +++ b/openair2/UTIL/OMG/rwalk.c @@ -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" - - -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); - - - 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 ++; - - if (Job_Vector == NULL) - LOG_E(OMG, "Job Vector is NULL\n"); - } - return(0); -} +#include "steadystaterwp.h" + + +int +start_rwalk_generator (omg_global_param omg_param_list) +{ + + 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; + + 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 -void place_rwalk_node(NodePtr node) { + pair = (pair_struct *) malloc (sizeof (struct pair_struct)); + pair->b = node; + // sleep_rwalk_node (pair, cur_time); //sleep + //pause probability...some of the nodes start at pause & the other on move - node->X_pos = (double) ((int) (randomGen(omg_param_list.min_X, omg_param_list.max_X)*100))/ 100; - node->mob->X_from = node->X_pos; - node->mob->X_to = node->X_pos; - node->Y_pos = (double) ((int) (randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100; - node->mob->Y_from = node->Y_pos; - node->mob->Y_to = node->Y_pos; + if (randomgen (0, 1) < pause_p) + sleep_steadystaterwp_node (pair, cur_time); //sleep + else + move_steadystaterwp_node (pair, cur_time); - node->mob->speed = 0.0; - node->mob->journey_time = 0.0; - LOG_D(OMG, " INITIALIZE RWALK NODE\n "); - LOG_I(OMG, "Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = 0.0\n", node->ID, node->type, node->X_pos, node->Y_pos); - Node_Vector[RWALK] = (Node_list) add_entry(node, Node_Vector[RWALK]); - Node_Vector_len[RWALK]++; - //Initial_Node_Vector_len[RWALK]++; + 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); } -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 +place_rwalk_node (node_struct * node) +{ + node->x_pos = + (double) ((int) + (randomgen + (omg_param_list[node->type].min_x, + omg_param_list[node->type].max_x) * 100)) / 100; + node->mob->x_from = node->x_pos; + node->mob->x_to = node->x_pos; + node->y_pos = + (double) ((int) + (randomgen + (omg_param_list[node->type].min_y, + omg_param_list[node->type].max_y) * 100)) / 100; + node->mob->y_from = node->y_pos; + node->mob->y_to = node->y_pos; + node->mob->speed = 0.0; + node->mob->journey_time = 0.0; + + // LOG_D (OMG, " INITIALIZE RWALK NODE\n "); + LOG_I (OMG, + "#Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = 0.0\n", + node->id, node->type, node->x_pos, node->y_pos); + + node_vector_end[node->type] = + (node_list *) add_entry (node, node_vector_end[node->type]); + + if (node_vector[node->type] == NULL) + node_vector[node->type] = node_vector_end[node->type]; + + node_vector_len[node->type]++; + +} - node->mob->sleep_duration = (double) ((int) (randomGen(omg_param_list.min_sleep, omg_param_list.max_sleep)*100))/ 100; - LOG_D(OMG, "node: %d \tsleep duration : %.2f\n",node->ID, node->mob->sleep_duration); - node->mob->start_journey = cur_time; - 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; +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[node->type].min_sleep, + omg_param_list[node->type].max_sleep) * 100)) / 100; + // LOG_D (OMG, "node: %d \tsleep duration : %.2f\n", node->ID, +// node->mob->sleep_duration); + node->mob->start_journey = cur_time; + pair->next_event_t = cur_time + node->mob->sleep_duration; //when to wake up + // LOG_D (OMG, "to wake up at time: cur_time + sleep_duration : %.2f\n", +// pair->a); - return pair; } - -Pair move_rwalk_node(NodePtr node, double cur_time) { - Pair pair = malloc(sizeof(Pair)); - 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; + + +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>param_list.max_X){ - node->mob->X_to = param_list.max_X; + else if (x_next > omg_param_list[node->type].max_x) + { + distancex = + (omg_param_list[node->type].max_x - x_now) / cos (alpha); + } - else { - node->mob->X_to = X_next; + else + { + distancex = distance; } - if (Y_next<param_list.min_Y){ - node->mob->Y_to = param_list.min_Y; + 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>param_list.max_Y){ - node->mob->Y_to = param_list.max_Y; + else if (y_next > omg_param_list[node->type].max_y) + { + distancey = + (omg_param_list[node->type].max_y - y_now) / sin (alpha); + } - else { - node->mob->Y_to = Y_next; - }*/ - if (X_next < omg_param_list.min_X){ - while (X_next < omg_param_list.min_X){ - X_next = X_next + omg_param_list.max_X; - } - node->mob->X_to = X_next; - } - else if (X_next > omg_param_list.max_X){ - while (X_next > omg_param_list.max_X){ - X_next = X_next - omg_param_list.max_X; - } - node->mob->X_to = X_next; - } - else { - node->mob->X_to = X_next; + else + { + distancey = distance; } - 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; + + if ((distancex == distance && distancey == distance)) + break; + + + + if (distancey < distancex) + { + + x_now = distancey * cos (alpha) + x_now; + y_now = distancey * sin (alpha) + y_now; + distance = distance - distancey; + + dx = distance * cos (2 * M_PI - alpha); + dy = distance * sin (2 * M_PI - alpha); + + x_next = x_now + dx; + y_next = y_now + dy; + + alpha = 2 * M_PI - alpha; + } - else { - node->mob->Y_to = Y_next; + 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; } - - 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; - -} + 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++; + } -void update_rwalk_nodes(double cur_time) {// need to implement an out-of-area check as well as a rebound function to stay in the area - LOG_D(OMG, "--------UPDATE--------\n"); - Job_list tmp = Job_Vector; - int done = 0; // - while ((tmp != NULL) && (done == 0)){ - //if (tmp->pair == NULL){LOG_E(OMG, "UPDATE RWALK : tmp->pair ==NULL\n" );} - //if (tmp->pair != NULL){LOG_E(OMG, "UPDATE RWALK : tmp->pair !=NULL\n" );} - LOG_D(OMG, "cur_time %f\n", cur_time ); - LOG_D(OMG, "tmp->pair->a %f\n", tmp->pair->a ); - - if((tmp->pair !=NULL) && ( (double)tmp->pair->a >= cur_time - eps) && ( (double)tmp->pair->a <= cur_time + eps) ) { - if (tmp->pair->b->generator == RWALK){ - LOG_D(OMG, " (first_job_time) %.2f == %.2f (cur_time) \n ",tmp->pair->a, cur_time ); - LOG_D(OMG, " UPDATE RWALK \n "); - NodePtr my_node = (NodePtr)tmp->pair->b; - /*if(my_node->mobile == 1) { - LOG_D(OMG, " stop node and let it sleep \n" ); - my_node->mobile = 0; - Pair pair = malloc(sizeof(Pair)); - pair = sleep_rwalk_node(my_node, cur_time); - tmp->pair = pair; - tmp = tmp->next; - }*/ - if ((my_node->mobile ==0) || (my_node->mobile == 1)) { - LOG_D(OMG, " node %d...let's move again \n", my_node->ID); - my_node->mobile = 1; - Pair pair = malloc(sizeof(Pair)); - pair = move_rwalk_node(my_node, cur_time); - tmp->pair = pair; - tmp = tmp->next; - } - else{ - LOG_E(OMG, "update_generator: unsupported node state - mobile : %d \n", my_node->mobile); - //exit(-1); - } - } - else { - LOG_D(OMG, " (first_job_time) %.2f == %.2f(cur_time) but (generator=%d) != (RWALK=%d)\n ",tmp->pair->a, cur_time, tmp->pair->b->generator, RWALK ); - tmp = tmp->next; - } - } - else if ( (tmp->pair != NULL) && (cur_time < tmp->pair->a ) ){ //&& (tmp->pair->b->generator == RWALK) - LOG_D(OMG, " %.2f < %.2f \n",cur_time, tmp->pair->a); - LOG_D(OMG, "Nothing to do\n"); - done = 1; //quit the loop - } - else { - LOG_E(OMG, "\n %.2f > %.2f", cur_time,tmp->pair->a ); //LOG_D(OMG, " (generator=%d) != (RWALK=%d) \n", tmp->pair->b->generator, RWALK ); - done = 1; //quit the loop - exit(-1); - } - } - //sorting the new entries - LOG_D(OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T - display_job_list(Job_Vector); - Job_Vector = quick_sort (Job_Vector);/////////// - LOG_D(OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n"); - display_job_list(Job_Vector); } -void get_rwalk_positions_updated(double cur_time){ - - double 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; - } +double +residualtime (omg_global_param omg_param) +{ + double u; + u = randomgen (0, 1); + if (u < + (2 * omg_param.min_sleep / + (omg_param.max_journey_time + omg_param.min_journey_time))) + return u * (omg_param.max_journey_time + omg_param.min_journey_time) / 2; + else + return omg_param.max_journey_time - + sqrtf ((1 - u) * (pow (omg_param.max_journey_time, 2) - + pow (omg_param.min_sleep, 2))); +} + + +void +update_rwalk_nodes (double cur_time) +{ + int done = 0; + job_list *tmp = job_vector[RWALK]; + node_struct *my_node; + while (tmp != NULL && done == 0) + { + my_node = (node_struct *) tmp->pair->b; + + //case1:time to next event equals to current time + if (tmp->pair != NULL + && ((double) tmp->pair->next_event_t >= cur_time - eps) + && ((double) tmp->pair->next_event_t <= cur_time + eps)) + { + if (my_node->mobile == 1) + sleep_rwalk_node (tmp->pair, cur_time); + else + move_rwalk_node (tmp->pair, cur_time); + + } + //case2: current time is greater than the time to next event + + else if (tmp->pair != NULL + && (cur_time - eps) > tmp->pair->next_event_t) + { + + while (cur_time >= tmp->pair->next_event_t) + { + if (my_node->mobile == 1) + sleep_rwalk_node (tmp->pair, cur_time); + else + move_rwalk_node (tmp->pair, cur_time); + + } } - else { - LOG_E(OMG,"ERROR current time %f > first job_time %f\n", cur_time, my_pair->a); - } + //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) + { -/*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"); + 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 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; } - else { - l = Job_Vector_len; - //LOG_D(OMG,"(generator=%d) != (RWALK=%d)\n", my_pair->b->generator, RWALK ); - LOG_E(OMG, " %.2f > %.2f \n", cur_time,my_pair->a); - } -} -}*/ + if (y_next < omg_param_list[tmp->pair->b->type].min_y) + { + distancey = + (omg_param_list[tmp->pair->b->type].min_y - + y_now) / sin (alpha); + } + else if (y_next > omg_param_list[tmp->pair->b->type].max_y) + { + distancey = + (omg_param_list[tmp->pair->b->type].max_y - + y_now) / sin (alpha); + } + else + { + distancey = len; + } + + if (distancex == len && distancey == len) + break; + if (distancey < distancex) + { + x_now = distancey * cos (alpha) + x_now; + y_now = distancey * sin (alpha) + y_now; + len = len - distancey; + dx = len * cos (2 * M_PI - alpha); + dy = len * sin (2 * M_PI - alpha); + x_next = x_now + dx; + y_next = y_now + dy; + + alpha = 2 * M_PI - alpha; + + } + else if (distancex < distancey) + { + x_now = distancex * cos (alpha) + x_now; + y_now = distancex * sin (alpha) + y_now; + + len = len - distancex; + + dx = len * cos (M_PI - alpha); + dy = len * sin (M_PI - alpha); + + x_next = x_now + dx; + y_next = y_now + dy; + + alpha = M_PI - alpha; + } - + + } + + tmp->pair->b->x_pos = (double) ((int) (x_next * 100)) / 100; + tmp->pair->b->y_pos = (double) ((int) (y_next * 100)) / 100; + + + } + else + { + tmp->pair->b->x_pos = tmp->pair->b->mob->x_to; + tmp->pair->b->y_pos = tmp->pair->b->mob->y_to; + } + + //if(tmp->pair->b->id==2 && ((int)(cur_time*1000)% 100)==0) + //LOG_D (OMG, "%d %.2f %.2f \n\n",tmp->pair->b->id,tmp->pair->b->x_pos,tmp->pair->b->y_pos); + + tmp = tmp->next; + + } +} diff --git a/openair2/UTIL/OMG/rwalk.h b/openair2/UTIL/OMG/rwalk.h index a5ace929311ecb9255f923036383800843ed7b5b..86d199018211a47d49cb0541b86f6afd9134caef 100644 --- a/openair2/UTIL/OMG/rwalk.h +++ b/openair2/UTIL/OMG/rwalk.h @@ -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_ */ diff --git a/openair2/UTIL/OMG/rwp.c b/openair2/UTIL/OMG/rwp.c index 57cde714a23cd458b065d504e13ebf9d65a4736f..8fa2507c106a439c0a9408877f839591da77525b 100644 --- a/openair2/UTIL/OMG/rwp.c +++ b/openair2/UTIL/OMG/rwp.c @@ -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"); - } - LOG_I(OMG, "[RWP] Number of random waypoint nodes has been set to %d\n", omg_param_list.nodes); - - for (n_id = 0; n_id< omg_param_list.nodes; n_id++) { - - node = (NodePtr) create_node(); - mobility = (MobilityPtr) create_mobility(); - node->mobile = 0; // static for the moment - node->ID = n_id; - node->type = omg_param_list.nodes_type; // UE eNB - node->generator = omg_param_list.mobility_type; // STATIC, RWP... - node->mob = mobility; - - place_rwp_node(node); //initial positions - - Pair pair = malloc (sizeof(Pair)); - pair = sleep_rwp_node(node, cur_time); //sleep - - Job_Vector = add_job(pair, Job_Vector); - Job_Vector_len ++; - - if (Job_Vector == NULL) - LOG_E(OMG, "[RWP] Job Vector is NULL\n"); - // else - // LOG_T(OMG, "\nJob_Vector_Rwp->pair->b->ID %d\n", Job_Vector_Rwp->pair->b->ID);*/ - } - return(0); -} -void place_rwp_node(NodePtr node) { - node->X_pos = (double) ((int) (randomGen(omg_param_list.min_X, omg_param_list.max_X)*100))/ 100; - 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; +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; + - 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[RWP] = (Node_list) add_entry(node, Node_Vector[RWP]); - Node_Vector_len[RWP]++; - //Initial_Node_Vector_len[RWP]++; + if (job_vector[RWP] == NULL) + LOG_E (OMG, "[RWP] Job Vector is NULL\n"); + return (0); } -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; +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]++; } -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 +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 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 +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]); + + + } + while (node->mob->x_to == node->mob->x_from + && node->mob->y_to == node->mob->y_from); + + distance = fabs (node->mob->x_to - node->mob->x_from) + + fabs (node->mob->y_to - node->mob->y_from); + + /* LOG_D(OMG,"#location number %d x pos to %.2f y pos to %.2f x pos from %.2f y pos from %.2f\n\n",loc_num,node->mob->x_to,node->mob->y_to,node->mob->x_from,node->mob->y_from); */ + + } + else if (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 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; + +/*update RWP nodes position*/ + +void +update_rwp_nodes (double cur_time) +{ + + int done = 0; + job_list *tmp = job_vector[RWP]; + node_struct *my_node; + while (tmp != NULL && done == 0) + { + my_node = (node_struct *) tmp->pair->b; + + //case1:time to next event equals to current time + if (tmp->pair != NULL + && ((double) tmp->pair->next_event_t >= cur_time - eps) + && ((double) tmp->pair->next_event_t <= cur_time + eps)) + { + if (my_node->mobile == 1) + sleep_rwp_node (tmp->pair, cur_time); + else + move_rwp_node (tmp->pair, cur_time); + + } + //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; - - while (l < Job_Vector_len){ - LOG_D(OMG, "l == %d \n", l); - - //Pair my_pair = malloc (sizeof(Pair)); - //my_pair = tmp->pair; - - 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, "cur_time %f\n", cur_time ); - LOG_D(OMG, "tmp->pair->a %f\n", tmp->pair->a ); - - if((tmp->pair !=NULL) && ( (double)tmp->pair->a >= cur_time - eps) && ( (double)tmp->pair->a <= cur_time + eps) ) { - if (tmp->pair->b->generator == 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; +void +get_rwp_positions_updated (double cur_time) +{ + + double x_now = 0.0, y_now = 0.0; + double len, dx, dy; + job_list *tmp = job_vector[RWP]; + + while (tmp != NULL) + { + + if (tmp->pair->b->mobile == 1 && tmp->pair->next_event_t >= cur_time) + { + + 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 (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; + + } + +} diff --git a/openair2/UTIL/OMG/rwp.h b/openair2/UTIL/OMG/rwp.h index 10649657abd8d81c5903a441d3d469eeeda47d14..dcbd0a4e837c5382d717e027fd8a24b49411d568 100644 --- a/openair2/UTIL/OMG/rwp.h +++ b/openair2/UTIL/OMG/rwp.h @@ -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) diff --git a/openair2/UTIL/OMG/socket_traci_OMG.h b/openair2/UTIL/OMG/socket_traci_OMG.h index ffce4127858de59267c4cd96dd93da7c54fbc719..edca51c823fe87159f1eca38b2fb0e9588a1ec3b 100644 --- a/openair2/UTIL/OMG/socket_traci_OMG.h +++ b/openair2/UTIL/OMG/socket_traci_OMG.h @@ -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 diff --git a/openair2/UTIL/OMG/static.c b/openair2/UTIL/OMG/static.c index 85a14f33108831ed6d4da156a61cf5568e13784c..1275dacfbe19272fb26099452cdfbbf598727892 100644 --- a/openair2/UTIL/OMG/static.c +++ b/openair2/UTIL/OMG/static.c @@ -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" + + +void +start_static_generator (omg_global_param omg_param_list) +{ + + int id; + static int n_id = 0; + node_struct *node = NULL; + mobility_struct *mobility = NULL; + + srand (omg_param_list.seed + STATIC); + + LOG_I (OMG, "Static mobility model for %d %d nodes\n", omg_param_list.nodes, + omg_param_list.nodes_type); + for (id = n_id; id < (omg_param_list.nodes + n_id); id++) + { + + node = create_node (); + mobility = create_mobility (); + + node->id = id; + node->type = omg_param_list.nodes_type; + node->mob = mobility; + node->generator = STATIC; + place_static_node (node); //initial positions + } + n_id += omg_param_list.nodes; + -#include "omg.h" -void place_static_node(NodePtr node); - -void start_static_generator(omg_global_param omg_param_list) { - - int n_id=0; - // double cur_time = 1.0; - NodePtr node = NULL; - MobilityPtr mobility = NULL; - - - if (omg_param_list.nodes <= 0){ - LOG_W(OMG, "Number of static nodes has not been set\n"); - return; - } - - srand(omg_param_list.seed + STATIC); - // for (n_id = omg_param_list.first_ix; n_id< omg_param_list.first_ix + omg_param_list.nodes; n_id++){ - - if (omg_param_list.nodes_type == eNB) { - LOG_I(OMG, "Static mobility model for %d eNBs \n", omg_param_list.nodes); - } else if (omg_param_list.nodes_type == UE) { - LOG_I(OMG, "Static mobility model for %d UE\n",omg_param_list.nodes); - } - - for (n_id = 0; n_id< omg_param_list.nodes; n_id++) { - - node = (NodePtr) create_node(); - mobility = (MobilityPtr) create_mobility(); - - node->ID = n_id; - node->generator = omg_param_list.mobility_type; - node->type = omg_param_list.nodes_type; - node->mob = mobility; - node->generator = STATIC; - - place_static_node(node); //initial positions - } } -void place_static_node(NodePtr node) { - if (omg_param_list.user_fixed && node->type == eNB) { - 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]++; +} diff --git a/openair2/UTIL/OMG/static.h b/openair2/UTIL/OMG/static.h index 7323c3b2a2e0fa27b1cd9344bcb46ecf808ba961..7cb1ae7ea186da80f6fb38ef236b4c9f1fa503db 100644 --- a/openair2/UTIL/OMG/static.h +++ b/openair2/UTIL/OMG/static.h @@ -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_ */ diff --git a/openair2/UTIL/OMG/steadystaterwp.c b/openair2/UTIL/OMG/steadystaterwp.c new file mode 100644 index 0000000000000000000000000000000000000000..c316114790b538a400264a623d73ec9db6bc09e5 --- /dev/null +++ b/openair2/UTIL/OMG/steadystaterwp.c @@ -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; + + } + +} diff --git a/openair2/UTIL/OMG/steadystaterwp.h b/openair2/UTIL/OMG/steadystaterwp.h new file mode 100644 index 0000000000000000000000000000000000000000..86269b252e83c4329ee55bd1c61d7037e8ab139c --- /dev/null +++ b/openair2/UTIL/OMG/steadystaterwp.h @@ -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 + + + + + + + + + + + diff --git a/openair2/UTIL/OMG/storage_traci_OMG.c b/openair2/UTIL/OMG/storage_traci_OMG.c index d143ab841056e49be1fe6a75cde4c02d913e6013..5395d2f0111f09d1037d5b19880fca0100c1d36c 100644 --- a/openair2/UTIL/OMG/storage_traci_OMG.c +++ b/openair2/UTIL/OMG/storage_traci_OMG.c @@ -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; diff --git a/openair2/UTIL/OMG/storage_traci_OMG.h b/openair2/UTIL/OMG/storage_traci_OMG.h index 4cbdddb01fe9a76fe6cb5c6301dfe652eaa42e17..c83e6df1d1b6e66f50f8df2d2dd8195d37090590 100644 --- a/openair2/UTIL/OMG/storage_traci_OMG.h +++ b/openair2/UTIL/OMG/storage_traci_OMG.h @@ -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); diff --git a/openair2/UTIL/OMG/sumo.c b/openair2/UTIL/OMG/sumo.c index 91e9c5bdfcac790163acbc5669c2fde8a2341b7d..c85624f83e92b4b3708d4a22ef019f685af43d1b 100644 --- a/openair2/UTIL/OMG/sumo.c +++ b/openair2/UTIL/OMG/sumo.c @@ -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); + + init (omg_param_list.sumo_end - omg_param_list.sumo_start); - // printf("received Number of nodes %d\n", max_node_SUMO); + int max_node_SUMO = 100; //commandGetMaxSUMONodesVariable(); TODO method not implemented in TraCI server..must find another solution + + // printf("received Number of nodes %d\n", max_node_SUMO); // create the OAI/SUMO ID manager - id_manager = create_IDManager(); + id_manager = create_IDManager (); + + node_struct *node = NULL; + mobility_struct *mobility = NULL; - NodePtr node = NULL; - MobilityPtr mobility = NULL; - - active_nodes = NULL; // container to return a subset of only ACTIVE OAI nodes in SUMO + 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_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; - - Node_Vector[SUMO] = (Node_list) add_entry(node, Node_Vector[SUMO]); - } - - update_IDs(); // update the mapping between departed and arrived nodes in SUMO. - - return(0); + 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 + } + + 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(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; - } - + 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; - } + 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; } - 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); + + 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); + } + } - - } - 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); - - 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; + 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; + } + + } + +#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 - - 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 +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 + + return true; - return true; + } - } + else + { +#ifdef STANDALONE + printf + ("All OAI Nodes are already active in SUMO; cannot control this SUMO node in OAI\n"); +#else + LOG_I (OMG, + "All OAI Nodes are already active in SUMO; cannot control this SUMO node in OAI\n"); +#endif + return false; + } +} - else { - #ifdef STANDALONE - printf("All OAI Nodes are already active in SUMO; cannot control this SUMO node in OAI\n"); - #else - LOG_I(OMG, "All OAI Nodes are already active in SUMO; cannot control this SUMO node in OAI\n"); - #endif - return false; - } -} +void +update_sumo_nodes (double cur_time) +{ + if ((cur_time - last_update_time) < MIN_SUMO_STEP) + { // the min time interval for SUMO must be 100ms or more + printf ("--------Update Step too small--------\n"); + return; + } -void update_sumo_nodes(double cur_time) { - 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 + 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){ - - - - #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); - } +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; +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; - - 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; +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; + } } - } - 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; } diff --git a/openair2/UTIL/OMG/sumo.h b/openair2/UTIL/OMG/sumo.h index 55f770c50f80a88eccb1bff414d0e05ba643a0b7..240a6a2b1d8e90f955b3b24e7fd155df15ba85a8 100644 --- a/openair2/UTIL/OMG/sumo.h +++ b/openair2/UTIL/OMG/sumo.h @@ -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_ */ diff --git a/openair2/UTIL/OMG/trace.c b/openair2/UTIL/OMG/trace.c index fe9a8732740908637405263fbfb8c7d8be17f87a..2631442a7c0f84a1810aeff6413ee6c55c2e8e8a 100644 --- a/openair2/UTIL/OMG/trace.c +++ b/openair2/UTIL/OMG/trace.c @@ -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" - -extern node_info* head_node_info; -extern hash_table_t* table; - -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 deploy_nodes() { - - NodePtr node = NULL; - -// 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); -} +#define FIXED 1 +#define MOVING 0 + +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) +{ + 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; + + parse_data (omg_param_list.mobility_file, omg_param_list.nodes_type); //read mobility file + + //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); - - - 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]++; - -} +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; -// [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->speed = n_ptr->speed; + node->mob->journey_time = 0.0; + // node->start_journey=(double) n_ptr->time; //time of initial position + // node->mob->target_time=(double) n_ptr->next->time; //time of next destination + LOG_I (OMG, + "[TRACE] Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = %.2f \n ", + node->id, node->type, node->x_pos, node->y_pos, node->mob->speed); - node->mob->sleep_duration = sleep_duration ; - LOG_D(OMG, "node: %d \tsleep duration : %.2f\n",node->ID, node->mob->sleep_duration); + node_vector_end[node->type] = + (node_list *) add_entry (node, node_vector_end[node->type]); - node->mob->start_journey = cur_time; - - pair->a =(node->mob->start_journey + node->mob->sleep_duration); + if (node_vector[node->type] == NULL) + node_vector[node->type] = node_vector_end[node->type]; - LOG_D(OMG, "to wake up at time: cur_time %f + sleep_duration : %.2f\n", cur_time,pair->a); - pair->b = node; + node_vector_len[node->type]++; - return pair; } -Pair keep_awake_trace_node(NodePtr node, double cur_time,float duration,int jump){ - +void +move_trace_node (pair_struct * pair, node_data * n_data, double cur_time) +{ + node_struct *node; + node = pair->b; + double cdistance, journeytime, speed; + double journeytime_next, distance; + node->mob->x_from = node->mob->x_to; + node->mob->y_from = node->mob->y_to; node->mobile = 1; - - node->mob->speed = 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; + pair->next_event_t = cur_time + journeytime_next; //when to reach the destination + +} + +void +schedule_trace_node (pair_struct * pair, node_data * n_data, double cur_time) +{ + node_struct *node = pair->b; + node->mobile = 3; node->mob->start_journey = cur_time; - - //node->mob->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 = 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; - - 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 +update_trace_nodes (double cur_time) +{ + job_list *tmp; + int done = 0; + node_data *node_n; + node_struct *my_node; + + + tmp = job_vector[TRACE]; + if (tmp == NULL) + LOG_D (OMG, "[TRACE] last data for all nodes\n"); + + while (tmp != NULL && done != 1) + { //1 + my_node = tmp->pair->b; + node_n = get_next_data (table[my_node->type], my_node->gid, DATA_ONLY); + + if (node_n->next->next == NULL) + { + tmp->pair->b->x_pos = tmp->pair->b->mob->x_to; + tmp->pair->b->mob->x_from = tmp->pair->b->x_pos; + tmp->pair->b->y_pos = tmp->pair->b->mob->y_to; + tmp->pair->b->mob->y_from = tmp->pair->b->y_pos; + tmp->pair->b->mobile = 0; + tmp->pair->b->mob->speed = 0.0; + // LOG_D (OMG, "[TRACE] last data for all nodes\n"); + tmp = tmp->next; + continue; + } + + + + //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; - double Y_now=0.0; - //LOG_D(OMG, "--------GET TRACE POSITIONS--------\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); - - 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; + +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) +{ + + +} diff --git a/openair2/UTIL/OMG/trace.h b/openair2/UTIL/OMG/trace.h index b95ff5b0d564a283bdd843a0ec042243eb220c6f..acc61825be0d90d7512f68a495351d87ec1e1c11 100644 --- a/openair2/UTIL/OMG/trace.h +++ b/openair2/UTIL/OMG/trace.h @@ -42,65 +42,22 @@ #define TRACE_H_ //#include "defs.h" #include "omg.h" -#include "hashtable.h" +#include "trace_hashtable.h" #include "mobility_parser.h" +int start_trace_generator (omg_global_param omg_param_list); -/** - * \fn void start_trace_generator(omg_global_param omg_param_list) - * \brief Start the TRACE model by setting the initial positions of each node then letting it sleep for a random duration and adding this job to the Job_Vector - * \param omg_param_list a structure that contains the main parameters needed to establish the random positions distribution - */ -int start_trace_generator(omg_global_param omg_param_list) ; - -/** - * \fn int create_trace_node(node_info *head_node) - * \brief Called by the function start_trace_generator(), it assigns position ((X,Y) coordinates) for a node from mobility file and add it to the Node_Vector_Rwp - * \param node a pointer of type NodePtr that represents the node to which the random position is assigned - */ -int create_trace_node(NodePtr node,node_info *head_node) ; -/** - * \fn void place_rwp_node(NodePtr node) - * \brief Called by the function start_rwp_generator(), it generates a random position ((X,Y) coordinates) for a node and add it to the Node_Vector_Rwp - * \param node a pointer of type NodePtr that represents the node to which the random position is assigned - */ -void place_trace_node(NodePtr node) ; -int deploy_nodes(); -/** - * \fn Pair sleep_rwp_node(NodePtr node, double cur_time) - * \brief Called by the function start_rwp_generator(omg_global_param omg_param_list) and update_rwp_nodes(double cur_time), it allows the node to sleep for a random duration starting - * from the current time - * \param node a pointer of type NodePtr that represents the node to which the random sleep duration is assigned - * \param cur_time a variable of type double that represents the current time - * \return A Pair structure containing the node and the time when it is reaching the destination - */ -Pair sleep_trace_node(NodePtr node, double cur_time,float sleep_duration) ; -Pair keep_awake_trace_node(NodePtr node, double cur_time,float duration,int jump); -/** - * \fn Pair move_rwp_node(NodePtr node, double cur_time) - * \brief Called by the function update_rwp_nodes(double cur_time), it computes the next destination of a node ((X,Y) coordinates and the arrival - * time at the destination) - * \param node a variable of type NodePtr that represents the node that has to move - * \param cur_time a variable of type double that represents the current time - * \return A Pair structure containing the node structure and the arrival time at the destination - */ -Pair move_trace_node(NodePtr node, double cur_time) ; - -/** - * \fn void update_rwp_nodes(double cur_time) - * \brief Update the positions of the nodes. After comparing the current time to the first job_time, it is decided wether to start - * \ a new job or to keep the current job - * \param cur_time a variable of type double that represents the current time - */ -void update_trace_nodes(double cur_time) ; - -/** - * \fn void get_rwp_positions_updated(double cur_time) - * \brief Compute the positions of the nodes at a given time in case they are moving (intermediate positions). Otherwise, generate a message saying that - * the nodes are still sleeping - * \param cur_time a variable of type double that represents the current time - */ -void get_trace_positions_updated(double cur_time); +void place_trace_node (node_struct* node, node_data* n); +void move_trace_node (pair_struct* pair, node_data* n_data, double cur_time); + +void schedule_trace_node ( pair_struct* pair, node_data* n_data, double cur_time); + +void sleep_trace_node ( pair_struct* pair, node_data* n_data, double cur_time); + +void update_trace_nodes (double cur_time); + +void get_trace_positions_updated (double cur_time); +void clear_list (void); #endif /* TRACE_H_ */ diff --git a/openair2/UTIL/OMG/trace_hashtable.c b/openair2/UTIL/OMG/trace_hashtable.c new file mode 100644 index 0000000000000000000000000000000000000000..016cae3c07f3f832e4f139bf58357d6870cb38fe --- /dev/null +++ b/openair2/UTIL/OMG/trace_hashtable.c @@ -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 () +{ + +} diff --git a/openair2/UTIL/OMG/trace_hashtable.h b/openair2/UTIL/OMG/trace_hashtable.h new file mode 100644 index 0000000000000000000000000000000000000000..7a0464b04f4729d509fbc4522a82fc340476e56e --- /dev/null +++ b/openair2/UTIL/OMG/trace_hashtable.h @@ -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