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 #include "radio-uip-uaodv.h"
00035 #include "net/hc.h"
00036 #include "net/uip.h"
00037 #include "net/uaodv.h"
00038 #include "net/uaodv-rt.h"
00039 #include "net/uaodv-def.h"
00040 #include "lib/crc16.h"
00041 #include "list.h"
00042 #include <string.h>
00043 #include <stdio.h>
00044
00045
00046 #define MAX_BUFFERED_PACKETS 10
00047 #define MAX_RETRANSMISSIONS_RREP 16
00048 #define MAX_RETRANSMISSIONS_UNICAST 16
00049
00050
00051 #define FWD_ID "fWd:"
00052 #define FWD_ID_LENGTH 4
00053 #define FWD_NEXT_IP FWD_ID_LENGTH
00054 #define FWD_PACKET_LENGTH (FWD_NEXT_IP + 4)
00055
00056
00057 #define ACK_ID "aCk"
00058 #define ACK_ID_LENGTH 3
00059 #define ACK_CRC ACK_ID_LENGTH
00060 #define ACK_PACKET_LENGTH (ACK_ID_LENGTH + 2)
00061 #define ACK_TIMEOUT (CLOCK_SECOND / 50) * (random_rand() % 100)
00062
00063 enum {
00064 EVENT_SEND_ACK
00065 };
00066
00067 struct buf_packet {
00068 struct buf_packet *next;
00069 u8_t data[UIP_BUFSIZE];
00070 int len;
00071 u8_t resends;
00072 u8_t acked;
00073 u8_t want_ack;
00074 u16_t crc;
00075 uip_ipaddr_t finaldest;
00076 struct etimer etimer;
00077 };
00078
00079 LIST(buf_packet_list);
00080 MEMB(buf_packet_mem, struct buf_packet, MAX_BUFFERED_PACKETS);
00081
00082 PROCESS(radio_uip_process, "radio uIP uAODV process");
00083
00084 static const struct radio_driver *radio;
00085
00086
00087
00088
00089 static void receiver(const struct radio_driver *d);
00090 u8_t radio_uip_uaodv_send(void);
00091 void radio_uip_uaodv_init(const struct radio_driver *d);
00092 int radio_uip_handle_ack(u8_t *buf, int len);
00093 u16_t radio_uip_calc_crc(u8_t *buf, int len);
00094 int radio_uip_buffer_outgoing_packet(u8_t *buf, int len, uip_ipaddr_t *dest, int max_sends);
00095 int radio_uip_is_ack(u8_t *buf, int len);
00096 int radio_uip_uaodv_add_header(u8_t *buf, int len, uip_ipaddr_t *addr);
00097 int radio_uip_uaodv_remove_header(u8_t *buf, int len);
00098 void radio_uip_uaodv_change_header(u8_t *buf, int len, uip_ipaddr_t *addr);
00099 int radio_uip_uaodv_header_exists(u8_t *buf, int len);
00100 int radio_uip_uaodv_is_broadcast(uip_ipaddr_t *addr);
00101 int radio_uip_uaodv_fwd_is_broadcast(u8_t *buf, int len);
00102 int radio_uip_uaodv_fwd_is_me(u8_t *buf, int len);
00103 int radio_uip_uaodv_dest_is_me(u8_t *buf, int len);
00104 int radio_uip_uaodv_dest_port(u8_t *buf, int len);
00105
00106
00107
00108 PROCESS_THREAD(radio_uip_process, ev, data)
00109 {
00110 struct buf_packet *packet;
00111
00112 PROCESS_BEGIN();
00113
00114 while(1) {
00115 PROCESS_YIELD();
00116
00117 if(ev == EVENT_SEND_ACK) {
00118
00119
00120 u8_t ackPacket[ACK_PACKET_LENGTH];
00121 memcpy(ackPacket, ACK_ID, ACK_ID_LENGTH);
00122 ackPacket[ACK_CRC] = ((u16_t) data >> 8);
00123 ackPacket[ACK_CRC+1] = ((u16_t) data & 0xff);
00124 radio->send(ackPacket, ACK_PACKET_LENGTH);
00125
00126 } else if(ev == PROCESS_EVENT_TIMER) {
00127
00128 for(packet = list_head(buf_packet_list);
00129 packet != NULL;
00130 packet = packet->next) {
00131 if (etimer_expired(&packet->etimer)) {
00132
00133 if (packet->acked) {
00134
00135 list_remove(buf_packet_list, packet);
00136 memb_free(&buf_packet_mem, packet);
00137
00138 } else if (packet->resends > 0) {
00139
00140 packet->resends--;
00141 etimer_set(&packet->etimer, ACK_TIMEOUT);
00142
00143 radio->send(packet->data, packet->len);
00144
00145 } else {
00146
00147
00148
00149 if (packet->want_ack && !uip_ipaddr_cmp(&packet->finaldest, &uip_broadcast_addr)) {
00150 uaodv_bad_dest(&packet->finaldest);
00151 }
00152
00153 list_remove(buf_packet_list, packet);
00154 memb_free(&buf_packet_mem, packet);
00155 }
00156 }
00157 }
00158 }
00159 }
00160 PROCESS_END();
00161 }
00162
00163 static void
00164 receiver(const struct radio_driver *d)
00165 {
00166 uip_len = d->read(&uip_buf[UIP_LLH_LEN], UIP_BUFSIZE - UIP_LLH_LEN);
00167 if (uip_len <= 0) {
00168 return;
00169 }
00170
00171
00172 if (radio_uip_is_ack(&uip_buf[UIP_LLH_LEN], uip_len)) {
00173 radio_uip_handle_ack(&uip_buf[UIP_LLH_LEN], uip_len);
00174 return;
00175 }
00176
00177
00178 if (!radio_uip_uaodv_header_exists(&uip_buf[UIP_LLH_LEN], uip_len)) {
00179 tcpip_input();
00180 return;
00181 }
00182
00183
00184 if (!radio_uip_uaodv_fwd_is_me(&uip_buf[UIP_LLH_LEN], uip_len)) {
00185 return;
00186 }
00187
00188 {
00189
00190 u16_t crc;
00191 crc = radio_uip_calc_crc(&uip_buf[UIP_LLH_LEN], uip_len);
00192 process_post(&radio_uip_process, EVENT_SEND_ACK, (void*) (u32_t) crc);
00193 }
00194
00195
00196 uip_len = radio_uip_uaodv_remove_header(&uip_buf[UIP_LLH_LEN], uip_len);
00197 tcpip_input();
00198 }
00199
00200 u8_t
00201 radio_uip_uaodv_send(void)
00202 {
00203 struct uaodv_rt_entry *route;
00204
00205
00206 if (radio_uip_uaodv_is_broadcast(&((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->destipaddr)) {
00207 return radio_uip_buffer_outgoing_packet(&uip_buf[UIP_LLH_LEN], uip_len, (void*) &uip_broadcast_addr, 1);
00208 }
00209
00210
00211 if (((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->proto == UIP_PROTO_UDP
00212 && radio_uip_uaodv_dest_port(&uip_buf[UIP_LLH_LEN], uip_len) == UIP_HTONS(UAODV_UDPPORT)) {
00213 uip_ipaddr_t nexthop;
00214 memcpy(&nexthop, &((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->destipaddr, 4);
00215
00216 uip_len = radio_uip_uaodv_add_header(
00217 &uip_buf[UIP_LLH_LEN],
00218 uip_len,
00219 &nexthop
00220 );
00221
00222
00223 return radio_uip_buffer_outgoing_packet(
00224 &uip_buf[UIP_LLH_LEN],
00225 uip_len,
00226 &((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN + FWD_PACKET_LENGTH])->destipaddr,
00227 MAX_RETRANSMISSIONS_RREP);
00228 }
00229
00230
00231 route = uaodv_rt_lookup_any((&((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->destipaddr));
00232 if (route == NULL || route->is_bad) {
00233
00234
00235 if (tcpip_is_forwarding) {
00236 uaodv_bad_dest((&((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->destipaddr));
00237 }
00238
00239 return UIP_FW_DROPPED;
00240 }
00241
00242
00243 uip_len = radio_uip_uaodv_add_header(&uip_buf[UIP_LLH_LEN], uip_len, &route->nexthop);
00244 return radio_uip_buffer_outgoing_packet(
00245 &uip_buf[UIP_LLH_LEN],
00246 uip_len,
00247 &route->dest,
00248 MAX_RETRANSMISSIONS_UNICAST);
00249 }
00250
00251 void
00252 radio_uip_uaodv_init(const struct radio_driver *d)
00253 {
00254
00255 memb_init(&buf_packet_mem);
00256 list_init(buf_packet_list);
00257 process_start(&radio_uip_process, NULL);
00258
00259 radio = d;
00260 radio->set_receive_function(receiver);
00261 radio->on();
00262 }
00263
00264 u16_t
00265 radio_uip_calc_crc(u8_t *buf, int len)
00266 {
00267 u16_t crcacc = 0xffff;
00268 int counter;
00269
00270
00271 for (counter = 0; counter < len; counter++) {
00272 crcacc = crc16_add(buf[counter], crcacc);
00273 }
00274 return crcacc;
00275 }
00276
00277 int
00278 radio_uip_buffer_outgoing_packet(u8_t *buf, int len, uip_ipaddr_t *dest, int max_sends)
00279 {
00280 struct buf_packet *packet;
00281
00282 u16_t crc;
00283
00284
00285 crc = radio_uip_calc_crc(&uip_buf[UIP_LLH_LEN], uip_len);
00286
00287
00288 for(packet = list_head(buf_packet_list);
00289 packet != NULL;
00290 packet = packet->next) {
00291 if (packet->crc == crc) {
00292 return UIP_FW_DROPPED;
00293 }
00294 }
00295
00296
00297 packet = (struct buf_packet *)memb_alloc(&buf_packet_mem);
00298 if (packet == NULL) {
00299 return UIP_FW_DROPPED;
00300 }
00301
00302
00303 memcpy(packet->data, buf, len);
00304 packet->len = len;
00305 packet->resends = max_sends;
00306 packet->acked = 0;
00307 if (packet->resends > 1)
00308 packet->want_ack = 1;
00309 else
00310 packet->want_ack = 0;
00311 memcpy(&packet->finaldest, dest, 4);
00312 packet->crc = crc;
00313
00314
00315 PROCESS_CONTEXT_BEGIN(&radio_uip_process);
00316 etimer_set(&packet->etimer, 0);
00317 PROCESS_CONTEXT_END(&radio_uip_process);
00318
00319
00320 list_add(buf_packet_list, packet);
00321
00322 return UIP_FW_OK;
00323 }
00324
00325 int
00326 radio_uip_is_ack(u8_t *buf, int len)
00327 {
00328 if (len != ACK_PACKET_LENGTH)
00329 return 0;
00330
00331 return memcmp(buf, ACK_ID, ACK_ID_LENGTH) == 0;
00332
00333 }
00334
00335 int
00336 radio_uip_handle_ack(u8_t *buf, int len)
00337 {
00338 struct buf_packet *packet;
00339 u16_t ackCRC;
00340
00341 ackCRC = (u16_t) (buf[ACK_CRC] << 8) + (u16_t) (0xff&buf[ACK_CRC+1]);
00342
00343
00344 for(packet = list_head(buf_packet_list);
00345 packet != NULL;
00346 packet = packet->next) {
00347 if (packet->crc == ackCRC) {
00348
00349 packet->acked = 1;
00350 return 0;
00351 }
00352 }
00353
00354 return 1;
00355 }
00356
00357 int
00358 radio_uip_uaodv_add_header(u8_t *buf, int len, uip_ipaddr_t *addr)
00359 {
00360 u8_t tempbuf[len];
00361 memcpy(tempbuf, buf, len);
00362 memcpy(&buf[FWD_PACKET_LENGTH], tempbuf, len);
00363 memcpy(buf, FWD_ID, FWD_ID_LENGTH);
00364 memcpy(&buf[FWD_NEXT_IP], (char*)addr, 4);
00365 return FWD_PACKET_LENGTH + len;
00366 }
00367
00368 int
00369 radio_uip_uaodv_remove_header(u8_t *buf, int len)
00370 {
00371 u8_t tempbuf[len];
00372 memcpy(tempbuf, &buf[FWD_PACKET_LENGTH], len);
00373 memcpy(buf, tempbuf, len);
00374 return len - FWD_PACKET_LENGTH;
00375 }
00376
00377 void
00378 radio_uip_uaodv_change_header(u8_t *buf, int len, uip_ipaddr_t *addr)
00379 {
00380 memcpy(&buf[FWD_NEXT_IP], addr, 4);
00381 }
00382
00383 int
00384 radio_uip_uaodv_header_exists(u8_t *buf, int len)
00385 {
00386 return !memcmp(buf, FWD_ID, FWD_ID_LENGTH);
00387 }
00388
00389 int
00390 radio_uip_uaodv_is_broadcast(uip_ipaddr_t *addr)
00391 {
00392 return uip_ipaddr_cmp(addr, &uip_broadcast_addr);
00393 }
00394
00395 int
00396 radio_uip_uaodv_fwd_is_broadcast(u8_t *buf, int len)
00397 {
00398 return radio_uip_uaodv_is_broadcast((uip_ipaddr_t*) &buf[FWD_NEXT_IP]);
00399 }
00400
00401 int
00402 radio_uip_uaodv_fwd_is_me(u8_t *buf, int len)
00403 {
00404 return !memcmp(&buf[FWD_NEXT_IP], &uip_hostaddr, 4);
00405 }
00406
00407 int
00408 radio_uip_uaodv_dest_is_me(u8_t *buf, int len)
00409 {
00410 return !memcmp((&((struct uip_udpip_hdr *)buf)->destipaddr), &uip_hostaddr, 4);
00411 }
00412
00413 int
00414 radio_uip_uaodv_dest_port(u8_t *buf, int len)
00415 {
00416 if (len < sizeof(struct uip_udpip_hdr))
00417 return -1;
00418 return (int) ((struct uip_udpip_hdr *)buf)->destport;
00419 }
00420