trace.c 14.5 KB
Newer Older
1
/*******************************************************************************
nikaeinn's avatar
nikaeinn committed
2
3
    OpenAirInterface
    Copyright(c) 1999 - 2014 Eurecom
4

nikaeinn's avatar
nikaeinn committed
5
6
7
8
    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.
9
10


nikaeinn's avatar
nikaeinn committed
11
12
13
14
    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.
15

nikaeinn's avatar
nikaeinn committed
16
17
18
19
    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/>.
20
21

  Contact Information
nikaeinn's avatar
nikaeinn committed
22
23
24
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
  OpenAirInterface Dev  : openair4g-devel@eurecom.fr
25

nikaeinn's avatar
nikaeinn committed
26
  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
27

nikaeinn's avatar
nikaeinn committed
28
*******************************************************************************/
29
30
/*! \file trace.c
* \brief The trace-based mobility model for OMG/OAI (mobility is statically imported from a file)
31
32
* \author  S. Gashaw, N. Nikaein, J. Harri
* \date 2014
33
* \version 0.1
34
35
* \company EURECOM
* \email: 
36
37
38
39
40
41
42
* \note
* \warning
*/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
43
#include <math.h>
44
#include "trace.h"
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#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");
151
152
153
154

  return 0;
}

155
156
157
158
159
160
161
162
163
164
165
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;
166

167
168
169
170
171
172
173
  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);
174

175
176
  node_vector_end[node->type] =
    (node_list *) add_entry (node, node_vector_end[node->type]);
177

178
179
  if (node_vector[node->type] == NULL)
    node_vector[node->type] = node_vector_end[node->type];
180

181
  node_vector_len[node->type]++;
182
183
184

}

185
186
187
188
189
190
191
192
193
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;
194
  node->mobile = 1;
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
  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;
238
  node->mob->start_journey = cur_time;
239
240
  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);
241
242
243
}


244
245
246
247
248
249
250
251
252
253
254
255
256
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

257
  /* */ 
258
259
260
261
  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;
262
      LOG_D(OMG,"[TRACE] curretn and next lcoation are the same : sleep for %f\n",node->mob->sleep_duration);
263
    }
264
  else /* early arrival*/ 
265
    {				//sleep case 2
266
267
268
      //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);
269
270
271
272
273
274
275
    }

  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);*/

276
277
}

278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296

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);

297
298
299
300
301
302
      
      //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 )
	{
	  if (node_n->next->next == NULL)
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
	{
	  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
370
371
372
      else if (tmp->pair != NULL && cur_time > tmp->pair->next_event_t)
	{
	  if (node_n->next->next == NULL)
373
	{
374
375
376
377
378
379
380
381
382
383
384
	  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;
	}
	  
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
	  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]);
475
476
}

477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553

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;
	    }

554
555
	}
      tmp = tmp->next;
556

557
    }
558

559
560
561

}

562
563
564
565
566
567
568

void
clear_list (void)
{


}