Files
openairinterface5g/openair2/UTIL/OMG/trace.c
T

556 lines
14 KiB
C

/*******************************************************************************
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.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;
}
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)
{
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, 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)
{
}