]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/lib/net/blip/UdpP.nc
commit svn HEAD of blip into core to start merge testing
[tinyos-2.x.git] / tos / lib / net / blip / UdpP.nc
index 8cb0e5fb7351418529b24e7ab0e2a0a55ea3c331..47ecb0d53177f88c3511be9cab97cbf8c210c8c3 100644 (file)
@@ -1,18 +1,26 @@
 
 #include <ip_malloc.h>
 #include <in_cksum.h>
+#include <Statistics.h>
 
 module UdpP {
   provides interface UDP[uint8_t clnt];
   provides interface Init;
+  provides interface Statistics<udp_statistics_t>;
   uses interface IP;
   uses interface IPAddress;
 } implementation {
 
+#ifdef PRINTFUART_ENABLED
+#undef dbg
+#define dbg(X,fmt, args...) printfUART(fmt, ##args)
+#endif
+
   enum {
     N_CLIENTS = uniqueCount("UDP_CLIENT"),
   };
 
+  udp_statistics_t stats;
   uint16_t local_ports[N_CLIENTS];
 
   enum {
@@ -40,6 +48,7 @@ module UdpP {
   }
 
   command error_t Init.init() {
+    call Statistics.clear();
     ip_memclr((uint8_t *)local_ports, sizeof(uint16_t) * N_CLIENTS);
     return SUCCESS;
   }
@@ -64,7 +73,6 @@ module UdpP {
     return SUCCESS;
   }
 
-
   event void IP.recv(struct ip6_hdr *iph,
                      void *payload,
                      struct ip_metadata *meta) {
@@ -86,6 +94,34 @@ module UdpP {
     ip_memcpy(&addr.sin6_addr, &iph->ip6_src, 16);
     addr.sin6_port = udph->srcport;
 
+
+    { 
+      uint16_t rx_cksum = ntohs(udph->chksum), my_cksum;
+      vec_t cksum_vec[4];
+      uint32_t hdr[2];
+
+      udph->chksum = 0;
+
+      cksum_vec[0].ptr = (uint8_t *)(iph->ip6_src.s6_addr);
+      cksum_vec[0].len = 16;
+      cksum_vec[1].ptr = (uint8_t *)(iph->ip6_dst.s6_addr);
+      cksum_vec[1].len = 16;
+      cksum_vec[2].ptr = (uint8_t *)hdr;
+      cksum_vec[2].len = 8;
+      hdr[0] = iph->plen;
+      hdr[1] = htonl(IANA_UDP);
+      cksum_vec[3].ptr = payload;
+      cksum_vec[3].len = ntohs(iph->plen);
+
+      my_cksum = in_cksum(cksum_vec, 4);
+      printfUART("rx cksum: %x calc: %x\n", rx_cksum, my_cksum);
+      if (rx_cksum != my_cksum) {
+        BLIP_STATS_INCR(cksum);
+        return;
+      }
+    }
+
+    BLIP_STATS_INCR(rcvd);
     signal UDP.recvfrom[i](&addr, (void *)(udph + 1), ntohs(iph->plen) - sizeof(struct udp_hdr), meta);
   }
 
@@ -118,13 +154,16 @@ module UdpP {
     g_udp = (struct generic_header *)(udp + 1);
 
     // fill in all the packet fields
-    ip_memclr((uint8_t *)&msg->hdr, sizeof(struct ip6_hdr));
+    ip_memclr((uint8_t *)msg, sizeof(struct split_ip_msg));
     ip_memclr((uint8_t *)udp, sizeof(struct udp_hdr));
     
     setSrcAddr(msg);
     memcpy(&msg->hdr.ip6_dst, dest->sin6_addr.s6_addr, 16);
     
-    if (local_ports[clnt] == 0 && alloc_lport(clnt) == 0) return FAIL;
+    if (local_ports[clnt] == 0 && (local_ports[clnt] = alloc_lport(clnt)) == 0) {
+      ip_free(msg);
+      return FAIL;
+    }
     udp->srcport = local_ports[clnt];
     udp->dstport = dest->sin6_port;
     udp->len = htons(len + sizeof(struct udp_hdr));
@@ -141,12 +180,25 @@ module UdpP {
     udp->chksum = htons(msg_cksum(msg, IANA_UDP)); 
 
     rc = call IP.send(msg);
+    BLIP_STATS_INCR(sent);
 
     ip_free(msg);
     return rc;
 
   }
 
+  command void Statistics.clear() {
+#ifdef BLIP_STATS
+    ip_memclr((uint8_t *)&stats, sizeof(udp_statistics_t));
+#endif
+  }
+
+  command void Statistics.get(udp_statistics_t *buf) {
+#ifdef BLIP_STATS
+    ip_memcpy(buf, &stats, sizeof(udp_statistics_t));
+#endif
+  }
+
   default event void UDP.recvfrom[uint8_t clnt](struct sockaddr_in6 *from, void *payload,
                                                uint16_t len, struct ip_metadata *meta) {