Contiki 3.x
uaodv.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2005, Swedish Institute of Computer Science.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  */
32 
33 /**
34  * \file
35  * Micro implementation of the AODV ad hoc routing protocol
36  * \author
37  * Adam Dunkels <adam@sics.se>
38  */
39 
40 #include <stdio.h>
41 #include <stdarg.h>
42 
43 #include "contiki.h"
44 #include "net/ipv4/uaodv-def.h"
45 #include "net/ipv4/uaodv-rt.h"
46 
47 #define NDEBUG
48 #include "lib/assert.h"
49 
50 #ifdef CC2420_RADIO
51 #include "cc2420.h"
52 #define RSSI_THRESHOLD -39 /* accept -39 ... xx */
53 #endif
54 
55 /* This implementation never expires routes!!! */
56 #define MY_ROUTE_TIMEOUT 0x7fffffff /* Should be 0xffffffff! */
57 #define MY_NET_DIAMETER 20
58 
59 PROCESS(uaodv_process, "uAODV");
60 
61 static struct uip_udp_conn *bcastconn, *unicastconn;
62 
63 /* Compare sequence numbers as per RFC 3561. */
64 #define SCMP32(a, b) ((int32_t)((a) - (b)))
65 
66 static CC_INLINE uint32_t
67 last_known_seqno(uip_ipaddr_t *host)
68 {
69  struct uaodv_rt_entry *route = uaodv_rt_lookup_any(host);
70 
71  if(route != NULL)
72  return uip_htonl(route->hseqno);
73 
74  return 0;
75 }
76 
77 
78 static uint32_t rreq_id, my_hseqno; /* In host byte order! */
79 
80 #define NFWCACHE 16
81 
82 static struct {
83  uip_ipaddr_t orig;
84  uint32_t id;
85 } fwcache[NFWCACHE];
86 
87 static CC_INLINE int
88 fwc_lookup(const uip_ipaddr_t *orig, const uint32_t *id)
89 {
90  unsigned n = (orig->u8[2] + orig->u8[3]) % NFWCACHE;
91  return fwcache[n].id == *id && uip_ipaddr_cmp(&fwcache[n].orig, orig);
92 }
93 
94 static CC_INLINE void
95 fwc_add(const uip_ipaddr_t *orig, const uint32_t *id)
96 {
97  unsigned n = (orig->u8[2] + orig->u8[3]) % NFWCACHE;
98  fwcache[n].id = *id;
99  uip_ipaddr_copy(&fwcache[n].orig, orig);
100 }
101 
102 #ifdef NDEBUG
103 #define PRINTF(...) do {} while (0)
104 #define print_debug(...) do{}while(0)
105 #else
106 #define PRINTF(...) printf(__VA_ARGS__)
107 #ifdef __GNUC__
108 static void
109 print_debug(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
110 #endif /* __GNUC__ */
111 static void
112 print_debug(const char *fmt, ...)
113 {
114  va_list ap;
115 
116  va_start(ap, fmt);
117  printf("%d.%d.%d.%d: ", uip_ipaddr_to_quad(&uip_hostaddr));
118  vprintf(fmt, ap);
119  va_end(ap);
120  return;
121 }
122 #endif
123 
124 #define BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
125 #define uip_udp_sender() (&BUF->srcipaddr)
126 
127 /*---------------------------------------------------------------------------*/
128 static void
129 sendto(const uip_ipaddr_t *dest, const void *buf, int len)
130 {
131  /* XXX: this is a HACK! We're updating the uIP UDP connection
132  "unicastconn" so that the destination address is the next-hop,
133  and we're patching the "uip_udp_conn" variable so that it points
134  the this connection instead. THIS IS NOT A NICE WAY TO DO THIS,
135  but it is currently nicer than the alternative (requesting a new
136  poll, and remembering the state, etc.). */
137 
138  uip_ipaddr_copy(&unicastconn->ripaddr, dest);
139  uip_udp_conn = unicastconn;
140  uip_udp_packet_send(unicastconn, buf, len);
141 }
142 /*---------------------------------------------------------------------------*/
143 #ifdef AODV_BAD_HOP_EXTENSION
144 static unsigned
145 add_rreq_extensions(void *_p)
146 {
147  struct uaodv_bad_hop_ext *p = _p;
148  uip_ipaddr_t *a = p->addrs;
149  unsigned i, n;
150 
151 #define SCALE_RETRANS_THRESHOLD (3*4)
152 
153  cc2420_check_remote(0xffff); /* Age table. */
154  n = 0;
155  for (i = 0; i < NNEIGBOURS; i++) {
156  if (neigbours[i].nretrans >= SCALE_RETRANS_THRESHOLD
157  && neigbours[i].mac != 0xffff) {
158  a->u16[0] = uip_hostaddr.u16[0];
159  a->u16[1] = neigbours[i].mac;
160  n++;
161  if(n == 15)
162  break; /* Avoid buffer overrun */
163  print_debug("BAD HOP %d.%d.%d.%d\t%d\n",
164  uip_ipaddr_to_quad(a), neigbours[i].nretrans);
165  }
166  }
167 
168  if(n == 0)
169  return 0;
170 
171  p->type = RREQ_BAD_HOP_EXT;
172  p->length = 2 + 4*n; /* Two unused bytes + addresses */
173  return 2 + p->length; /* Type + len + extension data */
174 }
175 #else
176 #define add_rreq_extensions(p) 0 /* Don't add anything */
177 #endif
178 
179 static void
180 send_rreq(uip_ipaddr_t *addr)
181 {
182  struct uaodv_msg_rreq *rm = (struct uaodv_msg_rreq *)uip_appdata;
183  int len;
184 
185  print_debug("send RREQ for %d.%d.%d.%d\n", uip_ipaddr_to_quad(addr));
186 
187  rm->type = UAODV_RREQ_TYPE;
188  rm->dest_seqno = last_known_seqno(addr);
189  if(rm->dest_seqno == 0)
190  rm->flags = UAODV_RREQ_UNKSEQNO;
191  else
192  rm->flags = 0;
193  rm->reserved = 0;
194  rm->hop_count = 0;
195  rm->rreq_id = uip_htonl(rreq_id++);
196  uip_ipaddr_copy(&rm->dest_addr, addr);
197  uip_gethostaddr(&rm->orig_addr);
198  my_hseqno++; /* Always */
199  rm->orig_seqno = uip_htonl(my_hseqno);
200  bcastconn->ttl = MY_NET_DIAMETER;
201  len = sizeof(struct uaodv_msg_rreq);
202  len += add_rreq_extensions(rm + 1);
203  uip_udp_packet_send(bcastconn, rm, len);
204 }
205 /*---------------------------------------------------------------------------*/
206 static void
207 send_rrep(uip_ipaddr_t *dest, uip_ipaddr_t *nexthop, uip_ipaddr_t *orig,
208  uint32_t *seqno, unsigned hop_count)
209 {
210  struct uaodv_msg_rrep *rm = (struct uaodv_msg_rrep *)uip_appdata;
211 
212  print_debug("send RREP orig=%d.%d.%d.%d hops=%d\n",
213  uip_ipaddr_to_quad(orig), hop_count);
214 
215  rm->type = UAODV_RREP_TYPE;
216  rm->flags = 0;
217  rm->prefix_sz = 0; /* I.e a /32 route. */
218  rm->hop_count = hop_count;
219  uip_ipaddr_copy(&rm->orig_addr, orig);
220  rm->dest_seqno = *seqno;
221  uip_ipaddr_copy(&rm->dest_addr, dest);
222  rm->lifetime = UIP_HTONL(MY_ROUTE_TIMEOUT);
223  sendto(nexthop, rm, sizeof(struct uaodv_msg_rrep));
224 }
225 /*---------------------------------------------------------------------------*/
226 static void
227 send_rerr(uip_ipaddr_t *addr, uint32_t *seqno)
228 {
229  struct uaodv_msg_rerr *rm = (struct uaodv_msg_rerr *)uip_appdata;
230 
231  print_debug("send RERR for %d.%d.%d.%d\n", uip_ipaddr_to_quad(addr));
232 
233  rm->type = UAODV_RERR_TYPE;
234  rm->reserved = 0;
235  rm->dest_count = 1;
236  uip_ipaddr_copy(&rm->unreach[0].addr, addr);
237  rm->unreach[0].seqno = *seqno;
238  if(*seqno == 0)
239  rm->flags = UAODV_RERR_UNKNOWN;
240  else
241  rm->flags = 0;
242 
243  uip_udp_packet_send(bcastconn, rm, sizeof(struct uaodv_msg_rerr));
244 }
245 /*---------------------------------------------------------------------------*/
246 static void
247 handle_incoming_rreq(void)
248 {
249  struct uaodv_msg_rreq *rm = (struct uaodv_msg_rreq *)uip_appdata;
250  uip_ipaddr_t dest_addr, orig_addr;
251  struct uaodv_rt_entry *rt, *fw = NULL;
252 
253  print_debug("RREQ %d.%d.%d.%d -> %d.%d.%d.%d ttl=%u"
254  " orig=%d.%d.%d.%d seq=%lu hops=%u dest=%d.%d.%d.%d seq=%lu\n",
255  uip_ipaddr_to_quad(&BUF->srcipaddr),
256  uip_ipaddr_to_quad(&BUF->destipaddr),
257  BUF->ttl,
258  uip_ipaddr_to_quad(&rm->orig_addr), uip_ntohl(rm->orig_seqno),
259  rm->hop_count,
260  uip_ipaddr_to_quad(&rm->dest_addr), uip_ntohl(rm->dest_seqno));
261 
262  if(uip_ipaddr_cmp(&rm->orig_addr, &uip_hostaddr)) {
263  return; /* RREQ looped back! */
264  }
265 
266 #ifdef CC2420_RADIO
267  {
268  int ret = cc2420_check_remote(uip_udp_sender()->u16[1]);
269 
270  if(ret == REMOTE_YES) {
271  print_debug("RREQ drop is remote\n");
272  return;
273  } else if (ret == REMOTE_NO) {
274  /* Is neigbour, accept it. */
275  } else if(cc2420_last_rssi < RSSI_THRESHOLD) {
276  print_debug("RREQ drop %d %d\n", cc2420_last_rssi,
277  cc2420_last_correlation);
278  return;
279  }
280  }
281 #endif
282 
283 #ifdef AODV_BAD_HOP_EXTENSION
284  if(uip_len > (sizeof(*rm) + 2)) {
285  struct uaodv_bad_hop_ext *ext = (void *)(uip_appdata + sizeof(*rm));
286  uint8_t *end = uip_appdata + uip_len;
287  for(;
288  (uint8_t *)ext < end;
289  ext = (void *)((uint8_t *)ext + ext->length + 2)) {
290  uint8_t *eend = (uint8_t *)ext + ext->length;
291  if(eend > end)
292  eend = end;
293 
294  if(ext->type == RREQ_BAD_HOP_EXT) {
295  uip_ipaddr_t *a;
296  for(a = ext->addrs; (uint8_t *)a < eend; a++) {
297  if(uip_ipaddr_cmp(a, &uip_hostaddr)) {
298  print_debug("BAD_HOP drop\n");
299  return;
300  }
301  }
302  }
303  }
304  }
305 #endif /* AODV_BAD_HOP_EXTENSION */
306 
307  /* New reverse route? */
308  rt = uaodv_rt_lookup(&rm->orig_addr);
309  if(rt == NULL
310  || (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) > 0) /* New route. */
311  || (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) == 0
312  && rm->hop_count < rt->hop_count)) { /* Better route. */
313  print_debug("Inserting1\n");
314  rt = uaodv_rt_add(&rm->orig_addr, uip_udp_sender(),
315  rm->hop_count, &rm->orig_seqno);
316  }
317 
318  /* Check if it is for our address or a fresh route. */
319  if(uip_ipaddr_cmp(&rm->dest_addr, &uip_hostaddr)
320  || rm->flags & UAODV_RREQ_DESTONLY) {
321  fw = NULL;
322  } else {
323  fw = uaodv_rt_lookup(&rm->dest_addr);
324  if(!(rm->flags & UAODV_RREQ_UNKSEQNO)
325  && fw != NULL
326  && SCMP32(fw->hseqno, uip_ntohl(rm->dest_seqno)) <= 0) {
327  fw = NULL;
328  }
329  }
330 
331  if (fw != NULL) {
332  uint32_t net_seqno;
333 
334  print_debug("RREQ for known route\n");
335  uip_ipaddr_copy(&dest_addr, &rm->dest_addr);
336  uip_ipaddr_copy(&orig_addr, &rm->orig_addr);
337  net_seqno = uip_htonl(fw->hseqno);
338  send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno,
339  fw->hop_count + 1);
340  } else if(uip_ipaddr_cmp(&rm->dest_addr, &uip_hostaddr)) {
341  uint32_t net_seqno;
342 
343  print_debug("RREQ for our address\n");
344  uip_ipaddr_copy(&dest_addr, &rm->dest_addr);
345  uip_ipaddr_copy(&orig_addr, &rm->orig_addr);
346 
347  my_hseqno++;
348  if(!(rm->flags & UAODV_RREQ_UNKSEQNO)
349  && SCMP32(my_hseqno, uip_ntohl(rm->dest_seqno)) < 0) {
350  print_debug("New my_hseqno %lu\n", my_hseqno); /* We have rebooted. */
351  my_hseqno = uip_ntohl(rm->dest_seqno) + 1;
352  }
353  net_seqno = uip_htonl(my_hseqno);
354  send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno, 0);
355  } else if(BUF->ttl > 1) {
356  int len;
357 
358  /* Have we seen this RREQ before? */
359  if(fwc_lookup(&rm->orig_addr, &rm->rreq_id)) {
360  print_debug("RREQ cached, not fwd\n");
361  return;
362  }
363  fwc_add(&rm->orig_addr, &rm->rreq_id);
364 
365  print_debug("RREQ fwd\n");
366  rm->hop_count++;
367  bcastconn->ttl = BUF->ttl - 1;
368  len = sizeof(struct uaodv_msg_rreq);
369  len += add_rreq_extensions(rm + 1);
370  uip_udp_packet_send(bcastconn, rm, len);
371  }
372 }
373 /*---------------------------------------------------------------------------*/
374 static void
375 handle_incoming_rrep(void)
376 {
377  struct uaodv_msg_rrep *rm = (struct uaodv_msg_rrep *)uip_appdata;
378  struct uaodv_rt_entry *rt;
379 
380  /* Useless HELLO message? */
381  if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) {
382 #ifdef AODV_RESPOND_TO_HELLOS
383  uint32_t net_seqno;
384 #ifdef CC2420_RADIO
385  int ret = cc2420_check_remote(uip_udp_sender()->u16[1]);
386 
387  if(ret == REMOTE_YES) {
388  print_debug("HELLO drop is remote\n");
389  return;
390  } else if (ret == REMOTE_NO) {
391  /* Is neigbour, accept it. */
392  } else if(cc2420_last_rssi < RSSI_THRESHOLD) {
393  print_debug("HELLO drop %d %d\n", cc2420_last_rssi, cc2420_last_correlation);
394  return;
395  }
396 #endif
397  /* Sometimes it helps to send a non-requested RREP in response! */
398  net_seqno = uip_htonl(my_hseqno);
399  send_rrep(&uip_hostaddr, &BUF->srcipaddr, &BUF->srcipaddr, &net_seqno, 0);
400 #endif
401  return;
402  }
403 
404  print_debug("RREP %d.%d.%d.%d -> %d.%d.%d.%d"
405  " dest=%d.%d.%d.%d seq=%lu hops=%u orig=%d.%d.%d.%d\n",
406  uip_ipaddr_to_quad(&BUF->srcipaddr),
407  uip_ipaddr_to_quad(&BUF->destipaddr),
408  uip_ipaddr_to_quad(&rm->dest_addr), uip_ntohl(rm->dest_seqno),
409  rm->hop_count,
410  uip_ipaddr_to_quad(&rm->orig_addr));
411 
412  rt = uaodv_rt_lookup(&rm->dest_addr);
413 
414  /* New forward route? */
415  if(rt == NULL || (SCMP32(uip_ntohl(rm->dest_seqno), rt->hseqno) > 0)) {
416  print_debug("Inserting3\n");
417  rt = uaodv_rt_add(&rm->dest_addr, uip_udp_sender(),
418  rm->hop_count, &rm->dest_seqno);
419 #ifdef CC2420_RADIO
420  /* This link is ok since he is unicasting back to us! */
421  cc2420_recv_ok(uip_udp_sender());
422  print_debug("RREP recv ok %d %d\n",
423  cc2420_last_rssi, cc2420_last_correlation);
424 #endif
425  } else {
426  print_debug("Not inserting\n");
427  }
428 
429  /* Forward RREP towards originator? */
430  if(uip_ipaddr_cmp(&rm->orig_addr, &uip_hostaddr)) {
431  print_debug("ROUTE FOUND\n");
432  if(rm->flags & UAODV_RREP_ACK) {
433  struct uaodv_msg_rrep_ack *ack = (void *)uip_appdata;
434  ack->type = UAODV_RREP_ACK_TYPE;
435  ack->reserved = 0;
436  sendto(uip_udp_sender(), ack, sizeof(*ack));
437  }
438  } else {
439  rt = uaodv_rt_lookup(&rm->orig_addr);
440 
441  if(rt == NULL) {
442  print_debug("RREP received, but no route back to originator... :-( \n");
443  return;
444  }
445 
446  if(rm->flags & UAODV_RREP_ACK) {
447  print_debug("RREP with ACK request (ignored)!\n");
448  /* Don't want any RREP-ACKs in return! */
449  rm->flags &= ~UAODV_RREP_ACK;
450  }
451 
452  rm->hop_count++;
453 
454  print_debug("Fwd RREP to %d.%d.%d.%d\n", uip_ipaddr_to_quad(&rt->nexthop));
455 
456  sendto(&rt->nexthop, rm, sizeof(struct uaodv_msg_rrep));
457  }
458 }
459 /*---------------------------------------------------------------------------*/
460 static void
461 handle_incoming_rerr(void)
462 {
463  struct uaodv_msg_rerr *rm = (struct uaodv_msg_rerr *)uip_appdata;
464  struct uaodv_rt_entry *rt;
465 
466  print_debug("RERR %d.%d.%d.%d -> %d.%d.%d.%d"
467  " unreach=%d.%d.%d.%d seq=%lu\n",
468  uip_ipaddr_to_quad(&BUF->srcipaddr),
469  uip_ipaddr_to_quad(&BUF->destipaddr),
470  uip_ipaddr_to_quad((uip_ipaddr_t *)&rm->unreach[0]),
471  uip_ntohl(rm->unreach[0].seqno));
472 
473  if(uip_ipaddr_cmp(&rm->unreach[0].addr, &uip_hostaddr))
474  return;
475 
476  rt = uaodv_rt_lookup_any(&rm->unreach[0].addr);
477  if(rt != NULL && uip_ipaddr_cmp(&rt->nexthop, uip_udp_sender())) {
478  if((rm->flags & UAODV_RERR_UNKNOWN) || rm->unreach[0].seqno == 0
479  || SCMP32(rt->hseqno, uip_ntohl(rm->unreach[0].seqno)) <= 0) {
480  rt->is_bad = 1;
481  if(rm->flags & UAODV_RERR_UNKNOWN) {
482  rm->flags &= ~UAODV_RERR_UNKNOWN;
483  rm->unreach[0].seqno = uip_htonl(rt->hseqno);
484  }
485  print_debug("RERR rebroadcast\n");
486  uip_udp_packet_send(bcastconn, rm, sizeof(struct uaodv_msg_rerr));
487  }
488  }
489 }
490 /*---------------------------------------------------------------------------*/
491 static void
492 handle_incoming_packet(void)
493 {
494  struct uaodv_msg *m = (struct uaodv_msg *)uip_appdata;
495 
496  /* print_debug("New UDP data, AODV packet type %d\n", m->type);*/
497  switch(m->type) {
498  case UAODV_RREQ_TYPE:
499  handle_incoming_rreq();
500  break;
501 
502  case UAODV_RREP_TYPE:
503  handle_incoming_rrep();
504  break;
505 
506  case UAODV_RERR_TYPE:
507  handle_incoming_rerr();
508  break;
509  }
510 
511 }
512 /*---------------------------------------------------------------------------*/
513 static enum {
514  COMMAND_NONE,
515  COMMAND_SEND_RREQ,
516  COMMAND_SEND_RERR,
517 } command;
518 
519 static uip_ipaddr_t bad_dest;
520 static uint32_t bad_seqno; /* In network byte order! */
521 
522 void
523 uaodv_bad_dest(uip_ipaddr_t *dest)
524 {
525  struct uaodv_rt_entry *rt = uaodv_rt_lookup_any(dest);
526 
527  if(rt == NULL)
528  bad_seqno = 0; /* Or flag this in RERR? */
529  else {
530  rt->is_bad = 1;
531  bad_seqno = uip_htonl(rt->hseqno);
532  }
533 
534  uip_ipaddr_copy(&bad_dest, dest);
535  command = COMMAND_SEND_RERR;
536  process_post(&uaodv_process, PROCESS_EVENT_MSG, NULL);
537 }
538 
539 static uip_ipaddr_t rreq_addr;
540 static struct timer next_time;
541 
542 struct uaodv_rt_entry *
543 uaodv_request_route_to(uip_ipaddr_t *host)
544 {
545  struct uaodv_rt_entry *route = uaodv_rt_lookup(host);
546 
547  if(route != NULL) {
548  uaodv_rt_lru(route);
549  return route;
550  }
551 
552  /*
553  * Broadcast protocols must be rate-limited!
554  */
555  if(!timer_expired(&next_time)) {
556  return NULL;
557  }
558 
559  if(command != COMMAND_NONE) {
560  return NULL;
561  }
562 
563  uip_ipaddr_copy(&rreq_addr, host);
564  command = COMMAND_SEND_RREQ;
565  process_post(&uaodv_process, PROCESS_EVENT_MSG, NULL);
566  timer_set(&next_time, CLOCK_SECOND/8); /* Max 10/s per RFC3561. */
567  return NULL;
568 }
569 
570 PROCESS_THREAD(uaodv_process, ev, data)
571 {
572  PROCESS_EXITHANDLER(goto exit);
573 
574  PROCESS_BEGIN();
575 
576  printf("uaodv_process starting %lu\n", (unsigned long) my_hseqno);
577 
578  bcastconn = udp_broadcast_new(UIP_HTONS(UAODV_UDPPORT), NULL);
579  unicastconn = udp_broadcast_new(UIP_HTONS(UAODV_UDPPORT), NULL);
580 
581  while(1) {
583 
584  if(ev == tcpip_event) {
585  if(uip_newdata()) {
586  handle_incoming_packet();
587  continue;
588  }
589  if(uip_poll()) {
590  if(command == COMMAND_SEND_RREQ) {
591  if(uaodv_rt_lookup(&rreq_addr) == NULL)
592  send_rreq(&rreq_addr);
593  } else if (command == COMMAND_SEND_RERR) {
594  send_rerr(&bad_dest, &bad_seqno);
595  }
596  command = COMMAND_NONE;
597  continue;
598  }
599  }
600 
601  if(ev == PROCESS_EVENT_MSG) {
602  tcpip_poll_udp(bcastconn);
603  }
604  }
605 
606  exit:
607  command = COMMAND_NONE;
608  uaodv_rt_flush_all();
609  uip_udp_remove(bcastconn);
610  bcastconn = NULL;
611  uip_udp_remove(unicastconn);
612  unicastconn = NULL;
613  printf("uaodv_process exiting\n");
614  PROCESS_END();
615 }
616 /*---------------------------------------------------------------------------*/
uip_len
The length of the packet in the uip_buf buffer.
Definition: tcp_loader.c:75
#define uip_gethostaddr(addr)
Get the IP address of this host.
Definition: uip.h:215
A timer.
Definition: timer.h:86
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
#define uip_newdata()
Is new incoming data available?
Definition: uip.h:738
#define uip_udp_remove(conn)
Remove a UDP connection.
Definition: uip.h:876
void timer_set(struct timer *t, clock_time_t interval)
Set a timer.
Definition: timer.c:64
void __attribute__((interrupt))
This ISR handles most of the business interacting with the 1-wire bus.
Definition: onewire.c:174
#define NULL
The null pointer.
#define uip_poll()
Is the connection being polled by uIP?
Definition: uip.h:817
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
Definition: uip.h:1238
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
Definition: process.c:322
CCIF void tcpip_poll_udp(struct uip_udp_conn *conn)
Cause a specified UDP connection to be polled.
uip_ipaddr_t ripaddr
The IP address of the remote peer.
Definition: uip.h:1395
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
Definition: process.h:273
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
struct uip_udp_conn * udp_broadcast_new(uint16_t port, void *appstate)
Create a new UDP broadcast connection.
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
Definition: uip.h:1026
#define PROCESS_EXITHANDLER(handler)
Specify an action when a process exits.
Definition: process.h:254
#define uip_ipaddr_to_quad(a)
Convert an IP address to four bytes separated by commas.
Definition: uip.h:927
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
Definition: process.h:141
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
process_event_t tcpip_event
The uIP event.
Definition: tcpip.c:75
Routing tables for the micro implementation of the AODV ad hoc routing protocol ...
Definitions for the micro implementation of the AODV ad hoc routing protocol ...
Representation of a uIP UDP connection.
Definition: uip.h:1394
int timer_expired(struct timer *t)
Check if a timer has expired.
Definition: timer.c:121
uip_appdata
Pointer to the application data in the packet buffer.
Definition: tcp_loader.c:74
uint8_t ttl
Default time-to-live.
Definition: uip.h:1398
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82