529 lines
15 KiB
C
529 lines
15 KiB
C
/*******************************************************************************
|
|
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)
|
|
{
|
|
|
|
|
|
}
|