fixed a clock skew correction bug and added a checksum
diff --git a/aos/common/sensors/sensors.h b/aos/common/sensors/sensors.h
index 11cf105..007921c 100644
--- a/aos/common/sensors/sensors.h
+++ b/aos/common/sensors/sensors.h
@@ -3,8 +3,8 @@
 
 #include "aos/common/time.h"
 #include "aos/common/byteorder.h"
-
 #include "aos/common/control_loop/ControlLoop.h"
+#include "aos/common/inttypes.h"
 
 namespace aos {
 // This namespace contains all of the stuff for dealing with reading sensors and
@@ -36,9 +36,16 @@
 using ::aos::control_loops::kLoopFrequency;
 using ::aos::control_loops::NextLoopTime;
 
+uint32_t CalculateChecksum(char *buf, size_t size);
+
 // This is the struct that actually gets sent over the UDP socket.
 template<class Values>
 struct SensorData {
+  // All of the other 4-byte chunks in the message bitwise-exclusive-ORed
+  // together. Needed because it seems like nobody else checks... (vxworks not
+  // sending the UDP checksum or (not very likely) linux not checking it).
+  uint32_t checksum;
+
   Values values;
   // Starts at 0 and goes up.
   int32_t count;
@@ -49,6 +56,24 @@
   void HostToNetwork() {
     count = hton(count);
   }
+
+  void FillinChecksum() {
+    checksum = CalculateChecksum(reinterpret_cast<char *>(this) +
+                                 sizeof(checksum),
+                                 sizeof(*this) - sizeof(checksum));
+  }
+  // Returns whether or not checksum is correct.
+  bool CheckChecksum() {
+    uint32_t expected = CalculateChecksum(reinterpret_cast<char *>(this) +
+                                          sizeof(checksum),
+                                          sizeof(*this) - sizeof(checksum));
+    if (checksum != expected) {
+      LOG(INFO, "expected %"PRIx32" but got %"PRIx32"\n",
+          expected, checksum);
+      return false;
+    }
+    return true;
+  }
 } __attribute__((packed));
 
 }  // namespace sensors