00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include "contiki.h"
00047 #include "net/rime.h"
00048 #include "net/rime/route.h"
00049 #include "net/rime/route-discovery.h"
00050
00051 #include <stddef.h>
00052 #include <stdio.h>
00053
00054 struct route_msg {
00055 rimeaddr_t dest;
00056 uint8_t rreq_id;
00057 uint8_t pad;
00058 };
00059
00060 struct rrep_hdr {
00061 uint8_t rreq_id;
00062 uint8_t hops;
00063 rimeaddr_t dest;
00064 rimeaddr_t originator;
00065 };
00066
00067 #if CONTIKI_TARGET_NETSIM
00068 #include "ether.h"
00069 #endif
00070
00071
00072 #define DEBUG 0
00073 #if DEBUG
00074 #include <stdio.h>
00075 #define PRINTF(...) printf(__VA_ARGS__)
00076 #else
00077 #define PRINTF(...)
00078 #endif
00079
00080
00081 static char rrep_pending;
00082
00083 static void
00084 send_rreq(struct route_discovery_conn *c, const rimeaddr_t *dest)
00085 {
00086 rimeaddr_t dest_copy;
00087 struct route_msg *msg;
00088
00089 rimeaddr_copy(&dest_copy, dest);
00090 dest = &dest_copy;
00091
00092 packetbuf_clear();
00093 msg = packetbuf_dataptr();
00094 packetbuf_set_datalen(sizeof(struct route_msg));
00095
00096 msg->pad = 0;
00097 msg->rreq_id = c->rreq_id;
00098 rimeaddr_copy(&msg->dest, dest);
00099
00100 netflood_send(&c->rreqconn, c->rreq_id);
00101 c->rreq_id++;
00102 }
00103
00104 static void
00105 send_rrep(struct route_discovery_conn *c, const rimeaddr_t *dest)
00106 {
00107 struct rrep_hdr *rrepmsg;
00108 struct route_entry *rt;
00109 rimeaddr_t saved_dest;
00110
00111 rimeaddr_copy(&saved_dest, dest);
00112
00113 packetbuf_clear();
00114 dest = &saved_dest;
00115 rrepmsg = packetbuf_dataptr();
00116 packetbuf_set_datalen(sizeof(struct rrep_hdr));
00117 rrepmsg->hops = 0;
00118 rimeaddr_copy(&rrepmsg->dest, dest);
00119 rimeaddr_copy(&rrepmsg->originator, &rimeaddr_node_addr);
00120 rt = route_lookup(dest);
00121 if(rt != NULL) {
00122 PRINTF("%d.%d: send_rrep to %d.%d via %d.%d\n",
00123 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00124 dest->u8[0],dest->u8[1],
00125 rt->nexthop.u8[0],rt->nexthop.u8[1]);
00126 unicast_send(&c->rrepconn, &rt->nexthop);
00127 } else {
00128 PRINTF("%d.%d: no route for rrep to %d.%d\n",
00129 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00130 dest->u8[0],dest->u8[1]);
00131 }
00132 }
00133
00134 static void
00135 insert_route(const rimeaddr_t *originator, const rimeaddr_t *last_hop,
00136 uint8_t hops)
00137 {
00138 PRINTF("%d.%d: Inserting %d.%d into routing table, next hop %d.%d, hop count %d\n",
00139 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00140 originator->u8[0], originator->u8[1],
00141 last_hop->u8[0], last_hop->u8[1],
00142 hops);
00143
00144 route_add(originator, last_hop, hops, 0);
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 }
00162
00163 static void
00164 rrep_packet_received(struct unicast_conn *uc, const rimeaddr_t *from)
00165 {
00166 struct rrep_hdr *msg = packetbuf_dataptr();
00167 struct route_entry *rt;
00168 rimeaddr_t dest;
00169 struct route_discovery_conn *c = (struct route_discovery_conn *)
00170 ((char *)uc - offsetof(struct route_discovery_conn, rrepconn));
00171
00172 PRINTF("%d.%d: rrep_packet_received from %d.%d towards %d.%d len %d\n",
00173 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00174 from->u8[0],from->u8[1],
00175 msg->dest.u8[0],msg->dest.u8[1],
00176 packetbuf_datalen());
00177
00178 PRINTF("from %d.%d hops %d rssi %d lqi %d\n",
00179 from->u8[0], from->u8[1],
00180 msg->hops,
00181 packetbuf_attr(PACKETBUF_ATTR_RSSI),
00182 packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY));
00183
00184 insert_route(&msg->originator, from, msg->hops);
00185
00186 if(rimeaddr_cmp(&msg->dest, &rimeaddr_node_addr)) {
00187 PRINTF("rrep for us!\n");
00188 rrep_pending = 0;
00189 ctimer_stop(&c->t);
00190 if(c->cb->new_route) {
00191 rimeaddr_t originator;
00192
00193
00194
00195
00196 rimeaddr_copy(&originator, &msg->originator);
00197 c->cb->new_route(c, &originator);
00198 }
00199
00200 } else {
00201 rimeaddr_copy(&dest, &msg->dest);
00202
00203 rt = route_lookup(&msg->dest);
00204 if(rt != NULL) {
00205 PRINTF("forwarding to %d.%d\n", rt->nexthop.u8[0], rt->nexthop.u8[1]);
00206 msg->hops++;
00207 unicast_send(&c->rrepconn, &rt->nexthop);
00208 } else {
00209 PRINTF("%d.%d: no route to %d.%d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], msg->dest.u8[0], msg->dest.u8[1]);
00210 }
00211 }
00212 }
00213
00214 static int
00215 rreq_packet_received(struct netflood_conn *nf, const rimeaddr_t *from,
00216 const rimeaddr_t *originator, uint8_t seqno, uint8_t hops)
00217 {
00218 struct route_msg *msg = packetbuf_dataptr();
00219 struct route_discovery_conn *c = (struct route_discovery_conn *)
00220 ((char *)nf - offsetof(struct route_discovery_conn, rreqconn));
00221
00222 PRINTF("%d.%d: rreq_packet_received from %d.%d hops %d rreq_id %d last %d.%d/%d\n",
00223 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00224 from->u8[0], from->u8[1],
00225 hops, msg->rreq_id,
00226 c->last_rreq_originator.u8[0],
00227 c->last_rreq_originator.u8[1],
00228 c->last_rreq_id);
00229
00230 if(!(rimeaddr_cmp(&c->last_rreq_originator, originator) &&
00231 c->last_rreq_id == msg->rreq_id)) {
00232
00233 PRINTF("%d.%d: rreq_packet_received: request for %d.%d originator %d.%d / %d\n",
00234 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00235 msg->dest.u8[0], msg->dest.u8[1],
00236 originator->u8[0], originator->u8[1],
00237 msg->rreq_id);
00238
00239 rimeaddr_copy(&c->last_rreq_originator, originator);
00240 c->last_rreq_id = msg->rreq_id;
00241
00242 if(rimeaddr_cmp(&msg->dest, &rimeaddr_node_addr)) {
00243 PRINTF("%d.%d: route_packet_received: route request for our address\n",
00244 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
00245 PRINTF("from %d.%d hops %d rssi %d lqi %d\n",
00246 from->u8[0], from->u8[1],
00247 hops,
00248 packetbuf_attr(PACKETBUF_ATTR_RSSI),
00249 packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY));
00250
00251 insert_route(originator, from, hops);
00252
00253
00254 send_rrep(c, originator);
00255 return 0;
00256 } else {
00257
00258 PRINTF("from %d.%d hops %d rssi %d lqi %d\n",
00259 from->u8[0], from->u8[1],
00260 hops,
00261 packetbuf_attr(PACKETBUF_ATTR_RSSI),
00262 packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY));
00263 insert_route(originator, from, hops);
00264 }
00265
00266 return 1;
00267 }
00268 return 0;
00269 }
00270
00271 static const struct unicast_callbacks rrep_callbacks = {rrep_packet_received};
00272 static const struct netflood_callbacks rreq_callbacks = {rreq_packet_received, NULL, NULL};
00273
00274 void
00275 route_discovery_open(struct route_discovery_conn *c,
00276 clock_time_t time,
00277 uint16_t channels,
00278 const struct route_discovery_callbacks *callbacks)
00279 {
00280 netflood_open(&c->rreqconn, time, channels + 0, &rreq_callbacks);
00281 unicast_open(&c->rrepconn, channels + 1, &rrep_callbacks);
00282 c->cb = callbacks;
00283 }
00284
00285 void
00286 route_discovery_close(struct route_discovery_conn *c)
00287 {
00288 unicast_close(&c->rrepconn);
00289 netflood_close(&c->rreqconn);
00290 ctimer_stop(&c->t);
00291 }
00292
00293 static void
00294 timeout_handler(void *ptr)
00295 {
00296 struct route_discovery_conn *c = ptr;
00297 PRINTF("route_discovery: timeout, timed out\n");
00298 rrep_pending = 0;
00299 if(c->cb->timedout) {
00300 c->cb->timedout(c);
00301 }
00302 }
00303
00304 int
00305 route_discovery_discover(struct route_discovery_conn *c, const rimeaddr_t *addr,
00306 clock_time_t timeout)
00307 {
00308 if(rrep_pending) {
00309 PRINTF("route_discovery_send: ignoring request because of pending response\n");
00310 return 0;
00311 }
00312
00313 PRINTF("route_discovery_send: sending route request\n");
00314 ctimer_set(&c->t, timeout, timeout_handler, c);
00315 rrep_pending = 1;
00316 send_rreq(c, addr);
00317 return 1;
00318 }
00319
00320