48 #include "lib/assert.h"
52 #define RSSI_THRESHOLD -39
56 #define MY_ROUTE_TIMEOUT 0x7fffffff
57 #define MY_NET_DIAMETER 20
59 PROCESS(uaodv_process,
"uAODV");
64 #define SCMP32(a, b) ((int32_t)((a) - (b)))
66 static CC_INLINE uint32_t
67 last_known_seqno(uip_ipaddr_t *host)
69 struct uaodv_rt_entry *route = uaodv_rt_lookup_any(host);
72 return uip_htonl(route->hseqno);
78 static uint32_t rreq_id, my_hseqno;
88 fwc_lookup(
const uip_ipaddr_t *orig,
const uint32_t *
id)
90 unsigned n = (orig->u8[2] + orig->u8[3]) % NFWCACHE;
91 return fwcache[n].id == *
id && uip_ipaddr_cmp(&fwcache[n].orig, orig);
95 fwc_add(
const uip_ipaddr_t *orig,
const uint32_t *
id)
97 unsigned n = (orig->u8[2] + orig->u8[3]) % NFWCACHE;
103 #define PRINTF(...) do {} while (0)
104 #define print_debug(...) do{}while(0)
106 #define PRINTF(...) printf(__VA_ARGS__)
109 print_debug(
const char *fmt, ...)
__attribute__((format(printf, 1, 2)));
112 print_debug(
const char *fmt, ...)
124 #define BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
125 #define uip_udp_sender() (&BUF->srcipaddr)
129 sendto(
const uip_ipaddr_t *dest,
const void *buf,
int len)
140 uip_udp_packet_send(unicastconn, buf, len);
143 #ifdef AODV_BAD_HOP_EXTENSION
145 add_rreq_extensions(
void *_p)
147 struct uaodv_bad_hop_ext *p = _p;
148 uip_ipaddr_t *a = p->addrs;
151 #define SCALE_RETRANS_THRESHOLD (3*4)
153 cc2420_check_remote(0xffff);
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;
163 print_debug(
"BAD HOP %d.%d.%d.%d\t%d\n",
171 p->type = RREQ_BAD_HOP_EXT;
173 return 2 + p->length;
176 #define add_rreq_extensions(p) 0
180 send_rreq(uip_ipaddr_t *addr)
182 struct uaodv_msg_rreq *rm = (
struct uaodv_msg_rreq *)
uip_appdata;
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;
195 rm->rreq_id = uip_htonl(rreq_id++);
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);
207 send_rrep(uip_ipaddr_t *dest, uip_ipaddr_t *nexthop, uip_ipaddr_t *orig,
208 uint32_t *seqno,
unsigned hop_count)
210 struct uaodv_msg_rrep *rm = (
struct uaodv_msg_rrep *)
uip_appdata;
212 print_debug(
"send RREP orig=%d.%d.%d.%d hops=%d\n",
215 rm->type = UAODV_RREP_TYPE;
218 rm->hop_count = hop_count;
220 rm->dest_seqno = *seqno;
222 rm->lifetime = UIP_HTONL(MY_ROUTE_TIMEOUT);
223 sendto(nexthop, rm,
sizeof(
struct uaodv_msg_rrep));
227 send_rerr(uip_ipaddr_t *addr, uint32_t *seqno)
229 struct uaodv_msg_rerr *rm = (
struct uaodv_msg_rerr *)
uip_appdata;
233 rm->type = UAODV_RERR_TYPE;
237 rm->unreach[0].seqno = *seqno;
239 rm->flags = UAODV_RERR_UNKNOWN;
243 uip_udp_packet_send(bcastconn, rm,
sizeof(
struct uaodv_msg_rerr));
247 handle_incoming_rreq(
void)
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;
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",
262 if(uip_ipaddr_cmp(&rm->orig_addr, &uip_hostaddr)) {
268 int ret = cc2420_check_remote(uip_udp_sender()->u16[1]);
270 if(ret == REMOTE_YES) {
271 print_debug(
"RREQ drop is remote\n");
273 }
else if (ret == REMOTE_NO) {
275 }
else if(cc2420_last_rssi < RSSI_THRESHOLD) {
276 print_debug(
"RREQ drop %d %d\n", cc2420_last_rssi,
277 cc2420_last_correlation);
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));
288 (uint8_t *)ext < end;
289 ext = (
void *)((uint8_t *)ext + ext->length + 2)) {
290 uint8_t *eend = (uint8_t *)ext + ext->length;
294 if(ext->type == RREQ_BAD_HOP_EXT) {
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");
308 rt = uaodv_rt_lookup(&rm->orig_addr);
310 || (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) > 0)
311 || (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) == 0
312 && rm->hop_count < rt->hop_count)) {
313 print_debug(
"Inserting1\n");
314 rt = uaodv_rt_add(&rm->orig_addr, uip_udp_sender(),
315 rm->hop_count, &rm->orig_seqno);
319 if(uip_ipaddr_cmp(&rm->dest_addr, &uip_hostaddr)
320 || rm->flags & UAODV_RREQ_DESTONLY) {
323 fw = uaodv_rt_lookup(&rm->dest_addr);
324 if(!(rm->flags & UAODV_RREQ_UNKSEQNO)
326 && SCMP32(fw->hseqno, uip_ntohl(rm->dest_seqno)) <= 0) {
334 print_debug(
"RREQ for known route\n");
337 net_seqno = uip_htonl(fw->hseqno);
338 send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno,
340 }
else if(uip_ipaddr_cmp(&rm->dest_addr, &uip_hostaddr)) {
343 print_debug(
"RREQ for our address\n");
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);
351 my_hseqno = uip_ntohl(rm->dest_seqno) + 1;
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) {
359 if(fwc_lookup(&rm->orig_addr, &rm->rreq_id)) {
360 print_debug(
"RREQ cached, not fwd\n");
363 fwc_add(&rm->orig_addr, &rm->rreq_id);
365 print_debug(
"RREQ fwd\n");
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);
375 handle_incoming_rrep(
void)
377 struct uaodv_msg_rrep *rm = (
struct uaodv_msg_rrep *)
uip_appdata;
378 struct uaodv_rt_entry *rt;
381 if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) {
382 #ifdef AODV_RESPOND_TO_HELLOS
385 int ret = cc2420_check_remote(uip_udp_sender()->u16[1]);
387 if(ret == REMOTE_YES) {
388 print_debug(
"HELLO drop is remote\n");
390 }
else if (ret == REMOTE_NO) {
392 }
else if(cc2420_last_rssi < RSSI_THRESHOLD) {
393 print_debug(
"HELLO drop %d %d\n", cc2420_last_rssi, cc2420_last_correlation);
398 net_seqno = uip_htonl(my_hseqno);
399 send_rrep(&uip_hostaddr, &BUF->srcipaddr, &BUF->srcipaddr, &net_seqno, 0);
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",
412 rt = uaodv_rt_lookup(&rm->dest_addr);
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);
421 cc2420_recv_ok(uip_udp_sender());
422 print_debug(
"RREP recv ok %d %d\n",
423 cc2420_last_rssi, cc2420_last_correlation);
426 print_debug(
"Not inserting\n");
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;
436 sendto(uip_udp_sender(), ack,
sizeof(*ack));
439 rt = uaodv_rt_lookup(&rm->orig_addr);
442 print_debug(
"RREP received, but no route back to originator... :-( \n");
446 if(rm->flags & UAODV_RREP_ACK) {
447 print_debug(
"RREP with ACK request (ignored)!\n");
449 rm->flags &= ~UAODV_RREP_ACK;
456 sendto(&rt->nexthop, rm,
sizeof(
struct uaodv_msg_rrep));
461 handle_incoming_rerr(
void)
463 struct uaodv_msg_rerr *rm = (
struct uaodv_msg_rerr *)
uip_appdata;
464 struct uaodv_rt_entry *rt;
466 print_debug(
"RERR %d.%d.%d.%d -> %d.%d.%d.%d"
467 " unreach=%d.%d.%d.%d seq=%lu\n",
471 uip_ntohl(rm->unreach[0].seqno));
473 if(uip_ipaddr_cmp(&rm->unreach[0].addr, &uip_hostaddr))
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) {
481 if(rm->flags & UAODV_RERR_UNKNOWN) {
482 rm->flags &= ~UAODV_RERR_UNKNOWN;
483 rm->unreach[0].seqno = uip_htonl(rt->hseqno);
485 print_debug(
"RERR rebroadcast\n");
486 uip_udp_packet_send(bcastconn, rm,
sizeof(
struct uaodv_msg_rerr));
492 handle_incoming_packet(
void)
494 struct uaodv_msg *m = (
struct uaodv_msg *)
uip_appdata;
498 case UAODV_RREQ_TYPE:
499 handle_incoming_rreq();
502 case UAODV_RREP_TYPE:
503 handle_incoming_rrep();
506 case UAODV_RERR_TYPE:
507 handle_incoming_rerr();
519 static uip_ipaddr_t bad_dest;
520 static uint32_t bad_seqno;
523 uaodv_bad_dest(uip_ipaddr_t *dest)
525 struct uaodv_rt_entry *rt = uaodv_rt_lookup_any(dest);
531 bad_seqno = uip_htonl(rt->hseqno);
535 command = COMMAND_SEND_RERR;
539 static uip_ipaddr_t rreq_addr;
540 static struct timer next_time;
542 struct uaodv_rt_entry *
543 uaodv_request_route_to(uip_ipaddr_t *host)
545 struct uaodv_rt_entry *route = uaodv_rt_lookup(host);
559 if(command != COMMAND_NONE) {
564 command = COMMAND_SEND_RREQ;
576 printf(
"uaodv_process starting %lu\n", (
unsigned long) my_hseqno);
586 handle_incoming_packet();
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);
596 command = COMMAND_NONE;
601 if(ev == PROCESS_EVENT_MSG) {
607 command = COMMAND_NONE;
608 uaodv_rt_flush_all();
613 printf(
"uaodv_process exiting\n");
uip_len
The length of the packet in the uip_buf buffer.
#define uip_gethostaddr(addr)
Get the IP address of this host.
#define PROCESS_BEGIN()
Define the beginning of a process.
#define uip_newdata()
Is new incoming data available?
#define uip_udp_remove(conn)
Remove a UDP connection.
void timer_set(struct timer *t, clock_time_t interval)
Set a timer.
void __attribute__((interrupt))
This ISR handles most of the business interacting with the 1-wire bus.
#define NULL
The null pointer.
#define uip_poll()
Is the connection being polled by uIP?
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
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.
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
#define PROCESS_END()
Define the end of a process.
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.
#define PROCESS_EXITHANDLER(handler)
Specify an action when a process exits.
#define uip_ipaddr_to_quad(a)
Convert an IP address to four bytes separated by commas.
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
#define PROCESS(name, strname)
Declare a process.
process_event_t tcpip_event
The uIP event.
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.
int timer_expired(struct timer *t)
Check if a timer has expired.
uip_appdata
Pointer to the application data in the packet buffer.
uint8_t ttl
Default time-to-live.
#define CLOCK_SECOND
A second, measured in system clock time.