49 #include "lib/assert.h"
53 #define RSSI_THRESHOLD -39
57 #define MY_ROUTE_TIMEOUT 0x7fffffff
58 #define MY_NET_DIAMETER 20
60 PROCESS(uaodv_process,
"uAODV");
65 #define SCMP32(a, b) ((s32_t)((a) - (b)))
67 static CC_INLINE u32_t
70 struct uaodv_rt_entry *route = uaodv_rt_lookup_any(host);
73 return uip_htonl(route->hseqno);
79 static u32_t rreq_id, my_hseqno;
91 unsigned n = (orig->u8[2] + orig->u8[3]) % NFWCACHE;
92 return fwcache[n].id == *
id &&
uip_ipaddr_cmp(&fwcache[n].orig, orig);
98 unsigned n = (orig->u8[2] + orig->u8[3]) % NFWCACHE;
104 #define PRINTF(...) do {} while (0)
105 #define print_debug(...) do{}while(0)
107 #define PRINTF(...) printf(__VA_ARGS__)
110 print_debug(
const char *fmt, ...)
__attribute__((format(printf, 1, 2)));
113 print_debug(
const char *fmt, ...)
125 #define BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
126 #define uip_udp_sender() (&BUF->srcipaddr)
130 sendto(
const uip_ipaddr_t *dest,
const void *buf,
int len)
141 uip_udp_packet_send(unicastconn, buf, len);
144 #ifdef AODV_BAD_HOP_EXTENSION
146 add_rreq_extensions(
void *_p)
148 struct uaodv_bad_hop_ext *p = _p;
152 #define SCALE_RETRANS_THRESHOLD (3*4)
154 cc2420_check_remote(0xffff);
156 for (i = 0; i < NNEIGBOURS; i++) {
157 if (neigbours[i].nretrans >= SCALE_RETRANS_THRESHOLD
158 && neigbours[i].mac != 0xffff) {
159 a->u16[0] = uip_hostaddr.u16[0];
160 a->u16[1] = neigbours[i].mac;
164 print_debug(
"BAD HOP %d.%d.%d.%d\t%d\n",
172 p->type = RREQ_BAD_HOP_EXT;
174 return 2 + p->length;
177 #define add_rreq_extensions(p) 0
183 struct uaodv_msg_rreq *rm = (
struct uaodv_msg_rreq *)
uip_appdata;
188 rm->type = UAODV_RREQ_TYPE;
189 rm->dest_seqno = last_known_seqno(addr);
190 if(rm->dest_seqno == 0)
191 rm->flags = UAODV_RREQ_UNKSEQNO;
196 rm->rreq_id = uip_htonl(rreq_id++);
200 rm->orig_seqno = uip_htonl(my_hseqno);
201 bcastconn->
ttl = MY_NET_DIAMETER;
202 len =
sizeof(
struct uaodv_msg_rreq);
203 len += add_rreq_extensions(rm + 1);
204 uip_udp_packet_send(bcastconn, rm, len);
209 u32_t *seqno,
unsigned hop_count)
211 struct uaodv_msg_rrep *rm = (
struct uaodv_msg_rrep *)
uip_appdata;
213 print_debug(
"send RREP orig=%d.%d.%d.%d hops=%d\n",
216 rm->type = UAODV_RREP_TYPE;
219 rm->hop_count = hop_count;
221 rm->dest_seqno = *seqno;
223 rm->lifetime = UIP_HTONL(MY_ROUTE_TIMEOUT);
224 sendto(nexthop, rm,
sizeof(
struct uaodv_msg_rrep));
230 struct uaodv_msg_rerr *rm = (
struct uaodv_msg_rerr *)
uip_appdata;
234 rm->type = UAODV_RERR_TYPE;
238 rm->unreach[0].seqno = *seqno;
240 rm->flags = UAODV_RERR_UNKNOWN;
244 uip_udp_packet_send(bcastconn, rm,
sizeof(
struct uaodv_msg_rerr));
248 handle_incoming_rreq(
void)
250 struct uaodv_msg_rreq *rm = (
struct uaodv_msg_rreq *)
uip_appdata;
252 struct uaodv_rt_entry *rt, *fw =
NULL;
254 print_debug(
"RREQ %d.%d.%d.%d -> %d.%d.%d.%d ttl=%u"
255 " orig=%d.%d.%d.%d seq=%lu hops=%u dest=%d.%d.%d.%d seq=%lu\n",
269 int ret = cc2420_check_remote(uip_udp_sender()->u16[1]);
271 if(ret == REMOTE_YES) {
272 print_debug(
"RREQ drop is remote\n");
274 }
else if (ret == REMOTE_NO) {
276 }
else if(cc2420_last_rssi < RSSI_THRESHOLD) {
277 print_debug(
"RREQ drop %d %d\n", cc2420_last_rssi,
278 cc2420_last_correlation);
284 #ifdef AODV_BAD_HOP_EXTENSION
285 if(
uip_len > (
sizeof(*rm) + 2)) {
286 struct uaodv_bad_hop_ext *ext = (
void *)(
uip_appdata +
sizeof(*rm));
290 ext = (
void *)((u8_t *)ext + ext->length + 2)) {
291 u8_t *eend = (u8_t *)ext + ext->length;
295 if(ext->type == RREQ_BAD_HOP_EXT) {
297 for(a = ext->addrs; (u8_t *)a < eend; a++) {
299 print_debug(
"BAD_HOP drop\n");
309 rt = uaodv_rt_lookup(&rm->orig_addr);
311 || (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) > 0)
312 || (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) == 0
313 && rm->hop_count < rt->hop_count)) {
314 print_debug(
"Inserting1\n");
315 rt = uaodv_rt_add(&rm->orig_addr, uip_udp_sender(),
316 rm->hop_count, &rm->orig_seqno);
321 || rm->flags & UAODV_RREQ_DESTONLY) {
324 fw = uaodv_rt_lookup(&rm->dest_addr);
325 if(!(rm->flags & UAODV_RREQ_UNKSEQNO)
327 && SCMP32(fw->hseqno, uip_ntohl(rm->dest_seqno)) <= 0) {
335 print_debug(
"RREQ for known route\n");
338 net_seqno = uip_htonl(fw->hseqno);
339 send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno,
344 print_debug(
"RREQ for our address\n");
349 if(!(rm->flags & UAODV_RREQ_UNKSEQNO)
350 && SCMP32(my_hseqno, uip_ntohl(rm->dest_seqno)) < 0) {
351 print_debug(
"New my_hseqno %lu\n", my_hseqno);
352 my_hseqno = uip_ntohl(rm->dest_seqno) + 1;
354 net_seqno = uip_htonl(my_hseqno);
355 send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno, 0);
356 }
else if(BUF->ttl > 1) {
360 if(fwc_lookup(&rm->orig_addr, &rm->rreq_id)) {
361 print_debug(
"RREQ cached, not fwd\n");
364 fwc_add(&rm->orig_addr, &rm->rreq_id);
366 print_debug(
"RREQ fwd\n");
368 bcastconn->
ttl = BUF->ttl - 1;
369 len =
sizeof(
struct uaodv_msg_rreq);
370 len += add_rreq_extensions(rm + 1);
371 uip_udp_packet_send(bcastconn, rm, len);
376 handle_incoming_rrep(
void)
378 struct uaodv_msg_rrep *rm = (
struct uaodv_msg_rrep *)
uip_appdata;
379 struct uaodv_rt_entry *rt;
383 #ifdef AODV_RESPOND_TO_HELLOS
386 int ret = cc2420_check_remote(uip_udp_sender()->u16[1]);
388 if(ret == REMOTE_YES) {
389 print_debug(
"HELLO drop is remote\n");
391 }
else if (ret == REMOTE_NO) {
393 }
else if(cc2420_last_rssi < RSSI_THRESHOLD) {
394 print_debug(
"HELLO drop %d %d\n", cc2420_last_rssi, cc2420_last_correlation);
399 net_seqno = uip_htonl(my_hseqno);
400 send_rrep(&uip_hostaddr, &BUF->srcipaddr, &BUF->srcipaddr, &net_seqno, 0);
405 print_debug(
"RREP %d.%d.%d.%d -> %d.%d.%d.%d"
406 " dest=%d.%d.%d.%d seq=%lu hops=%u orig=%d.%d.%d.%d\n",
413 rt = uaodv_rt_lookup(&rm->dest_addr);
416 if(rt ==
NULL || (SCMP32(uip_ntohl(rm->dest_seqno), rt->hseqno) > 0)) {
417 print_debug(
"Inserting3\n");
418 rt = uaodv_rt_add(&rm->dest_addr, uip_udp_sender(),
419 rm->hop_count, &rm->dest_seqno);
422 cc2420_recv_ok(uip_udp_sender());
423 print_debug(
"RREP recv ok %d %d\n",
424 cc2420_last_rssi, cc2420_last_correlation);
427 print_debug(
"Not inserting\n");
432 print_debug(
"ROUTE FOUND\n");
433 if(rm->flags & UAODV_RREP_ACK) {
434 struct uaodv_msg_rrep_ack *ack = (
void *)
uip_appdata;
435 ack->type = UAODV_RREP_ACK_TYPE;
437 sendto(uip_udp_sender(), ack,
sizeof(*ack));
440 rt = uaodv_rt_lookup(&rm->orig_addr);
443 print_debug(
"RREP received, but no route back to originator... :-( \n");
447 if(rm->flags & UAODV_RREP_ACK) {
448 print_debug(
"RREP with ACK request (ignored)!\n");
450 rm->flags &= ~UAODV_RREP_ACK;
457 sendto(&rt->nexthop, rm,
sizeof(
struct uaodv_msg_rrep));
462 handle_incoming_rerr(
void)
464 struct uaodv_msg_rerr *rm = (
struct uaodv_msg_rerr *)
uip_appdata;
465 struct uaodv_rt_entry *rt;
467 print_debug(
"RERR %d.%d.%d.%d -> %d.%d.%d.%d"
468 " unreach=%d.%d.%d.%d seq=%lu\n",
472 uip_ntohl(rm->unreach[0].seqno));
477 rt = uaodv_rt_lookup_any(&rm->unreach[0].addr);
479 if((rm->flags & UAODV_RERR_UNKNOWN) || rm->unreach[0].seqno == 0
480 || SCMP32(rt->hseqno, uip_ntohl(rm->unreach[0].seqno)) <= 0) {
482 if(rm->flags & UAODV_RERR_UNKNOWN) {
483 rm->flags &= ~UAODV_RERR_UNKNOWN;
484 rm->unreach[0].seqno = uip_htonl(rt->hseqno);
486 print_debug(
"RERR rebroadcast\n");
487 uip_udp_packet_send(bcastconn, rm,
sizeof(
struct uaodv_msg_rerr));
493 handle_incoming_packet(
void)
495 struct uaodv_msg *m = (
struct uaodv_msg *)
uip_appdata;
499 case UAODV_RREQ_TYPE:
500 handle_incoming_rreq();
503 case UAODV_RREP_TYPE:
504 handle_incoming_rrep();
507 case UAODV_RERR_TYPE:
508 handle_incoming_rerr();
521 static u32_t bad_seqno;
526 struct uaodv_rt_entry *rt = uaodv_rt_lookup_any(dest);
532 bad_seqno = uip_htonl(rt->hseqno);
536 command = COMMAND_SEND_RERR;
541 static struct timer next_time;
543 struct uaodv_rt_entry *
546 struct uaodv_rt_entry *route = uaodv_rt_lookup(host);
560 if(command != COMMAND_NONE) {
565 command = COMMAND_SEND_RREQ;
577 printf(
"uaodv_process starting %lu\n", (
unsigned long) my_hseqno);
587 handle_incoming_packet();
591 if(command == COMMAND_SEND_RREQ) {
592 if(uaodv_rt_lookup(&rreq_addr) ==
NULL)
593 send_rreq(&rreq_addr);
594 }
else if (command == COMMAND_SEND_RERR) {
595 send_rerr(&bad_dest, &bad_seqno);
597 command = COMMAND_NONE;
602 if(ev == PROCESS_EVENT_MSG) {
608 command = COMMAND_NONE;
609 uaodv_rt_flush_all();
614 printf(
"uaodv_process exiting\n");