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 #include <stdio.h>
00042
00043 #include "net/hc.h"
00044 #include "net/uip-fw.h"
00045 #include "net/uip-over-mesh.h"
00046 #include "net/rime/route-discovery.h"
00047 #include "net/rime/route.h"
00048 #include "net/rime/trickle.h"
00049
00050 #define ROUTE_TRICKLE_INTERVAL CLOCK_SECOND * 32
00051 #define ROUTE_DISCOVERY_INTERVAL CLOCK_SECOND * 4
00052 #define ROUTE_TIMEOUT CLOCK_SECOND * 4
00053
00054 static struct queuebuf *queued_packet;
00055 static rimeaddr_t queued_receiver;
00056
00057
00058 static struct route_discovery_conn route_discovery;
00059
00060
00061 static struct unicast_conn dataconn;
00062
00063
00064
00065 static struct trickle_conn gateway_announce_conn;
00066
00067 #define DEBUG 0
00068 #if DEBUG
00069 #include <stdio.h>
00070 #define PRINTF(...) printf(__VA_ARGS__)
00071 #else
00072 #define PRINTF(...)
00073 #endif
00074
00075 #define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
00076
00077 static struct uip_fw_netif *gw_netif;
00078 static rimeaddr_t gateway;
00079 static uip_ipaddr_t netaddr, netmask;
00080
00081
00082 static void
00083 recv_data(struct unicast_conn *c, const rimeaddr_t *from)
00084 {
00085 struct route_entry *e;
00086 rimeaddr_t source;
00087
00088 uip_len = packetbuf_copyto(&uip_buf[UIP_LLH_LEN]);
00089
00090 source.u8[0] = BUF->srcipaddr.u8[2];
00091 source.u8[1] = BUF->srcipaddr.u8[3];
00092
00093 e = route_lookup(&source);
00094 if(e == NULL) {
00095 route_add(&source, from, 10, 0);
00096 } else {
00097 route_refresh(e);
00098 }
00099
00100
00101
00102 if(!uip_ipaddr_maskcmp(&BUF->srcipaddr, &netaddr, &netmask)) {
00103 e = route_lookup(&gateway);
00104 if(e != NULL) {
00105 route_refresh(e);
00106 }
00107 }
00108
00109
00110
00111 PRINTF("uip-over-mesh: %d.%d: recv_data with len %d\n",
00112 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], uip_len);
00113 tcpip_input();
00114 }
00115
00116 static void
00117 send_data(rimeaddr_t *next)
00118 {
00119 PRINTF("uip-over-mesh: %d.%d: send_data with len %d\n",
00120 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00121 packetbuf_totlen());
00122 unicast_send(&dataconn, next);
00123 }
00124
00125 static void
00126 new_route(struct route_discovery_conn *c, const rimeaddr_t *to)
00127 {
00128 struct route_entry *rt;
00129
00130 if(queued_packet) {
00131 PRINTF("uip-over-mesh: new route, sending queued packet\n");
00132
00133 queuebuf_to_packetbuf(queued_packet);
00134 queuebuf_free(queued_packet);
00135 queued_packet = NULL;
00136
00137 rt = route_lookup(&queued_receiver);
00138 if(rt) {
00139 route_decay(rt);
00140 send_data(&queued_receiver);
00141 }
00142 }
00143 }
00144
00145 static void
00146 timedout(struct route_discovery_conn *c)
00147 {
00148 PRINTF("uip-over-mesh: packet timed out\n");
00149 if(queued_packet) {
00150 PRINTF("uip-over-mesh: freeing queued packet\n");
00151 queuebuf_free(queued_packet);
00152 queued_packet = NULL;
00153 }
00154 }
00155
00156 static const struct unicast_callbacks data_callbacks = { recv_data };
00157 static const struct route_discovery_callbacks rdc = { new_route, timedout };
00158
00159 struct gateway_msg {
00160 rimeaddr_t gateway;
00161 };
00162
00163 static uint8_t is_gateway;
00164
00165 static void
00166 gateway_announce_recv(struct trickle_conn *c)
00167 {
00168 struct gateway_msg *msg;
00169 msg = packetbuf_dataptr();
00170 PRINTF("%d.%d: gateway message: %d.%d\n",
00171 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00172 msg->gateway.u8[0], msg->gateway.u8[1]);
00173
00174 if(!is_gateway) {
00175 uip_over_mesh_set_gateway(&msg->gateway);
00176 }
00177
00178 }
00179
00180 void
00181 uip_over_mesh_make_announced_gateway(void)
00182 {
00183 struct gateway_msg msg;
00184
00185
00186 if(!is_gateway) {
00187 PRINTF("%d.%d: making myself the gateway\n",
00188 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
00189 uip_over_mesh_set_gateway(&rimeaddr_node_addr);
00190 rimeaddr_copy(&(msg.gateway), &rimeaddr_node_addr);
00191 packetbuf_copyfrom(&msg, sizeof(struct gateway_msg));
00192 trickle_send(&gateway_announce_conn);
00193 is_gateway = 1;
00194 }
00195 }
00196 const static struct trickle_callbacks trickle_call = {gateway_announce_recv};
00197
00198 void
00199 uip_over_mesh_init(u16_t channels)
00200 {
00201
00202 PRINTF("Our address is %d.%d (%d.%d.%d.%d)\n",
00203 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00204 uip_hostaddr.u8[0], uip_hostaddr.u8[1],
00205 uip_hostaddr.u8[2], uip_hostaddr.u8[3]);
00206
00207 unicast_open(&dataconn, channels, &data_callbacks);
00208 route_discovery_open(&route_discovery, ROUTE_DISCOVERY_INTERVAL,
00209 channels + 1, &rdc);
00210 trickle_open(&gateway_announce_conn, ROUTE_TRICKLE_INTERVAL, channels + 3,
00211 &trickle_call);
00212
00213 route_init();
00214
00215 route_set_lifetime(30);
00216 }
00217
00218 u8_t
00219 uip_over_mesh_send(void)
00220 {
00221 rimeaddr_t receiver;
00222 struct route_entry *rt;
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 if(uip_ipaddr_maskcmp(&BUF->destipaddr, &netaddr, &netmask)) {
00234 receiver.u8[0] = BUF->destipaddr.u8[2];
00235 receiver.u8[1] = BUF->destipaddr.u8[3];
00236 } else {
00237 if(rimeaddr_cmp(&gateway, &rimeaddr_node_addr)) {
00238 PRINTF("uip_over_mesh_send: I am gateway, packet to %d.%d.%d.%d to local interface\n",
00239 uip_ipaddr_to_quad(&BUF->destipaddr));
00240 if(gw_netif != NULL) {
00241 return gw_netif->output();
00242 }
00243 return UIP_FW_DROPPED;
00244 } else if(rimeaddr_cmp(&gateway, &rimeaddr_null)) {
00245 PRINTF("uip_over_mesh_send: No gateway setup, dropping packet\n");
00246 return UIP_FW_OK;
00247 } else {
00248 PRINTF("uip_over_mesh_send: forwarding packet to %d.%d.%d.%d towards gateway %d.%d\n",
00249 uip_ipaddr_to_quad(&BUF->destipaddr),
00250 gateway.u8[0], gateway.u8[1]);
00251 rimeaddr_copy(&receiver, &gateway);
00252 }
00253 }
00254
00255 PRINTF("uIP over mesh send to %d.%d with len %d\n",
00256 receiver.u8[0], receiver.u8[1],
00257 uip_len);
00258
00259
00260
00261 packetbuf_copyfrom(&uip_buf[UIP_LLH_LEN], uip_len);
00262
00263
00264
00265
00266 if(BUF->proto == UIP_PROTO_TCP) {
00267 packetbuf_set_attr(PACKETBUF_ATTR_ERELIABLE, 1);
00268 packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1);
00269
00270 }
00271
00272 rt = route_lookup(&receiver);
00273 if(rt == NULL) {
00274 PRINTF("uIP over mesh no route to %d.%d\n", receiver.u8[0], receiver.u8[1]);
00275 if(queued_packet == NULL) {
00276 queued_packet = queuebuf_new_from_packetbuf();
00277 rimeaddr_copy(&queued_receiver, &receiver);
00278 route_discovery_discover(&route_discovery, &receiver, ROUTE_TIMEOUT);
00279 } else if(!rimeaddr_cmp(&queued_receiver, &receiver)) {
00280 route_discovery_discover(&route_discovery, &receiver, ROUTE_TIMEOUT);
00281 }
00282 } else {
00283 route_decay(rt);
00284 send_data(&rt->nexthop);
00285 }
00286 return UIP_FW_OK;
00287 }
00288
00289 void
00290 uip_over_mesh_set_gateway_netif(struct uip_fw_netif *n)
00291 {
00292 gw_netif = n;
00293 }
00294
00295 void
00296 uip_over_mesh_set_gateway(rimeaddr_t *gw)
00297 {
00298 rimeaddr_copy(&gateway, gw);
00299 }
00300
00301 void
00302 uip_over_mesh_set_net(uip_ipaddr_t *addr, uip_ipaddr_t *mask)
00303 {
00304 uip_ipaddr_copy(&netaddr, addr);
00305 uip_ipaddr_copy(&netmask, mask);
00306 }
00307