Contiki 2.5
routing_epidemic.c
Go to the documentation of this file.
1 /**
2  * \addtogroup routing
3  * @{
4  */
5 
6 /**
7  * \defgroup routing_flooding Flooding Routing module
8  *
9  * @{
10  */
11 
12 /**
13  * \file
14  * \brief implementation of flood routing
15  * \author Georg von Zengen <vonzeng@ibr.cs.tu-bs.de>
16  * \author Wolf-Bastian Poettner <poettner@ibr.cs.tu-bs.de>
17  */
18 
19 #include <string.h>
20 
21 #include "net/netstack.h"
22 #include "net/rime/rimeaddr.h"
23 #include "lib/list.h"
24 #include "lib/memb.h"
25 #include "contiki.h"
26 #include "clock.h"
27 #include "logging.h"
28 
29 #include "bundle.h"
30 #include "storage.h"
31 #include "sdnv.h"
32 #include "agent.h"
33 #include "discovery.h"
34 #include "statistics.h"
35 #include "bundleslot.h"
36 #include "delivery.h"
37 #include "convergence_layer.h"
38 #include "registration.h"
39 
40 #include "routing.h"
41 
42 /**
43  * Internally used return values
44  */
45 #define EPIDEMIC_ROUTE_RETURN_OK 1
46 #define EPIDEMIC_ROUTE_RETURN_CONTINUE 0
47 #define EPIDEMIC_ROUTE_RETURN_FAIL -1
48 
49 struct neighbour_list_entry_t {
50  /** address of the neighbour */
51  rimeaddr_t neighbour;
52 
53  /** bundles that have been sent to the neighbour */
54  uint32_t bundles[ROUTING_BUNDLES_PER_NEIGHBOUR];
55 
56  /** Point to where to *next* bundle number will be stored */
57  uint8_t bundles_pointer;
58 };
59 
60 struct routing_entry_t {
61  /** Pointer to the next entry */
62  struct routing_entry_t * next;
63 
64  /** number of the bundle */
65  uint32_t bundle_number;
66 
67  /** bundle flags */
68  uint8_t flags;
69 
70  /** destination node */
71  uint32_t destination_node;
72 };
73 
74 /**
75  * Routing process
76  */
77 PROCESS(routing_process, "Epidemic ROUTE process");
78 
79 MEMB(routing_bundle_mem, struct routing_entry_t, BUNDLE_STORAGE_SIZE);
80 LIST(routing_bundle_list);
81 
82 MEMB(routing_neighbour_mem, struct neighbour_list_entry_t, ROUTING_NEIGHBOURS);
83 LIST(routing_neigbour_list);
84 
85 /**
86  * \brief called by agent at startup
87  */
89 {
90  // Start CL process
91  process_start(&routing_process, NULL);
92 }
93 
94 /**
95  * \brief Poll our process, so that we can resubmit bundles
96  */
98 {
99  process_poll(&routing_process);
100 }
101 
102 /**
103  * \brief checks for a neighbour in the neighbour list
104  * \param dest pointer to the address of the neighbor
105  * \return pointer to the address list entry, NULL otherwise
106  */
107 struct neighbour_list_entry_t * routing_epidemic_get_neighbour(rimeaddr_t * dest)
108 {
109  struct neighbour_list_entry_t * entry = NULL;
110 
111  for(entry = list_head(routing_neigbour_list);
112  entry != NULL;
113  entry = list_item_next(entry)) {
114  if( rimeaddr_cmp(dest, &entry->neighbour) ) {
115  /* Neighbour is in our list already, no need to store */
116  return entry;
117  }
118  }
119 
120  return NULL;
121 }
122 
123 struct neighbour_list_entry_t * routing_epidemic_create_neighbour(rimeaddr_t * dest)
124 {
125  struct neighbour_list_entry_t * entry = NULL;
126 
127  entry = routing_epidemic_get_neighbour(dest);
128  if( entry != NULL ) {
129  return entry;
130  }
131 
132  /* allocate neighbour list entry */
133  entry = memb_alloc(&routing_neighbour_mem);
134  if( entry == NULL ) {
135  return NULL;
136  }
137 
138  /* Initialize struct */
139  memset(entry, 0, sizeof(struct neighbour_list_entry_t));
140 
141  /* fill in the data */
142  rimeaddr_copy(&entry->neighbour, dest);
143 
144  /* add the struct to the list */
145  list_add(routing_neigbour_list, entry);
146 
147  return entry;
148 }
149 
150 void routing_epidemic_delete_neighbour(rimeaddr_t * dest)
151 {
152  struct neighbour_list_entry_t * entry = NULL;
153 
154  entry = routing_epidemic_get_neighbour(dest);
155  if( entry != NULL ) {
156  return;
157  }
158 
159  /* Remove entry from list */
160  list_remove(routing_neigbour_list, entry);
161 
162  /* Free entry */
163  memb_free(&routing_neighbour_mem, entry);
164 }
165 
166 void routing_epidemic_store_sent_bundle(rimeaddr_t * dest, uint32_t bundle_number)
167 {
168  struct neighbour_list_entry_t * n = NULL;
169  int h;
170 
171  /* Get the neighbour to which we have delivered the bundle */
172  n = routing_epidemic_create_neighbour(dest);
173 
174  /* Look, if we have sent this bundle to the neighbour earlier */
175  for(h=0; h<n->bundles_pointer; h++) {
176  if( n->bundles[h] == bundle_number ) {
177  return;
178  }
179  }
180 
181  /* Note down bundle in list of neighbour */
182  n->bundles[n->bundles_pointer] = bundle_number;
183  n->bundles_pointer ++;
184 }
185 
186 uint8_t routing_epidemic_was_bundle_sent(rimeaddr_t * dest, uint32_t bundle_number)
187 {
188  struct neighbour_list_entry_t * n = NULL;
189  int h;
190 
191  /* Get the neighbour to which we have delivered the bundle */
192  n = routing_epidemic_create_neighbour(dest);
193 
194  /* Look, if we have sent this bundle to the neighbour earlier */
195  for(h=0; h<n->bundles_pointer; h++) {
196  if( n->bundles[h] == bundle_number ) {
197  return 1;
198  }
199  }
200 
201  return 0;
202 }
203 
204 /**
205  * \brief checks if there are bundle to send to dest
206  * \param dest pointer to the address of the new neighbor
207  */
208 void routing_epidemic_new_neighbour(rimeaddr_t *dest)
209 {
210  routing_epidemic_create_neighbour(dest);
211 }
212 
213 
214 /**
215  * \brief Send bundle to neighbour
216  * \param bundle_number Number of the bundle
217  * \param neighbour Address of the neighbour
218  * \return 1 on success, -1 on error
219  */
220 int routing_epidemic_send_bundle(uint32_t bundle_number, rimeaddr_t * neighbour)
221 {
222  struct transmit_ticket_t * ticket = NULL;
223 
224  /* Allocate a transmission ticket */
225  ticket = convergence_layer_get_transmit_ticket();
226  if( ticket == NULL ) {
227  LOG(LOGD_DTN, LOG_ROUTE, LOGL_WRN, "unable to allocate transmit ticket");
228  return -1;
229  }
230 
231  /* Specify which bundle */
232  rimeaddr_copy(&ticket->neighbour, neighbour);
233  ticket->bundle_number = bundle_number;
234 
235  /* Put the bundle in the queue */
236  convergence_layer_enqueue_bundle(ticket);
237 
238  return 1;
239 }
240 
241 /**
242  * \brief Deliver a bundle to a local service
243  * \param entry Pointer to the routing entry of the bundle
244  * \return EPIDEMIC_ROUTE_RETURN_OK if delivered, EPIDEMIC_ROUTE_RETURN_CONTINUE otherwise
245  */
246 int routing_epidemic_send_to_local(struct routing_entry_t * entry)
247 {
248  struct mmem * bundlemem = NULL;
249 
250  // Should this bundle be delivered locally?
251  if( (entry->flags & ROUTING_FLAG_LOCAL) && !(entry->flags & ROUTING_FLAG_IN_DELIVERY) ) {
252  bundlemem = BUNDLE_STORAGE.read_bundle(entry->bundle_number);
253  if( bundlemem == NULL ) {
254  LOG(LOGD_DTN, LOG_ROUTE, LOGL_ERR, "cannot read bundle %lu", entry->bundle_number);
255  return EPIDEMIC_ROUTE_RETURN_CONTINUE;
256  }
257 
258  if( delivery_deliver_bundle(bundlemem) ) {
259  entry->flags |= ROUTING_FLAG_IN_DELIVERY;
260  }
261  }
262 
264 }
265 
266 /**
267  * \brief Forward a bundle to the next hop
268  * \param entry Pointer to the routing entry of the bundle
269  * \return EPIDEMIC_ROUTE_RETURN_OK if queued, EPIDEMIC_ROUTE_RETURN_CONTINUE if not queued and EPIDEMIC_ROUTE_RETURN_FAIL of queue is full
270  */
271 int routing_epidemic_forward(struct routing_entry_t * entry)
272 {
273  struct neighbour_list_entry_t * n = NULL;
274  int h = 0;
275 
276  for( n = list_head(routing_neigbour_list);
277  n != NULL;
278  n = list_item_next(n) ) {
279 
280  if( routing_epidemic_was_bundle_sent(&n->neighbour, entry->bundle_number) ) {
281  continue;
282  }
283 
284  LOG(LOGD_DTN, LOG_ROUTE, LOGL_INF, "send bundle %lu to %u.%u", entry->bundle_number, n->neighbour.u8[0], n->neighbour.u8[1]);
285 
286  /* Mark bundle as busy */
287  entry->flags |= ROUTING_FLAG_IN_TRANSIT;
288 
289  /* And queue it for sending */
290  h = routing_epidemic_send_bundle(entry->bundle_number, &n->neighbour);
291  if( h < 0 ) {
292  /* Enqueuing bundle failed - unblock it */
293  entry->flags &= ~ROUTING_FLAG_IN_TRANSIT;
294 
295  /* If sending the bundle fails, all other will likely also fail */
296  return EPIDEMIC_ROUTE_RETURN_FAIL;
297  }
298 
299  /* Only one bundle at a time */
301  }
302 
303  return EPIDEMIC_ROUTE_RETURN_CONTINUE;
304 }
305 
306 /**
307  * \brief iterate through all bundles and forward bundles
308  */
310 {
311  struct routing_entry_t * n = NULL;
312  int try_to_forward = 1;
313  int h = 0;
314 
315  LOG(LOGD_DTN, LOG_ROUTE, LOGL_DBG, "send to known neighbours");
316 
317  /**
318  * It is likely, that we will have less neighbours than bundles - therefore, we want to to go through bundles only once
319  */
320  for( n = (struct routing_entry_t *) list_head(routing_bundle_list);
321  n != NULL;
322  n = list_item_next(n) ) {
323 
324  /* Is the bundle for local? */
326  /* We do not care about the return value, because we would continue anyway */
327 
328  /* Skip this bundle, if it is not queued for forwarding */
329  if( !(n->flags & ROUTING_FLAG_FORWARD) || (n->flags & ROUTING_FLAG_IN_TRANSIT) || !try_to_forward ) {
330  continue;
331  }
332 
333  /* At this point, we know that the bundle is not for one of our neighbours, so send it to all the others */
335  if( h == EPIDEMIC_ROUTE_RETURN_OK ) {
336  /* Bundle will be forwarded, continue as normal */
337  } else if( h == EPIDEMIC_ROUTE_RETURN_CONTINUE ) {
338  /* Bundle will not be forwarded, continue as normal */
339  } else if( h == EPIDEMIC_ROUTE_RETURN_FAIL ) {
340  /* Enqueuing the bundle failed, to stop the forwarding process */
341  try_to_forward = 0;
342  continue;
343  }
344  }
345 }
346 
347 /**
348  * \brief Wrapper function for agent calls to resubmit bundles for already known neighbours
349  */
352 }
353 
354 /**
355  * \brief Adds a new bundle to the list of bundles
356  * \param bundle_number bundle number of the bundle
357  * \return >0 on success, <0 on error
358  */
359 int routing_epidemic_new_bundle(uint32_t * bundle_number)
360 {
361  struct routing_entry_t * n = NULL;
362  struct mmem * bundlemem = NULL;
363  struct bundle_t * bundle = NULL;
364  uint32_t source_node_eid;
365  rimeaddr_t source_node;
366 
367  LOG(LOGD_DTN, LOG_ROUTE, LOGL_DBG, "agent announces bundle %lu", *bundle_number);
368 
369  // Let us see, if we know this bundle already
370  for( n = list_head(routing_bundle_list);
371  n != NULL;
372  n = list_item_next(n) ) {
373 
374  if( n->bundle_number == *bundle_number ) {
375  LOG(LOGD_DTN, LOG_ROUTE, LOGL_ERR, "agent announces bundle %lu that is already known", *bundle_number);
376  return -1;
377  }
378  }
379 
380  // Notify statistics
382 
383  // Now allocate new memory for the list entry
384  n = memb_alloc(&routing_bundle_mem);
385  if( n == NULL ) {
386  LOG(LOGD_DTN, LOG_ROUTE, LOGL_ERR, "cannot allocate list entry for bundle, please increase BUNDLE_STORAGE_SIZE");
387  return -1;
388  }
389 
390  /* Initialize struct */
391  memset(n, 0, sizeof(struct routing_entry_t));
392 
393  // Now go and request the bundle from storage
394  bundlemem = BUNDLE_STORAGE.read_bundle(*bundle_number);
395  if( bundlemem == NULL ) {
396  LOG(LOGD_DTN, LOG_ROUTE, LOGL_ERR, "unable to read bundle %lu", *bundle_number);
397  memb_free(&routing_bundle_mem, n);
398  return -1;
399  }
400 
401  // Get our bundle struct and check the pointer
402  bundle = (struct bundle_t *) MMEM_PTR(bundlemem);
403  if( bundle == NULL ) {
404  LOG(LOGD_DTN, LOG_ROUTE, LOGL_ERR, "invalid bundle pointer for bundle %lu", *bundle_number);
405  memb_free(&routing_bundle_mem, n);
406  bundle_decrement(bundlemem);
407  return -1;
408  }
409 
410  // Nothing can go wrong anymore, add the (surrounding) struct to the list
411  list_add(routing_bundle_list, n);
412 
413  /* Here we decide if a bundle is to be delivered locally and/or forwarded */
414  if( bundle->dst_node == dtn_node_id ) {
415  /* This bundle is for our node_id, deliver locally */
416  LOG(LOGD_DTN, LOG_ROUTE, LOGL_DBG, "bundle is for local");
417  n->flags |= ROUTING_FLAG_LOCAL;
418  } else {
419  /* This bundle is not (directly) for us and will be forwarded */
420  LOG(LOGD_DTN, LOG_ROUTE, LOGL_DBG, "bundle is for forward");
421  n->flags |= ROUTING_FLAG_FORWARD;
422  }
423 
424  if( !(bundle->flags & BUNDLE_FLAG_SINGLETON) ) {
425  /* Bundle is not Singleton, so forward it in any case */
426  LOG(LOGD_DTN, LOG_ROUTE, LOGL_DBG, "bundle is for forward");
427  n->flags |= ROUTING_FLAG_FORWARD;
428  }
429 
430  if( registration_is_local(bundle->dst_srv, bundle->dst_node) && bundle->dst_node != dtn_node_id) {
431  /* Bundle is for a local registration, so deliver it locally */
432  LOG(LOGD_DTN, LOG_ROUTE, LOGL_DBG, "bundle is for local and forward");
433  n->flags |= ROUTING_FLAG_LOCAL;
434  n->flags |= ROUTING_FLAG_FORWARD;
435  }
436 
437  // Now copy the necessary attributes from the bundle
438  n->bundle_number = *bundle_number;
439  bundle_get_attr(bundlemem, DEST_NODE, &n->destination_node);
440 
441  // Note down, that we have received this bundle from a certain neighbour -> do not send it again
442  bundle_get_attr(bundlemem, SRC_NODE, &source_node_eid);
443  source_node = convert_eid_to_rime(source_node_eid);
444  routing_epidemic_store_sent_bundle(&source_node, *bundle_number);
445  routing_epidemic_store_sent_bundle(&bundle->msrc, *bundle_number);
446 
447  // Now that we have the bundle, we do not need the allocated memory anymore
448  bundle_decrement(bundlemem);
449  bundlemem = NULL;
450  bundle = NULL;
451 
452  // Schedule to deliver and forward the bundle
454 
455  // We do not have a failure here, so it must be a success
456  return 1;
457 }
458 
459 /**
460  * \brief deletes bundle from list
461  * \param bundle_number bundle number of the bundle
462  */
463 void routing_epidemic_delete_bundle(uint32_t bundle_number)
464 {
465  struct routing_entry_t * n = NULL;
466 
467  LOG(LOGD_DTN, LOG_ROUTE, LOGL_DBG, "EPIDEMIC_del_bundle for bundle %lu", bundle_number);
468 
469  // Find the bundle in our internal storage
470  for( n = list_head(routing_bundle_list);
471  n != NULL;
472  n = list_item_next(n) ) {
473 
474  if( n->bundle_number == bundle_number ) {
475  break;
476  }
477  }
478 
479  if( n == NULL ) {
480  LOG(LOGD_DTN, LOG_ROUTE, LOGL_ERR, "epidemic_del_bundle for bundle %lu that we do not know", bundle_number);
481  return;
482  }
483 
484  list_remove(routing_bundle_list, n);
485 
486  // And also free the memory for the list entry
487  memb_free(&routing_bundle_mem, n);
488 }
489 
490 /**
491  * \brief Callback function informing us about the status of a sent bundle
492  * \param ticket CL transmit ticket of the bundle
493  * \param status status code
494  */
495 void routing_epidemic_bundle_sent(struct transmit_ticket_t * ticket, uint8_t status)
496 {
497  struct routing_entry_t * n = NULL;
498 
499  // Tell the agent to call us again to resubmit bundles
501 
502  // Find the bundle in our internal storage
503  for( n = list_head(routing_bundle_list);
504  n != NULL;
505  n = list_item_next(n) ) {
506 
507  if( n->bundle_number == ticket->bundle_number ) {
508  break;
509  }
510  }
511 
512  if( n == NULL ) {
513  LOG(LOGD_DTN, LOG_ROUTE, LOGL_ERR, "Bundle not in storage");
514  return;
515  }
516 
517  /* Bundle is not busy anymore */
518  n->flags &= ~ROUTING_FLAG_IN_TRANSIT;
519 
520  if( status == ROUTING_STATUS_NACK ||
521  status == ROUTING_STATUS_FAIL ) {
522  // NACK = Other side rejected the bundle, try again later
523  // FAIL = Transmission failed
524  // --> note down address in blacklist
525 
526  /* Free up the ticket */
527  convergence_layer_free_transmit_ticket(ticket);
528 
529  return;
530  }
531 
532  if( status == ROUTING_STATUS_ERROR ) {
533  LOG(LOGD_DTN, LOG_ROUTE, LOGL_ERR, "Bundle %lu has fatal error, deleting", ticket->bundle_number);
534 
535  /* Bundle failed permanently, we can delete it because it will never be delivered anyway */
536  n->flags = 0;
537 
538  /* Free up the ticket */
539  convergence_layer_free_transmit_ticket(ticket);
540 
541  return;
542  }
543 
544  // Here: status == ROUTING_STATUS_OK
546 
547  /* Note down, that we have sent the bundle to this neighbour */
548  routing_epidemic_store_sent_bundle(&ticket->neighbour, ticket->bundle_number);
549 
550  /* Free up the ticket */
551  convergence_layer_free_transmit_ticket(ticket);
552 }
553 
554 /**
555  * \brief Incoming notification, that service has finished processing bundle
556  * \param bundlemem Pointer to the MMEM struct of the bundle
557  */
558 void routing_epidemic_bundle_delivered_locally(struct mmem * bundlemem) {
559  struct routing_entry_t * n = NULL;
560  struct bundle_t * bundle = (struct bundle_t *) MMEM_PTR(bundlemem);
561 
562  // Tell the agent to call us again to resubmit bundles
564 
565  if( bundle == NULL ) {
566  LOG(LOGD_DTN, LOG_ROUTE, LOGL_ERR, "EPIDEMIC_locally_delivered called with invalid pointer");
567  return;
568  }
569 
570  // Find the bundle in our internal storage
571  for( n = (struct routing_entry_t *) list_head(routing_bundle_list);
572  n != NULL;
573  n = list_item_next(n) ) {
574 
575  if( n->bundle_number == bundle->bundle_num ) {
576  break;
577  }
578  }
579 
580  if( n == NULL ) {
581  LOG(LOGD_DTN, LOG_ROUTE, LOGL_ERR, "Bundle not in storage yet");
582  return;
583  }
584 
585  // Unset the IN_DELIVERY flag
586  n->flags &= ~ROUTING_FLAG_IN_DELIVERY;
587 
588  // Unset the LOCAL flag
589  n->flags &= ~ROUTING_FLAG_LOCAL;
590 
591  // Unblock the receiving service
592  delivery_unblock_service(bundlemem);
593 
594  // Free the bundle memory
595  bundle_decrement(bundlemem);
596 
597  /* Note down, that we have sent the bundle to this neighbour */
598  routing_epidemic_store_sent_bundle(&rimeaddr_node_addr, bundle->bundle_num);
599 }
600 
601 /**
602  * \brief Routing persistent process
603  */
604 PROCESS_THREAD(routing_process, ev, data)
605 {
606  PROCESS_BEGIN();
607 
608  LOG(LOGD_DTN, LOG_ROUTE, LOGL_INF, "FLOOD ROUTE process in running");
609 
610  /* Initialize memory used to store bundles for routing */
611  memb_init(&routing_bundle_mem);
612  list_init(routing_bundle_list);
613 
614  /* Initialize memory used to store neighbours */
615  memb_init(&routing_neighbour_mem);
616  list_init(routing_neigbour_list);
617 
618  while(1) {
619  PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
620 
622  }
623 
624  PROCESS_END();
625 }
626 
627 const struct routing_driver routing_epidemic ={
628  "EPIDEMIC_route",
636 };
637