/******************************************************************************* OpenAirInterface Copyright(c) 1999 - 2014 Eurecom OpenAirInterface is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenAirInterface is distributed in the hope that 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 OpenAirInterface.The full GNU General Public License is included in this distribution in the file called "COPYING". If not, see <http://www.gnu.org/licenses/>. Contact Information OpenAirInterface Admin: openair_admin@eurecom.fr OpenAirInterface Tech : openair_tech@eurecom.fr OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE *******************************************************************************/ /*! \file trace.c * \brief The trace-based mobility model for OMG/OAI (mobility is statically imported from a file) * \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 "trace.h" #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"); return 0; } void place_trace_node (node_struct * node, node_data * n) { node_data *n_ptr = n; node->x_pos = (double) n_ptr->x_pos; node->mob->x_from = node->x_pos; node->mob->x_to = node->x_pos; node->y_pos = (double) n_ptr->y_pos; node->mob->y_from = node->y_pos; node->mob->y_to = node->y_pos; node->mob->speed = n_ptr->speed; node->mob->journey_time = 0.0; // node->start_journey=(double) n_ptr->time; //time of initial position // node->mob->target_time=(double) n_ptr->next->time; //time of next destination LOG_I (OMG, "[TRACE] Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = %.2f \n ", node->id, node->type, node->x_pos, node->y_pos, node->mob->speed); node_vector_end[node->type] = (node_list *) add_entry (node, node_vector_end[node->type]); if (node_vector[node->type] == NULL) node_vector[node->type] = node_vector_end[node->type]; node_vector_len[node->type]++; } void move_trace_node (pair_struct * pair, node_data * n_data, double cur_time) { node_struct *node; node = pair->b; double cdistance, journeytime, speed; double journeytime_next, distance; node->mob->x_from = node->mob->x_to; node->mob->y_from = node->mob->y_to; node->mobile = 1; node->mob->speed = n_data->speed; node->mob->x_to = (double) n_data->next->x_pos; node->mob->y_to = (double) n_data->next->y_pos; node->mob->target_time = (double) n_data->next->time; //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; 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); } 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; LOG_D(OMG,"[TRACE] curretn and next lcoation are the same : sleep for %f\n",node->mob->sleep_duration); } else { /* early arrival*/ //sleep case 2 //node->mob->sleep_duration = node->mob->target_time - (journeytime + node->mob->start_journey); node->mob->sleep_duration = node->mob->target_time - pair->next_event_t; LOG_D(OMG,"[TRACE] Early Arrival (target time > journeytime), sleep for %f target time was %f\n",node->mob->sleep_duration,node->mob->target_time); } 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) { 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); //case1:time to next event equals to current time if (tmp->pair != NULL && tmp->pair->next_event_t >= cur_time - omg_eps && tmp->pair->next_event_t <= cur_time ) { 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; } //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 > 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; 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; } while (cur_time >= tmp->pair->next_event_t) { if (node_n->next->next == NULL) { tmp->pair->b->x_pos = tmp->pair->b->mob->x_to; tmp->pair->b->mob->x_from = tmp->pair->b->x_pos; tmp->pair->b->y_pos = tmp->pair->b->mob->y_to; tmp->pair->b->mob->y_from = tmp->pair->b->y_pos; break; } if (my_node->mobile == 1) { if (my_node->mob->target_time > tmp->pair->next_event_t) { //sleep node sleep_trace_node (tmp->pair, node_n, cur_time); } else { node_n = get_next_data (table[my_node->type], my_node->gid, DATA_AND_STATUS_CHANGE); if (node_n->x_pos == node_n->next->x_pos && node_n->y_pos == node_n->next->y_pos) sleep_trace_node (tmp->pair, node_n, cur_time); else move_trace_node (tmp->pair, node_n, cur_time); } } else if (my_node->mobile == 0) { node_n = get_next_data (table[my_node->type], my_node->gid, DATA_AND_STATUS_CHANGE); if (node_n->x_pos == node_n->next->x_pos && node_n->y_pos == node_n->next->y_pos) sleep_trace_node (tmp->pair, node_n, cur_time); else move_trace_node (tmp->pair, node_n, cur_time); } else { node_n = get_next_data (table[my_node->type], my_node->gid, DATA_ONLY); if (node_n->x_pos == node_n->next->x_pos && node_n->y_pos == node_n->next->y_pos) sleep_trace_node (tmp->pair, node_n, cur_time); else move_trace_node (tmp->pair, node_n, cur_time); } node_n = get_next_data (table[my_node->type], my_node->gid, DATA_ONLY); if (node_n == NULL || node_n->next == NULL) { break; } } //2 } //case3: current time less than the time to next event else { done = 1; //quit the loop } tmp = tmp->next; } //1 //sorting the new entries //LOG_D (OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T // display_job_list (Job_Vector); job_vector[TRACE] = quick_sort (job_vector[TRACE]); /////////// //LOG_D (OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n"); // display_job_list( job_vector[TRACE]); } void get_trace_positions_updated (double cur_time) { double x_now = 0.0, y_now = 0.0; double len, dx, dy; job_list *tmp = job_vector[TRACE]; while (tmp != NULL) { if (tmp->pair->b->mobile == 1 && tmp->pair->next_event_t >= cur_time) { //printf("hiiiiiiiiiii \n"); len = sqrtf (pow (tmp->pair->b->mob->x_from - tmp->pair->b->mob->x_to, 2) + pow (tmp->pair->b->mob->y_from - tmp->pair->b->mob->y_to, 2)); if (len != 0) { dx = fabs (tmp->pair->b->mob->x_from - tmp->pair->b->mob->x_to) / len; dy = fabs (tmp->pair->b->mob->y_from - tmp->pair->b->mob->y_to) / len; //x coordinate if (tmp->pair->b->mob->x_from < tmp->pair->b->mob->x_to) { x_now = tmp->pair->b->mob->x_from + (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey))); } else { x_now = tmp->pair->b->mob->x_from - (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey))); } //y coordinate if (tmp->pair->b->mob->y_from < tmp->pair->b->mob->y_to) { y_now = tmp->pair->b->mob->y_from + (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey))); } else { y_now = tmp->pair->b->mob->y_from - (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey))); } tmp->pair->b->x_pos = (double) ((int) (x_now * 100)) / 100; tmp->pair->b->y_pos = (double) ((int) (y_now * 100)) / 100; } else { tmp->pair->b->x_pos = tmp->pair->b->mob->x_to; tmp->pair->b->y_pos = tmp->pair->b->mob->y_to; } } tmp = tmp->next; } } void clear_list (void) { }