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