cleaned up issues with Daniel's code

There were a lot of style things and a misunderstanding of the protocol
between the cape and the BBB.
diff --git a/bbb_cape/src/bbb/bbb.gyp b/bbb_cape/src/bbb/bbb.gyp
index ec617cc..ddbf388 100644
--- a/bbb_cape/src/bbb/bbb.gyp
+++ b/bbb_cape/src/bbb/bbb.gyp
@@ -1,4 +1,9 @@
 {
+  'target_defaults': {
+    'include_dirs': [
+      '..',
+    ],
+  },
   'targets': [
     {
       'target_name': 'crc',
@@ -16,8 +21,12 @@
       'dependencies': [
         'crc',
         '<(DEPTH)/bbb_cape/src/cape/cape.gyp:cows',
+        '<(DEPTH)/bbb_cape/src/cape/cape.gyp:data_struct',
         '<(AOS)/build/aos.gyp:logging',
       ],
+      'export_dependent_settings': [
+        '<(DEPTH)/bbb_cape/src/cape/cape.gyp:data_struct',
+      ],
       'sources': [
         'uart_receiver.cc',
       ],
diff --git a/bbb_cape/src/bbb/crc.cc b/bbb_cape/src/bbb/crc.cc
index 60e665a..214f86f 100644
--- a/bbb_cape/src/bbb/crc.cc
+++ b/bbb_cape/src/bbb/crc.cc
@@ -1,4 +1,4 @@
-#include "crc.h"
+#include "bbb/crc.h"
 
 #include "aos/common/once.h"
 
diff --git a/bbb_cape/src/bbb/crc.h b/bbb_cape/src/bbb/crc.h
index cb0bf63..7a8eb95 100644
--- a/bbb_cape/src/bbb/crc.h
+++ b/bbb_cape/src/bbb/crc.h
@@ -1,7 +1,7 @@
 #ifndef BBB_CRC_H_
 #define BBB_CRC_H_
 
-#include <cstring>
+#include <string.h>
 #include <stdint.h>
 
 namespace cape {
diff --git a/bbb_cape/src/bbb/gpios.cc b/bbb_cape/src/bbb/gpios.cc
index e2ab654..5a9c76e 100644
--- a/bbb_cape/src/bbb/gpios.cc
+++ b/bbb_cape/src/bbb/gpios.cc
@@ -1,146 +1,153 @@
-#include <cstdio>
-#include <cstdlib>
+#include "bbb/gpios.h"
+
+#include <stdio.h>
+#include <stdlib.h>
 
 #include "aos/common/logging/logging_impl.h"
-#include "gpios.h"
 
 namespace bbb {
 
-  Pin::Pin(int bank, int pin) : handle_(NULL), direction_(0),
-    kernel_pin_(bank * 32 + pin), exported_(false) {}
+Pin::Pin(int bank, int pin)
+    : handle_(NULL),
+      direction_(0),
+      kernel_pin_(bank * 32 + pin),
+      exported_(false) {}
 
-  Pin::~Pin() {
-    // Unexport the pin.
-    if ((handle_ = fopen("/sys/class/gpio/unexport", "ab")) == NULL) {
-      LOG(WARNING, "Could not unexport gpio pin.\n");
-      // There's nothing intelligent we can really do here.
-      return;
-    }
-
-    char gpio_num[2];
-    snprintf(gpio_num, sizeof(gpio_num), "%d", kernel_pin_);
-    fwrite(gpio_num, sizeof(char), 2, handle_);
-    fclose(handle_);
+Pin::~Pin() {
+  // Unexport the pin.
+  if ((handle_ = fopen("/sys/class/gpio/unexport", "ab")) == NULL) {
+    LOG(WARNING, "Could not unexport gpio pin.\n");
+    // There's nothing intelligent we can really do here.
+    return;
   }
 
-  int Pin::DoExport() {
-    char gpio_num[2];
-    snprintf(gpio_num, sizeof(gpio_num), "%d", kernel_pin_);
-    
-    // Export the pin.
-    if ((handle_ = fopen("/sys/class/gpio/export", "ab")) == NULL) {
-      LOG(ERROR, "Could not export GPIO pin.\n");
-      return -1;
-    }
+  char gpio_num[2];
+  snprintf(gpio_num, sizeof(gpio_num), "%d", kernel_pin_);
+  fwrite(gpio_num, sizeof(char), 2, handle_);
+  fclose(handle_);
+}
 
-    fwrite(gpio_num, sizeof(char), 2, handle_);
-    fclose(handle_);
+int Pin::DoExport() {
+  char gpio_num[2];
+  snprintf(gpio_num, sizeof(gpio_num), "%d", kernel_pin_);
 
-    exported_ = true;
-    return 0;
+  // Export the pin.
+  if ((handle_ = fopen("/sys/class/gpio/export", "ab")) == NULL) {
+    LOG(ERROR, "Could not export GPIO pin.\n");
+    return -1;
   }
 
-  int Pin::DoPinDirSet(int direction) {
-    char buf[4], type_path[64];
-    snprintf(type_path, sizeof(type_path), "/sys/class/gpio/gpio%d/direction", kernel_pin_);
-    
-    if ((handle_ = fopen(type_path, "rb+")) == NULL) {
-      LOG(ERROR, "Unable to set pin direction.\n");
-      return -1;
-    }
+  fwrite(gpio_num, sizeof(char), 2, handle_);
+  fclose(handle_);
 
-    direction_ = direction;
-    switch (direction) {
-      case 1:
-        strcpy(buf, "in");
-        break;
-      case 2:
-        strcpy(buf, "low");
-        break;
-      case 0:
-        return 0;
-      default:
-        LOG(ERROR, "Invalid direction identifier %d.\n", direction);
-        direction_ = 0;
-        return -1;
-    }
-    fwrite(buf, sizeof(char), 3, handle_);
-    fclose(handle_);
+  exported_ = true;
+  return 0;
+}
 
-    return 0;
+int Pin::DoPinDirSet(int direction) {
+  char buf[4], type_path[64];
+  snprintf(type_path, sizeof(type_path), "/sys/class/gpio/gpio%d/direction",
+           kernel_pin_);
+
+  if ((handle_ = fopen(type_path, "rb+")) == NULL) {
+    LOG(ERROR, "Unable to set pin direction.\n");
+    return -1;
   }
 
-  int Pin::MakeInput() {
-    if (!exported_) {
-      if (DoExport()) {
-        return -1;
-      }
-    }
+  direction_ = direction;
+  switch (direction) {
+    case 1:
+      strcpy(buf, "in");
+      break;
+    case 2:
+      strcpy(buf, "low");
+      break;
+    case 0:
+      return 0;
+    default:
+      LOG(ERROR, "Invalid direction identifier %d.\n", direction);
+      direction_ = 0;
+      return -1;
+  }
+  fwrite(buf, sizeof(char), 3, handle_);
+  fclose(handle_);
 
-    return DoPinDirSet(1);
+  return 0;
+}
+
+int Pin::MakeInput() {
+  if (!exported_) {
+    if (DoExport()) {
+      return -1;
+    }
   }
 
-  int Pin::MakeOutput() {
-    if (!exported_) {
-      if (DoExport()) {
-        return -1;
-      }
-    }
+  return DoPinDirSet(1);
+}
 
-    return DoPinDirSet(2);
+int Pin::MakeOutput() {
+  if (!exported_) {
+    if (DoExport()) {
+      return -1;
+    }
   }
 
-  int Pin::Write(uint8_t value) {
-    if (direction_ != 2) {
-      LOG(ERROR, "Only pins set as output can be written to.\n");
-      return -1;
-    }
+  return DoPinDirSet(2);
+}
 
-    char buf, val_path [64];
-    snprintf(val_path, sizeof(val_path), "/sys/class/gpio/gpio%d/value", kernel_pin_);
-    if (value != 0) {
-      value = 1;
-    }
-
-    if ((handle_ = fopen(val_path, "rb+")) == NULL) {
-      LOG(ERROR, "Unable to set pin value.\n");
-      return -1;
-    }
-
-    snprintf(&buf, sizeof(buf), "%d", value);
-    fwrite(&buf, sizeof(char), 1, handle_);
-    fclose(handle_);
-
-    return 0;
+int Pin::Write(uint8_t value) {
+  if (direction_ != 2) {
+    LOG(ERROR, "Only pins set as output can be written to.\n");
+    return -1;
   }
 
-  int Pin::Read() {
-    // NOTE: I can't find any docs confirming that one can indeed
-    // poll a pin's value using this method, but it seems that it
-    // should work. Really, the "right" (interrupt driven) way to
-    // do this is to set an event, but that involves messing with
-    // dev tree crap, which I'm not willing to do unless we need 
-    // this functionality.
-
-    if (direction_ != 1) {
-      LOG(ERROR, "Only pins set as input can be read from.\n");
-      return -1;
-    }
-
-    char buf, val_path [64];
-    snprintf(val_path, sizeof(val_path), "/sys/class/gpio/gpio%d/value", kernel_pin_);
-
-    if ((handle_ = fopen(val_path, "rb")) == NULL) {
-      LOG(ERROR, "Unable to read pin value.\n");
-      return -1;
-    }
-
-    if (fread(&buf, sizeof(char), 1, handle_) <= 0) {
-      LOG(ERROR, "Failed to read pin value from file.\n");
-      return -1;
-    }
-    fclose(handle_);
-    return atoi(&buf);
+  char buf, val_path[64];
+  snprintf(val_path, sizeof(val_path), "/sys/class/gpio/gpio%d/value",
+           kernel_pin_);
+  if (value != 0) {
+    value = 1;
   }
 
-} // bbb
+  if ((handle_ = fopen(val_path, "rb+")) == NULL) {
+    LOG(ERROR, "Unable to set pin value.\n");
+    return -1;
+  }
+
+  snprintf(&buf, sizeof(buf), "%d", value);
+  fwrite(&buf, sizeof(char), 1, handle_);
+  fclose(handle_);
+
+  return 0;
+}
+
+int Pin::Read() {
+  // NOTE: I can't find any docs confirming that one can indeed
+  // poll a pin's value using this method, but it seems that it
+  // should work. Really, the "right" (interrupt driven) way to
+  // do this is to set an event, but that involves messing with
+  // dev tree crap, which I'm not willing to do unless we need
+  // this functionality.
+
+  if (direction_ != 1) {
+    LOG(ERROR, "Only pins set as input can be read from.\n");
+    return -1;
+  }
+
+  char buf, val_path[64];
+  snprintf(val_path, sizeof(val_path), "/sys/class/gpio/gpio%d/value",
+           kernel_pin_);
+
+  if ((handle_ = fopen(val_path, "rb")) == NULL) {
+    LOG(ERROR, "Unable to read pin value.\n");
+    return -1;
+  }
+
+  if (fread(&buf, sizeof(char), 1, handle_) <= 0) {
+    LOG(ERROR, "Failed to read pin value from file.\n");
+    return -1;
+  }
+  fclose(handle_);
+  return atoi(&buf);
+}
+
+}  // namespace bbb
diff --git a/bbb_cape/src/bbb/gpios.h b/bbb_cape/src/bbb/gpios.h
index 1494da2..a377d68 100644
--- a/bbb_cape/src/bbb/gpios.h
+++ b/bbb_cape/src/bbb/gpios.h
@@ -1,8 +1,8 @@
 #ifndef BBB_CAPE_SRC_BBB_CAPE_CONTROL_H_
 #define BBB_CAPE_SRC_BBB_CAPE_CONTROL_H_
 
-#include <cstdint>
-#include <cstring>
+#include <stdint.h>
+#include <stdio.h>
 
 // As it turns out, controlling the BBB's GPIO pins
 // from C++ is kind of a pain. The purpose of this
@@ -35,6 +35,6 @@
   int Read();
 };
 
-} // bbb
+}  // namespace bbb
 
 #endif
diff --git a/bbb_cape/src/bbb/uart_receiver.cc b/bbb_cape/src/bbb/uart_receiver.cc
index aabedd3..b29723e 100644
--- a/bbb_cape/src/bbb/uart_receiver.cc
+++ b/bbb_cape/src/bbb/uart_receiver.cc
@@ -1,78 +1,90 @@
+#include "bbb/uart_receiver.h"
+
 #include <fcntl.h>
 #include <linux/serial.h>
 #include <termio.h>
 #include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <inttypes.h>
 
-#include <cmath>
-#include <cstring>
+#include <algorithm>
 
-#include "aos/common/logging/logging_impl.h"
+#include "aos/common/logging/logging.h"
 #include "bbb_cape/src/cape/cows.h"
-#include "crc.h"
-#include "uart_receiver.h"
+#include "bbb/crc.h"
 
 // This is the code for receiving data from the cape via UART.
-// NOTE: In order for this to work, you MUST HAVE "capemgr.enable_partno=BB_UART1"
+// NOTE: In order for this to work, you MUST HAVE
+// "capemgr.enable_partno=BB_UART1"
 // in your BBB's /media/BEAGLEBONE/uEnv.txt file!
 
 // Implementation for setting custom serial baud rates based on this code:
 // <http://jim.sh/ftx/files/linux-custom-baudrate.c>
 
 namespace bbb {
+namespace {
+// TODO(brians): Determine this in some way that allows easy switching for
+// testing with /dev/ttyUSB0 for example.
+const char *device = "/dev/ttyO1";
+}  // namespace
 
-UartReceiver::UartReceiver(uint32_t baud_rate) : 
-  baud_rate_(baud_rate) {
-  packet_size_ = DATA_STRUCT_SEND_SIZE;
-  //packet_size_ should be a multiple of four.
-  int toadd = packet_size_ % 4;
-  LOG(DEBUG, "Increasing packet size by %d bytes.\n", toadd);
-  packet_size_ += toadd;
-  
-  // See cows.h for where this comes from.
-  stuffed_size_ = ((packet_size_ - 1) / (pow(2, 32) - 1) + 1) * 4 + packet_size_;
-  
-  buf_ = static_cast<char *>(malloc(stuffed_size_));  
-}
+UartReceiver::UartReceiver(int32_t baud_rate)
+    : baud_rate_(baud_rate),
+      buf_(new AlignedChar[DATA_STRUCT_SEND_SIZE]),
+      fd_(open(device, O_RDWR | O_NOCTTY)) {
+  static_assert((DATA_STRUCT_SEND_SIZE % 4) == 0,
+                "We can't do checksums of lengths that aren't multiples of 4.");
 
-UartReceiver::~UartReceiver() {
-  free(buf_);
-}
-
-int UartReceiver::SetUp() {
-  termios options;
-  serial_struct serinfo;
-
-  if ((fd_ = open("/dev/ttyO1", O_RDWR | O_NOCTTY)) < 0) {
-    LOG(FATAL, "Open() failed with error %d.\
-      (Did you read my note in uart_receiver.cc?)\n", fd_);
+  if (fd_ < 0) {
+    LOG(FATAL, "open(%s, O_RDWR | O_NOCTTY) failed with %d: %s."
+               " Did you read my note in bbb/uart_receiver.cc?\n",
+        device, errno, strerror(errno));
   }
  
+  serial_struct serinfo;
   // Must implement an ugly custom divisor.
   serinfo.reserved_char[0] = 0;
-  if (ioctl(fd_, TIOCGSERIAL, &serinfo) < 0)
-    return -1;
+  if (ioctl(fd_, TIOCGSERIAL, &serinfo) < 0) {
+    LOG(FATAL, "ioctl(%d, TIOCGSERIAL, %p) failed with %d: %s\n",
+        fd_, &serinfo, errno, strerror(errno));
+  }
   serinfo.flags &= ~ASYNC_SPD_MASK;
   serinfo.flags |= ASYNC_SPD_CUST;
   serinfo.custom_divisor = (serinfo.baud_base + (baud_rate_ / 2)) / baud_rate_;
-  if (serinfo.custom_divisor < 1) 
-    serinfo.custom_divisor = 1;
-  if (ioctl(fd_, TIOCSSERIAL, &serinfo) < 0)
-    LOG(ERROR, "First ioctl failed.\n");
-    return -1;
-  if (ioctl(fd_, TIOCGSERIAL, &serinfo) < 0)
-    LOG(ERROR, "Second ioctl failed.\n");
-    return -1;
-  if (serinfo.custom_divisor * static_cast<int>(baud_rate_) 
-    != serinfo.baud_base) {
-    LOG(WARNING, "actual baudrate is %d / %d = %f",
-          serinfo.baud_base, serinfo.custom_divisor,
-          (float)serinfo.baud_base / serinfo.custom_divisor);
+  if (serinfo.custom_divisor < 1) serinfo.custom_divisor = 1;
+  if (ioctl(fd_, TIOCSSERIAL, &serinfo) < 0) {
+    LOG(FATAL, "ioctl(%d, TIOCSSERIAL, %p) failed with %d: %s\n",
+        fd_, &serinfo, errno, strerror(errno));
+  }
+  if (ioctl(fd_, TIOCGSERIAL, &serinfo) < 0) {
+    LOG(FATAL, "ioctl(%d, TIOCGSERIAL, %p) failed with %d: %s\n",
+        fd_, &serinfo, errno, strerror(errno));
+  }
+  if (serinfo.custom_divisor * baud_rate_ != serinfo.baud_base) {
+    LOG(WARNING, "actual baudrate is %d / %d = %f\n",
+        serinfo.baud_base, serinfo.custom_divisor,
+        static_cast<double>(serinfo.baud_base) / serinfo.custom_divisor);
   }
 
-  fcntl(fd_, F_SETFL, 0);
-  tcgetattr(fd_, &options);
-  cfsetispeed(&options, B38400);
-  cfsetospeed(&options, B38400);
+  if (fcntl(fd_, F_SETFL, 0) != 0) {
+    LOG(FATAL, "fcntl(%d, F_SETFL, 0) failed with %d: %s\n",
+        fd_, errno, strerror(errno));
+  }
+
+  termios options;
+  if (tcgetattr(fd_, &options) != 0) {
+    LOG(FATAL, "tcgetattr(%d, %p) failed with %d: %s\n",
+        fd_, &options, errno, strerror(errno));
+  }
+  if (cfsetispeed(&options, B38400) != 0) {
+    LOG(FATAL, "cfsetispeed(%p, B38400) failed with %d: %s\n",
+        &options, errno, strerror(errno));
+  }
+  if (cfsetospeed(&options, B38400) != 0) {
+    LOG(FATAL, "cfsetospeed(%p, B38400) failed with %d: %s\n",
+        &options, errno, strerror(errno));
+  }
   cfmakeraw(&options);
   options.c_cflag |= (CLOCAL | CREAD);
   options.c_cflag &= ~CRTSCTS;
@@ -81,98 +93,86 @@
   options.c_lflag = 0;
   options.c_cc[VMIN] = 0;
   options.c_cc[VTIME] = 1;
-  if (tcsetattr(fd_, TCSANOW, &options) != 0)
-    LOG(ERROR, "Tcsetattr failed.\n");
-    return -1;
-
-  return 0;
+  if (tcsetattr(fd_, TCSANOW, &options) != 0) {
+    LOG(FATAL, "tcsetattr(%d, TCSANOW, %p) failed with %d: %s\n",
+        fd_, &options, errno, strerror(errno));
+  }
 }
 
-int UartReceiver::GetPacket(DataStruct *packet) {
-  int pstarti = 0, bread, cons_zeros = 0;
-  uint32_t readi = 0;
-  bool done = false, has_packet = false;
-  uint32_t ptemp [(stuffed_size_ - 1) / 4 + 1];
+UartReceiver::~UartReceiver() {
+  delete buf_;
+  if (fd_ > 0) close(fd_);
+}
 
-  while (!done && buf_used_ < stuffed_size_) {
-    if ((bread = read(fd_, buf_ + buf_used_, stuffed_size_ - buf_used_)) < 0) {
-      LOG(WARNING, "Read() failed with error %d.\n", bread);
-      return -1;
+bool UartReceiver::FindPacket() {
+  // How many 0 bytes we've found at the front so far.
+  int zeros_found = 0;
+  // How many bytes of the packet we've read in (or -1 if we don't know where
+  // the packet is).
+  int packet_bytes = -1;
+  while (true) {
+    size_t already_read = ::std::max(packet_bytes, 0);
+    ssize_t new_bytes =
+        read(fd_, buf_ + already_read, DATA_STRUCT_SEND_SIZE - already_read);
+    if (new_bytes < 0) {
+      if (errno == EINTR) continue;
+      LOG(WARNING, "read(%d, %p, %zd) failed with %d: %s\n",
+          fd_, buf_ + already_read, DATA_STRUCT_SEND_SIZE - already_read,
+          errno, strerror(errno));
+      return false;
     }
-    buf_used_ += bread;
 
-    // Find the beginning of the packet.
-    // Look for four bytes of zeros.
-    while (readi < buf_used_) {
-      if (buf_[readi] == 0) {
-        if (cons_zeros == 4) {
-          if (has_packet) {
-            // We got to the end of a packet.
-            done = true;
+    if (packet_bytes == -1) {
+      // Find the beginning of the packet (aka look for four zero bytes).
+      for (ssize_t checked = 0; checked < new_bytes; ++checked) {
+        if (buf_[checked] == 0) {
+          ++zeros_found;
+          if (zeros_found == 4) {
+            packet_bytes = new_bytes - checked - 1;
+            memmove(buf_, buf_ + checked + 1, packet_bytes);
             break;
-          } else {
-            // We got to the start of a packet.
-            has_packet = true;
-            pstarti = readi - 3;
           }
         } else {
-          ++cons_zeros;
+          zeros_found = 0;
         }
-      } else {
-        cons_zeros = 0;
       }
-      readi++
+    } else {  // we think there's a packet at the beginning of our buffer
+      for (int to_check = packet_bytes; packet_bytes + new_bytes; ++to_check) {
+        // We shouldn't find any 0s in the middle of what should be a packet.
+        if (buf_[to_check] == 0) {
+          packet_bytes = -1;
+          break;
+        }
+      }
+      packet_bytes += new_bytes;
+      if (packet_bytes == DATA_STRUCT_SEND_SIZE) return true;
     }
   }
+}
 
-  // Copy packet data to output.
-  int filled = 0;
-  readi -= 3; // We read a little into the next packet.
-  for (uint32_t i = pstarti; i < readi - 3; ++i) {
-    ptemp[i] = buf_[i];
-    ++filled;
-  }
-  // Move everything we didn't use to the beginning of the buffer for next time.
-  uint32_t puti = 0;
-  for (uint32_t i = readi; i < stuffed_size_; ++i) {
-    buf_[puti++] = buf_[i];
-  }
-  buf_used_ = stuffed_size_ - readi;
-  readi = 0;
+bool UartReceiver::GetPacket(DataStruct *packet) {
+  if (!FindPacket()) return false;
 
-  // Cows algorithm always outputs something 4-byte aligned.
-  if (filled % 4) {
-    LOG(WARNING, "Rejecting packet due to it not being possible\
-      for cows to have created it.\n");
-    return -1;
-  }
-
-  // Unstuff our packet.
-  uint32_t ptemp_unstuffed [packet_size_];
-  uint32_t bunstuffed;
-  if ((bunstuffed = cows_unstuff(ptemp, sizeof(ptemp), ptemp_unstuffed)) == 0) {
-    LOG(WARNING, "Rejecting packet due to failure to unstuff it.\n");
-    return -1;
-  }
-  if (bunstuffed != packet_size_) {
-    LOG(WARNING, "Rejecting packet of wrong size.\
-      Expected packet of size %d, got packet of size %d.\n",
-      packet_size_, bunstuffed);
-    return -1;
+  uint32_t unstuffed = cows_unstuff(reinterpret_cast<uint32_t *>(buf_),
+                                    DATA_STRUCT_SEND_SIZE / 4,
+                                    reinterpret_cast<uint32_t *>(packet));
+  if (unstuffed == 0) {
+    LOG(WARNING, "invalid packet\n");
+  } else if (unstuffed != sizeof(packet)) {
+    LOG(WARNING, "packet is %" PRIu32 " words instead of %" PRIu32 "\n",
+        unstuffed, DATA_STRUCT_SEND_SIZE / 4);
   }
 
   // Make sure the checksum checks out.
-  uint32_t checksum = static_cast<uint32_t>(ptemp_unstuffed[packet_size_ - 4]);
-  // Checksum only gets done on the actual datastruct part of the packet,
-  // so we'll discard everything after it.
-  memcpy(packet, ptemp_unstuffed, sizeof(DataStruct));
-  if (cape::CalculateChecksum((uint8_t *)packet, sizeof(DataStruct)) != checksum) {
+  uint32_t checksum;
+  memcpy(&checksum, buf_ + DATA_STRUCT_SEND_SIZE - 4, 4);
+  if (cape::CalculateChecksum(reinterpret_cast<uint8_t *>(packet),
+                              sizeof(DataStruct)) != checksum) {
     LOG(WARNING, "Rejecting packet due to checksum failure.\n");
-    return -1;
+    return false;
   }
 
-  return 0;
+  return true;
 }
 
-} // bbb
-
+}  // namespace bbb
diff --git a/bbb_cape/src/bbb/uart_receiver.h b/bbb_cape/src/bbb/uart_receiver.h
index 36bb170..73ba781 100644
--- a/bbb_cape/src/bbb/uart_receiver.h
+++ b/bbb_cape/src/bbb/uart_receiver.h
@@ -1,30 +1,36 @@
 #ifndef FCR971_INPUT_UART_RECEIVER_H_
 #define FRC971_INPUT_UART_RECEIVER_H_
 
-#include <cstdint>
+#include <stdint.h>
 
 #define DATA_STRUCT_NAME DataStruct
-#include <bbb_cape/src/cape/data_struct.h>
+#include "cape/data_struct.h"
 #undef DATA_STRUCT_NAME
 
 namespace bbb {
-  
-  class UartReceiver {
-    uint32_t baud_rate_;   
-    size_t packet_size_, stuffed_size_;
-    int fd_;
-    uint32_t buf_used_;
-    char *buf_;
-  
-  public:
-    UartReceiver(uint32_t baud_rate);
-    ~UartReceiver();
-    // Opens file descriptor, etc.
-    int SetUp();
-    int GetPacket(DataStruct *packet);
-  
-  };
 
-} //bbb
+class UartReceiver {
+ public:
+  UartReceiver(int32_t baud_rate);
+  ~UartReceiver();
+
+  // Returns true if it finds one or false if it gets an I/O error first.
+  // packet must be aligned to 4 bytes.
+  bool GetPacket(DataStruct *packet);
+
+ private:
+  // Reads bytes until there are 4 zeros and then fills up buf_.
+  // Returns true if it finds one or false if it gets an I/O error first or the
+  // packet is invalid in some way.
+  bool FindPacket();
+
+  typedef char __attribute__((aligned(8))) AlignedChar;
+
+  const int32_t baud_rate_;
+  AlignedChar *const buf_;
+  const int fd_;
+};
+
+}  // namespace bbb
 
 #endif
diff --git a/bbb_cape/src/bbb/uart_receiver_main.cc b/bbb_cape/src/bbb/uart_receiver_main.cc
index 272d454..3e31624 100644
--- a/bbb_cape/src/bbb/uart_receiver_main.cc
+++ b/bbb_cape/src/bbb/uart_receiver_main.cc
@@ -1,10 +1,10 @@
-#include <cstdint>
+#include <stdint.h>
 
 #include "aos/atom_code/init.h"
 #include "aos/common/logging/logging_impl.h"
 #include "aos/common/time.h"
-#include "gpios.h"
-#include "uart_receiver.h"
+#include "bbb/gpios.h"
+#include "bbb/uart_receiver.h"
 
 using ::aos::time::Time;
 
@@ -16,7 +16,6 @@
   Time kPacketTimeout = Time::InSeconds(1);
 
   bbb::UartReceiver receiver = bbb::UartReceiver(3000000);
-  receiver.SetUp();
   bbb::Pin reset_pin = bbb::Pin(1, 6);
   reset_pin.MakeOutput();
 
diff --git a/bbb_cape/src/bbb/uart_receiver_test.cc b/bbb_cape/src/bbb/uart_receiver_test.cc
index 601dbf6..0552b20 100644
--- a/bbb_cape/src/bbb/uart_receiver_test.cc
+++ b/bbb_cape/src/bbb/uart_receiver_test.cc
@@ -1,7 +1,8 @@
+#include "bbb/uart_receiver.h"
+
 #include <termios.h>
 
 #include "gtest/gtest.h"
-#include "uart_receiver.h"
 
 namespace bbb {
 namespace {
@@ -14,10 +15,12 @@
   UartReceiverTest () : test_instance_(UartReceiver(3000000)) {}
 };
 
+#if 0
 TEST_F(UartReceiverTest, SetUpTest) {
   // Test its ability to open a file descriptor and set a baud rate.
   ASSERT_EQ(test_instance_.SetUp(), 0);
 }
+#endif
 
-} //namespace
-} //bbb
+}  // namespace
+}  // namespace bbb
diff --git a/bbb_cape/src/cape/cape.gyp b/bbb_cape/src/cape/cape.gyp
index e9d34ef..91ec298 100644
--- a/bbb_cape/src/cape/cape.gyp
+++ b/bbb_cape/src/cape/cape.gyp
@@ -1,4 +1,9 @@
 {
+  'target_defaults': {
+    'include_dirs': [
+      '..',
+    ],
+  },
   'targets': [
     {
       'target_name': 'cows',
@@ -7,5 +12,9 @@
         'cows.c',
       ],
     },
+    {
+      'target_name': 'data_struct',
+      'type': 'static_library',
+    },
   ],
 }
diff --git a/bbb_cape/src/cape/cows.c b/bbb_cape/src/cape/cows.c
index 396889c..16ed1fc 100644
--- a/bbb_cape/src/cape/cows.c
+++ b/bbb_cape/src/cape/cows.c
@@ -1,4 +1,4 @@
-#include "cows.h"
+#include "cape/cows.h"
 
 #include <limits.h>
 
diff --git a/bbb_cape/src/cape/data_struct.h b/bbb_cape/src/cape/data_struct.h
index 95992b9..797648f 100644
--- a/bbb_cape/src/cape/data_struct.h
+++ b/bbb_cape/src/cape/data_struct.h
@@ -60,6 +60,7 @@
 
 // The number of bytes that we actually send (so it stays consistent) (including
 // the byte-stuffing overhead and the CRC on the end).
+// This will always be a multiple of 4.
 #define DATA_STRUCT_SEND_SIZE 200
 
 #ifdef __cplusplus
diff --git a/bbb_cape/src/flasher/build.sh b/bbb_cape/src/flasher/build.sh
index 7e3ddd5..cb50569 100755
--- a/bbb_cape/src/flasher/build.sh
+++ b/bbb_cape/src/flasher/build.sh
@@ -2,6 +2,8 @@
 
 set -e
 
+cd $(dirname $0)
+
 [[ -d stm32flash ]] || ( git clone https://git.gitorious.org/stm32flash/stm32flash.git stm32flash &&
 	cd stm32flash && git checkout 16fbfe6e5854dc36f41712f60b2282cde7571afd && patch -p1 < ../0001-actually-calculate-and-send-a-checksum-for-individua.patch )
 
diff --git a/frc971/atom_code/build.sh b/frc971/atom_code/build.sh
index b8129ab..172b2d4 100755
--- a/frc971/atom_code/build.sh
+++ b/frc971/atom_code/build.sh
@@ -1,3 +1,5 @@
 #!/bin/bash
 
+cd $(dirname $0)
+
 ../../aos/build/build.sh atom atom_code.gyp no "$@"
diff --git a/frc971/crio/build.sh b/frc971/crio/build.sh
index b3fc031..9e77e89 100755
--- a/frc971/crio/build.sh
+++ b/frc971/crio/build.sh
@@ -1,3 +1,5 @@
 #!/bin/bash
 
+cd $(dirname $0)
+
 ../../aos/build/build.sh crio crio.gyp no "$@"