From 2ef8c91bbc6c9bb9ec7a4566cb9ce80c22565340 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Thu, 22 Mar 2007 17:34:16 +0000 Subject: [PATCH] Refactored the mesh code by splitting multi-hop forwarding and route discovery. The mesh module is now much simpler than before --- core/net/rime/mesh.c | 288 +++++++------------------------- core/net/rime/mesh.h | 28 +++- core/net/rime/route-discovery.c | 244 +++++++++++++++++++++++++++ core/net/rime/route-discovery.h | 73 ++++++++ 4 files changed, 393 insertions(+), 240 deletions(-) create mode 100644 core/net/rime/route-discovery.c create mode 100644 core/net/rime/route-discovery.h diff --git a/core/net/rime/mesh.c b/core/net/rime/mesh.c index 9200ea2e0..5b8d5989a 100644 --- a/core/net/rime/mesh.c +++ b/core/net/rime/mesh.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: mesh.c,v 1.4 2007/03/19 22:10:17 adamdunkels Exp $ + * $Id: mesh.c,v 1.5 2007/03/22 17:34:16 adamdunkels Exp $ */ /** @@ -41,12 +41,9 @@ #include "contiki.h" #include "net/rime.h" #include "net/rime/route.h" +#include "net/rime/mesh.h" -struct route_msg { - rimeaddr_t dest; - u8_t rreq_id; - u8_t pad; -}; +#include /* For offsetof */ struct data_hdr { rimeaddr_t dest; @@ -54,28 +51,7 @@ struct data_hdr { u16_t seqno; }; -struct rrep_hdr { - u8_t rreq_id; - u8_t hops; - rimeaddr_t dest; - rimeaddr_t originator; -}; - -struct mesh_conn { - struct uc_conn dataconn; - struct uc_conn rrepconn; - struct nf_conn rreqconn; - rimeaddr_t last_rreq_originator; - u16_t last_rreq_id; - u16_t rreq_id; - struct queuebuf *queued_data; - rimeaddr_t queued_data_dest; - const struct mesh_callbacks *cb; -}; - -static struct mesh_conn mc; - -static void (* send_datapacket_handler)(rimeaddr_t *next) = NULL; +#define PACKET_TIMEOUT (CLOCK_SECOND * 4) #define DEBUG 0 #if DEBUG @@ -87,238 +63,86 @@ static void (* send_datapacket_handler)(rimeaddr_t *next) = NULL; /*---------------------------------------------------------------------------*/ static void -send_rreq(rimeaddr_t *dest) +data_packet_received(struct mh_conn *mh, rimeaddr_t *from) { - struct route_msg *msg; + struct mesh_conn *c = (struct mesh_conn *) + ((char *)mh - offsetof(struct mesh_conn, mh)); - rimebuf_clear(); - msg = rimebuf_dataptr(); - rimebuf_set_datalen(sizeof(struct route_msg)); - - msg->pad = 0; - msg->rreq_id = mc.rreq_id; - rimeaddr_copy(&msg->dest, dest); - - nf_send(&mc.rreqconn); -} -/*---------------------------------------------------------------------------*/ -static void -send_data(rimeaddr_t *to, struct route_entry *next) -{ - struct data_hdr *hdr; - - if(rimebuf_hdrextend(sizeof(struct data_hdr))) { - hdr = rimebuf_hdrptr(); - rimeaddr_copy(&hdr->dest, to); - rimeaddr_copy(&hdr->originator, &rimeaddr_node_addr); - uc_send(&mc.dataconn, &next->nexthop); + if(c->cb->recv) { + c->cb->recv(c, from); } } /*---------------------------------------------------------------------------*/ static void -send_rrep(rimeaddr_t *dest) +found_route(struct route_discovery_conn *rdc, rimeaddr_t *dest) { - struct rrep_hdr *rrepmsg; - struct route_entry *rt; - - rimebuf_clear(); - rrepmsg = rimebuf_dataptr(); - rimebuf_set_datalen(sizeof(struct data_hdr)); - rrepmsg->hops = 0; - rimeaddr_copy(&rrepmsg->dest, dest); - rimeaddr_copy(&rrepmsg->originator, &rimeaddr_node_addr); - rt = route_lookup(dest); - if(rt != NULL) { - PRINTF("send_rrep to %d via %d\n", dest->u16, rt->nexthop.u16); - uc_send(&mc.rrepconn, &rt->nexthop); + struct mesh_conn *c = (struct mesh_conn *) + ((char *)rdc - offsetof(struct mesh_conn, route_discovery_conn)); + + if(rimeaddr_cmp(dest, &c->queued_data_dest)) { + queuebuf_to_rimebuf(c->queued_data); + queuebuf_free(c->queued_data); + c->queued_data = NULL; + mh_send(&c->mh, dest); } } /*---------------------------------------------------------------------------*/ static void -insert_route(rimeaddr_t *originator, rimeaddr_t *last_hop, u8_t hops) +route_timed_out(struct route_discovery_conn *rdc) { - struct route_entry *rt; - - rt = route_lookup(originator); - if(rt == NULL || hops < rt->hop_count) { - PRINTF("%d: Inserting %d into routing table, next hop %d, hop count %d\n", - rimeaddr_node_addr.u16, originator->u16, last_hop->u16, hops); - route_add(originator, last_hop, hops, 0); + struct mesh_conn *c = (struct mesh_conn *) + ((char *)rdc - offsetof(struct mesh_conn, route_discovery_conn)); + + if(c->queued_data != NULL) { + queuebuf_free(c->queued_data); + } + + if(c->cb->timedout) { + c->cb->timedout(c); } } /*---------------------------------------------------------------------------*/ -static rimeaddr_t * -handle_datapacket(rimeaddr_t *from) -{ - struct data_hdr *msg = rimebuf_dataptr(); - struct route_entry *rt; - rimeaddr_t dest; - - PRINTF("data_packet_received from %d towards %d len %d\n", from->u16, - msg->dest.u16, - rimebuf_datalen()); - - /* insert_route(msg->originator, from, msg->hops);*/ - - if(rimeaddr_cmp(&msg->dest, &rimeaddr_node_addr)) { - PRINTF("for us!\n"); - rimebuf_hdrreduce(sizeof(struct data_hdr)); - mc.cb->recv(&msg->originator); - } else { - rimeaddr_copy(&dest, &msg->dest); - - rt = route_lookup(&msg->dest); - if(rt != NULL) { - PRINTF("forwarding to %d\n", rt->nexthop.u16); - /* msg->hops++;*/ - return &rt->nexthop; - /* uc_send(c, &rt->nexthop);*/ - } else { - PRINTF("%d: no route to %d\n", rimeaddr_node_addr.u16, msg->dest.u16); - } - } - return NULL; -} +static const struct mh_callbacks data_callbacks = { data_packet_received, NULL }; +static const struct route_discovery_callbacks route_discovery_callbacks = + { found_route, route_timed_out }; /*---------------------------------------------------------------------------*/ -static void -data_packet_received(struct uc_conn *c, rimeaddr_t *from) +void +mesh_open(struct mesh_conn *c, u16_t channels, + const struct mesh_callbacks *callbacks) { - rimeaddr_t *forward; - forward = handle_datapacket(from); - - if(forward) { - uc_send(c, forward); - } + mh_open(&c->mh, channels, &data_callbacks); + route_discovery_open(&c->route_discovery_conn, channels + 1, + &route_discovery_callbacks); + c->cb = callbacks; } /*---------------------------------------------------------------------------*/ void -mesh_data_received(rimeaddr_t *from) +mesh_close(struct mesh_conn *c) { - rimeaddr_t *nexthop_addr; - nexthop_addr = handle_datapacket(from); - - if(nexthop_addr && send_datapacket_handler) { - send_datapacket_handler(nexthop_addr); - } -} -/*---------------------------------------------------------------------------*/ -static void -rrep_packet_received(struct uc_conn *c, rimeaddr_t *from) -{ - struct rrep_hdr *msg = rimebuf_dataptr(); - struct route_entry *rt; - rimeaddr_t dest; - - PRINTF("rrep_packet_received from %d towards %d len %d\n", from->u16, - msg->dest.u16, - rimebuf_datalen()); - - insert_route(&msg->originator, from, msg->hops); - - if(rimeaddr_cmp(&msg->dest, &rimeaddr_node_addr)) { - PRINTF("for us!\n"); - if(rimeaddr_cmp(&msg->originator, &mc.queued_data_dest) && - mc.queued_data != NULL) { - PRINTF("Got RREP for us from %d. queued packet to %d\n", - msg->originator.u16, mc.queued_data_dest.u16); - - queuebuf_to_rimebuf(mc.queued_data); - mc.queued_data = NULL; - rt = route_lookup(&mc.queued_data_dest); - if(rt != NULL) { - PRINTF("Sending data to %d through %d\n", mc.queued_data_dest.u16, - rt->nexthop.u16); - send_data(&mc.queued_data_dest, rt); - } - } - } else { - rimeaddr_copy(&dest, &msg->dest); - - rt = route_lookup(&msg->dest); - if(rt != NULL) { - PRINTF("forwarding to %d\n", rt->nexthop.u16); - msg->hops++; - uc_send(c, &rt->nexthop); - } else { - PRINTF("%d: no route to %d\n", rimeaddr_node_addr.u16, msg->dest.u16); - } - } -} -/*---------------------------------------------------------------------------*/ -static int -rreq_packet_received(struct nf_conn *c, rimeaddr_t *from, - rimeaddr_t *originator, u8_t seqno, u8_t hops) -{ - struct route_msg *msg = rimebuf_dataptr(); - - /* PRINTF("route_packet_received from %d hops %d\n", from, hops);*/ - - if(!(rimeaddr_cmp(&mc.last_rreq_originator, originator) && - mc.last_rreq_id <= msg->rreq_id)) { - - rimeaddr_copy(&mc.last_rreq_originator, originator); - mc.last_rreq_id = msg->rreq_id; - - if(rimeaddr_cmp(&msg->dest, &rimeaddr_node_addr)) { - PRINTF("route_packet_received: route request for our ID\n"); - insert_route(originator, from, hops); - - /* Send route reply back to source. */ - send_rrep(originator); - return 0; /* Don't continue to flood the rreq packet. */ - } else { - /* PRINTF("route request for %d\n", msg->dest_id);*/ - insert_route(originator, from, hops); - } - - return 1; - } - return 0; /* Don't forward packet. */ -} -/*---------------------------------------------------------------------------*/ -static const struct uc_callbacks data_callbacks = {data_packet_received}; -static const struct uc_callbacks rrep_callbacks = {rrep_packet_received}; -static const struct nf_callbacks rreq_callbacks = {rreq_packet_received, NULL}; -/*---------------------------------------------------------------------------*/ -void -mesh_open(const struct mesh_callbacks *callbacks, - void (* send_datapacket)(rimeaddr_t *next)) -{ - uc_open(&mc.dataconn, CHANNEL_MESH_DATA, &data_callbacks); - uc_open(&mc.rrepconn, CHANNEL_MESH_RREP, &rrep_callbacks); - nf_open(&mc.rreqconn, CHANNEL_MESH_RREQ, &rreq_callbacks); - mc.cb = callbacks; - - send_datapacket_handler = send_datapacket; -} -/*---------------------------------------------------------------------------*/ -void -mesh_close(void) -{ - uc_close(&mc.dataconn); - uc_close(&mc.rrepconn); - nf_close(&mc.rreqconn); + mh_close(&c->mh); + route_discovery_close(&c->route_discovery_conn); } /*---------------------------------------------------------------------------*/ int -mesh_send(rimeaddr_t *to) +mesh_send(struct mesh_conn *c, rimeaddr_t *to) { - struct route_entry *rt; + int could_send; - rt = route_lookup(to); - if(rt == NULL) { - if(mc.queued_data == NULL) { - PRINTF("mesh_send: queueing data, sending rreq\n"); - mc.queued_data = queuebuf_new_from_rimebuf(); - rimeaddr_copy(&mc.queued_data_dest, to); - send_rreq(to); - return 1; + could_send = mh_send(&c->mh, to); + + if(!could_send) { + if(c->queued_data != NULL) { + queuebuf_free(c->queued_data); } + + PRINTF("mesh_send: queueing data, sending rreq\n"); + c->queued_data = queuebuf_new_from_rimebuf(); + rimeaddr_copy(&c->queued_data_dest, to); + route_discovery_discover(&c->route_discovery_conn, to, + PACKET_TIMEOUT); return 0; - } else { - PRINTF("mesh_send: sending data\n"); - send_data(to, rt); - return 1; } + + return 1; } /*---------------------------------------------------------------------------*/ diff --git a/core/net/rime/mesh.h b/core/net/rime/mesh.h index c1086cfa9..eaac3313e 100644 --- a/core/net/rime/mesh.h +++ b/core/net/rime/mesh.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: mesh.h,v 1.4 2007/03/19 22:10:17 adamdunkels Exp $ + * $Id: mesh.h,v 1.5 2007/03/22 17:34:16 adamdunkels Exp $ */ /** @@ -42,18 +42,30 @@ #define __MESH_H__ #include "net/rime.h" +#include "net/rime/mh.h" +#include "net/rime/route-discovery.h" + +struct mesh_conn; struct mesh_callbacks { - void (* sent)(void); - void (* recv)(rimeaddr_t *from); + void (* recv)(struct mesh_conn *c, rimeaddr_t *from); + void (* sent)(struct mesh_conn *c); + void (* timedout)(struct mesh_conn *c); }; -void mesh_open(const struct mesh_callbacks *callbacks, - void (* data_send_function)(rimeaddr_t *next)); -int mesh_send(rimeaddr_t *dest); +struct mesh_conn { + struct mh_conn mh; + struct route_discovery_conn route_discovery_conn; + struct queuebuf *queued_data; + rimeaddr_t queued_data_dest; + const struct mesh_callbacks *cb; +}; -void mesh_data_received(rimeaddr_t *from); +void mesh_open(struct mesh_conn *c, u16_t channels, + const struct mesh_callbacks *callbacks); -void mesh_close(void); +int mesh_send(struct mesh_conn *c, rimeaddr_t *dest); + +void mesh_close(struct mesh_conn *c); #endif /* __MESH_H__ */ diff --git a/core/net/rime/route-discovery.c b/core/net/rime/route-discovery.c new file mode 100644 index 000000000..556913adf --- /dev/null +++ b/core/net/rime/route-discovery.c @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: route-discovery.c,v 1.1 2007/03/22 17:34:16 adamdunkels Exp $ + */ + +/** + * \file + * Route discovery protocol + * \author + * Adam Dunkels + */ + +#include "contiki.h" +#include "net/rime.h" +#include "net/rime/route.h" +#include "net/rime/route-discovery.h" + +#include /* For offsetof */ + +struct route_msg { + rimeaddr_t dest; + u8_t rreq_id; + u8_t pad; +}; + +struct rrep_hdr { + u8_t rreq_id; + u8_t hops; + rimeaddr_t dest; + rimeaddr_t originator; +}; + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/*---------------------------------------------------------------------------*/ +static void +send_rreq(struct route_discovery_conn *c, rimeaddr_t *dest) +{ + struct route_msg *msg; + + rimebuf_clear(); + msg = rimebuf_dataptr(); + rimebuf_set_datalen(sizeof(struct route_msg)); + + msg->pad = 0; + msg->rreq_id = c->rreq_id++; + rimeaddr_copy(&msg->dest, dest); + + nf_send(&c->rreqconn); +} +/*---------------------------------------------------------------------------*/ +static void +send_rrep(struct route_discovery_conn *c, rimeaddr_t *dest) +{ + struct rrep_hdr *rrepmsg; + struct route_entry *rt; + + rimebuf_clear(); + rrepmsg = rimebuf_dataptr(); + rimebuf_set_datalen(sizeof(struct rrep_hdr)); + rrepmsg->hops = 0; + rimeaddr_copy(&rrepmsg->dest, dest); + rimeaddr_copy(&rrepmsg->originator, &rimeaddr_node_addr); + rt = route_lookup(dest); + if(rt != NULL) { + PRINTF("%d.%d: send_rrep to %d.%d via %d.%d\n", + rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], + dest->u8[0],dest->u8[1], + rt->nexthop.u8[0],rt->nexthop.u8[1]); + uc_send(&c->rrepconn, &rt->nexthop); + } +} +/*---------------------------------------------------------------------------*/ +static void +insert_route(rimeaddr_t *originator, rimeaddr_t *last_hop, u8_t hops) +{ + struct route_entry *rt; + + rt = route_lookup(originator); + if(rt == NULL || hops < rt->hop_count) { + PRINTF("%d.%d: Inserting %d.%d into routing table, next hop %d.%d, hop count %d\n", + rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], + originator->u8[0], originator->u8[1], + last_hop->u8[0], last_hop->u8[1], + hops); + route_add(originator, last_hop, hops, 0); + } +} +/*---------------------------------------------------------------------------*/ +static void +rrep_packet_received(struct uc_conn *uc, rimeaddr_t *from) +{ + struct rrep_hdr *msg = rimebuf_dataptr(); + struct route_entry *rt; + rimeaddr_t dest; + struct route_discovery_conn *c = (struct route_discovery_conn *) + ((char *)uc - offsetof(struct route_discovery_conn, rrepconn)); + + PRINTF("%d.%d: rrep_packet_received from %d.%d towards %d.%d len %d\n", + rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], + from->u8[0],from->u8[1], + msg->dest.u8[0],msg->dest.u8[1], + rimebuf_datalen()); + + insert_route(&msg->originator, from, msg->hops); + + if(rimeaddr_cmp(&msg->dest, &rimeaddr_node_addr)) { + PRINTF("rrep for us!\n"); + if(c->cb->new_route) { + c->cb->new_route(c, &msg->originator); + } + + } else { + rimeaddr_copy(&dest, &msg->dest); + + rt = route_lookup(&msg->dest); + if(rt != NULL) { + PRINTF("forwarding to %d\n", rt->nexthop.u16[0]); + msg->hops++; + uc_send(&c->rrepconn, &rt->nexthop); + } else { + PRINTF("%d: no route to %d\n", rimeaddr_node_addr.u16[0], msg->dest.u16[0]); + } + } +} +/*---------------------------------------------------------------------------*/ +static int +rreq_packet_received(struct nf_conn *nf, rimeaddr_t *from, + rimeaddr_t *originator, u8_t seqno, u8_t hops) +{ + struct route_msg *msg = rimebuf_dataptr(); + struct route_discovery_conn *c = (struct route_discovery_conn *) + ((char *)nf - offsetof(struct route_discovery_conn, rreqconn)); + + PRINTF("%d.%d: rreq_packet_received from %d.%d hops %d rreq_id %d last %d/%d\n", + rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], + from->u8[0], from->u8[1], + hops, msg->rreq_id, + c->last_rreq_originator.u16[0], + c->last_rreq_id); + + if(!(rimeaddr_cmp(&c->last_rreq_originator, originator) && + c->last_rreq_id == msg->rreq_id)) { + + PRINTF("%d.%d: rreq_packet_received: request for %d.%d originator %d.%d / %d\n", + rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], + msg->dest.u8[0], msg->dest.u8[1], + originator->u8[0], originator->u8[1], + msg->rreq_id); + + rimeaddr_copy(&c->last_rreq_originator, originator); + c->last_rreq_id = msg->rreq_id; + + if(rimeaddr_cmp(&msg->dest, &rimeaddr_node_addr)) { + PRINTF("%d.%d: route_packet_received: route request for our address\n", + rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]); + insert_route(originator, from, hops); + + /* Send route reply back to source. */ + send_rrep(c, originator); + return 0; /* Don't continue to flood the rreq packet. */ + } else { + /* PRINTF("route request for %d\n", msg->dest_id);*/ + insert_route(originator, from, hops); + } + + return 1; + } + return 0; /* Don't forward packet. */ +} +/*---------------------------------------------------------------------------*/ +static const struct uc_callbacks rrep_callbacks = {rrep_packet_received}; +static const struct nf_callbacks rreq_callbacks = {rreq_packet_received, NULL}; +/*---------------------------------------------------------------------------*/ +void +route_discovery_open(struct route_discovery_conn *c, u16_t channels, + const struct route_discovery_callbacks *callbacks) +{ + nf_open(&c->rreqconn, channels + 0, &rreq_callbacks); + uc_open(&c->rrepconn, channels + 1, &rrep_callbacks); + c->cb = callbacks; +} +/*---------------------------------------------------------------------------*/ +void +route_discovery_close(struct route_discovery_conn *c) +{ + uc_close(&c->rrepconn); + nf_close(&c->rreqconn); + ctimer_stop(&c->t); +} +/*---------------------------------------------------------------------------*/ +static void +timeout_handler(void *ptr) +{ + struct route_discovery_conn *c = ptr; + PRINTF("route_discovery: timeout, timed out\n"); + if(c->cb->timedout) { + /* c->cb->timedout(c);*/ + } +} +/*---------------------------------------------------------------------------*/ +void +route_discovery_discover(struct route_discovery_conn *c, rimeaddr_t *addr, + clock_time_t timeout) +{ + PRINTF("route_discovery_send: sending route request\n"); + ctimer_set(&c->t, timeout, timeout_handler, c); + send_rreq(c, addr); +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/rime/route-discovery.h b/core/net/rime/route-discovery.h new file mode 100644 index 000000000..6b20fd7e3 --- /dev/null +++ b/core/net/rime/route-discovery.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: route-discovery.h,v 1.1 2007/03/22 17:34:16 adamdunkels Exp $ + */ + +/** + * \file + * Header file for the Rime mesh routing protocol + * \author + * Adam Dunkels + */ + +#ifndef __ROUTE_DISCOVERY_H__ +#define __ROUTE_DISCOVERY_H__ + +#include "net/rime.h" +#include "net/rime/nf.h" + +struct route_discovery_conn; + +struct route_discovery_callbacks { + void (* new_route)(struct route_discovery_conn *c, rimeaddr_t *to); + void (* timedout)(struct route_discovery_conn *c); +}; + +#define ROUTE_DISCOVERY_ENTRIES 8 + +struct route_discovery_conn { + struct nf_conn rreqconn; + struct uc_conn rrepconn; + struct ctimer t; + rimeaddr_t last_rreq_originator; + u16_t last_rreq_id; + u16_t rreq_id; + const struct route_discovery_callbacks *cb; +}; + +void route_discovery_open(struct route_discovery_conn *c, u16_t channels, + const struct route_discovery_callbacks *callbacks); +void route_discovery_discover(struct route_discovery_conn *c, rimeaddr_t *dest, + clock_time_t timeout); + +void route_discovery_close(struct route_discovery_conn *c); + +#endif /* __ROUTE_DISCOVERY_H__ */