Finish most of the uart stuff.

I've decided to push this, even though I can't test it.
That worries me a little. Use it with caution.

Implement GPIO stuff, and a main executable to receive uart
data. Also make some modifications to Brian's stuff, to get it to
build correctly.

Finally, add some testing stuff. Feel free to disregard that.
I probably won't be using it until I get debian flashed onto
my BeagleBone Black.
diff --git a/bbb_cape/src/bbb/bbb.gyp b/bbb_cape/src/bbb/bbb.gyp
index 9040140..ec617cc 100644
--- a/bbb_cape/src/bbb/bbb.gyp
+++ b/bbb_cape/src/bbb/bbb.gyp
@@ -22,5 +22,41 @@
         'uart_receiver.cc',
       ],
     },
+    {
+      'target_name': 'uart_receiver_test',
+      'type': 'executable',
+      'dependencies': [
+        'uart_receiver',
+        '<(EXTERNALS):gtest',
+        '<(AOS)/build/aos.gyp:logging',
+      ],
+      'sources': [
+        'uart_receiver_test.cc',
+      ],
+    },
+    {
+      'target_name': 'uart_receiver_main',
+      'type': 'executable',
+      'dependencies': [
+        'uart_receiver',
+        'gpios',
+        '<(AOS)/common/common.gyp:time',
+        '<(AOS)/build/aos.gyp:logging',
+        '<(AOS)/atom_code/atom_code.gyp:init',
+      ],
+      'sources': [
+        'uart_receiver_main.cc',
+      ],
+    },
+    {
+      'target_name': 'gpios',
+      'type': 'static_library',
+      'dependencies': [
+        '<(AOS)/build/aos.gyp:logging',
+      ],
+      'sources': [
+        'gpios.cc',
+      ],
+    },
   ],
 }
diff --git a/bbb_cape/src/bbb/gpios.cc b/bbb_cape/src/bbb/gpios.cc
new file mode 100644
index 0000000..e2ab654
--- /dev/null
+++ b/bbb_cape/src/bbb/gpios.cc
@@ -0,0 +1,146 @@
+#include <cstdio>
+#include <cstdlib>
+
+#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() {
+    // 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_);
+  }
+
+  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;
+    }
+
+    fwrite(gpio_num, sizeof(char), 2, handle_);
+    fclose(handle_);
+
+    exported_ = true;
+    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;
+    }
+
+    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 0;
+  }
+
+  int Pin::MakeInput() {
+    if (!exported_) {
+      if (DoExport()) {
+        return -1;
+      }
+    }
+
+    return DoPinDirSet(1);
+  }
+
+  int Pin::MakeOutput() {
+    if (!exported_) {
+      if (DoExport()) {
+        return -1;
+      }
+    }
+
+    return DoPinDirSet(2);
+  }
+
+  int Pin::Write(uint8_t value) {
+    if (direction_ != 2) {
+      LOG(ERROR, "Only pins set as output can be written to.\n");
+      return -1;
+    }
+
+    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::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);
+  }
+
+} // bbb
diff --git a/bbb_cape/src/bbb/gpios.h b/bbb_cape/src/bbb/gpios.h
new file mode 100644
index 0000000..1494da2
--- /dev/null
+++ b/bbb_cape/src/bbb/gpios.h
@@ -0,0 +1,40 @@
+#ifndef BBB_CAPE_SRC_BBB_CAPE_CONTROL_H_
+#define BBB_CAPE_SRC_BBB_CAPE_CONTROL_H_
+
+#include <cstdint>
+#include <cstring>
+
+// As it turns out, controlling the BBB's GPIO pins
+// from C++ is kind of a pain. The purpose of this
+// code is to provide a simple wrapper that masks
+// all the ugly stuff and exposes a nice API.
+
+// Based on example from 
+// <http://learnbuildshare.wordpress.com/2013/05/29/beaglebone-black-digital-ouput/>
+
+namespace bbb {
+
+class Pin {
+  FILE *handle_;
+  int direction_;
+  int kernel_pin_;
+  bool exported_;
+
+  int DoPinDirSet(int direction);
+  int DoExport();
+
+public:
+  // Here, for example, if you wanted to use
+  // GPIO1_28, you would give the ctor
+  // 1, 28 as arguments.
+  Pin(int bank, int pin);
+  ~Pin();
+  int MakeInput();
+  int MakeOutput();
+  int Write(uint8_t value);
+  int Read();
+};
+
+} // bbb
+
+#endif
diff --git a/bbb_cape/src/bbb/uart_receiver.cc b/bbb_cape/src/bbb/uart_receiver.cc
index 981e40b..b7e64c4 100644
--- a/bbb_cape/src/bbb/uart_receiver.cc
+++ b/bbb_cape/src/bbb/uart_receiver.cc
@@ -20,8 +20,9 @@
 
 namespace bbb {
 
-UartReceiver::UartReceiver(uint32_t baud_rate, size_t packet_size) : 
-  baud_rate_(baud_rate), packet_size_(packet_size) {
+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);
@@ -81,7 +82,7 @@
   // We know the minimum size for packets.
   // No use in having it do excessive syscalls.
   options.c_cc[VMIN] = packet_size_;
-  options.c_cc[VTIME] = 0;
+  options.c_cc[VTIME] = 1;
   if (tcsetattr(fd_, TCSANOW, &options) != 0)
     LOG(ERROR, "Tcsetattr failed.\n");
     return -1;
@@ -128,7 +129,7 @@
 
   // Copy packet data to output.
   int filled = 0;
-  readi -= 3;
+  readi -= 3; // We read a little into the next packet.
   for (uint32_t i = pstarti; i < readi - 3; ++i) {
     ptemp[i] = buf_[i];
     ++filled;
@@ -139,6 +140,7 @@
     buf_[puti++] = buf_[i];
   }
   buf_used_ = stuffed_size_ - readi;
+  readi = 0;
 
   // Cows algorithm always outputs something 4-byte aligned.
   if (filled % 4) {
@@ -163,6 +165,8 @@
 
   // 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) {
     LOG(WARNING, "Rejecting packet due to checksum failure.\n");
@@ -172,5 +176,5 @@
   return 0;
 }
 
-} //bbb
+} // bbb
 
diff --git a/bbb_cape/src/bbb/uart_receiver.h b/bbb_cape/src/bbb/uart_receiver.h
index ab6f019..36bb170 100644
--- a/bbb_cape/src/bbb/uart_receiver.h
+++ b/bbb_cape/src/bbb/uart_receiver.h
@@ -10,14 +10,14 @@
 namespace bbb {
   
   class UartReceiver {
-    speed_t baud_rate_;   
+    uint32_t baud_rate_;   
     size_t packet_size_, stuffed_size_;
     int fd_;
     uint32_t buf_used_;
     char *buf_;
   
   public:
-    UartReceiver(uint32_t baud_rate, size_t packet_size);
+    UartReceiver(uint32_t baud_rate);
     ~UartReceiver();
     // Opens file descriptor, etc.
     int SetUp();
diff --git a/bbb_cape/src/bbb/uart_receiver_main.cc b/bbb_cape/src/bbb/uart_receiver_main.cc
new file mode 100644
index 0000000..272d454
--- /dev/null
+++ b/bbb_cape/src/bbb/uart_receiver_main.cc
@@ -0,0 +1,48 @@
+#include <cstdint>
+
+#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"
+
+using ::aos::time::Time;
+
+int main() {
+  aos::Init();
+
+  // time since last good packet before we reset 
+  // the board.
+  Time kPacketTimeout = Time::InSeconds(1);
+
+  bbb::UartReceiver receiver = bbb::UartReceiver(3000000);
+  receiver.SetUp();
+  bbb::Pin reset_pin = bbb::Pin(1, 6);
+  reset_pin.MakeOutput();
+
+  DataStruct packet;
+  Time last_packet_time = Time::Now();
+  while (true) {
+    if (!last_packet_time.IsWithin(Time::Now(),
+      kPacketTimeout.ToNSec())) {
+      
+      LOG(ERROR, "No good packets for too long. Resetting cape.\n");
+      reset_pin.Write(1);
+      ::aos::time::SleepFor(Time::InSeconds(1));
+      reset_pin.Write(0);
+      
+      last_packet_time = Time::Now();
+    }
+
+    if (receiver.GetPacket(&packet)) {
+      LOG(INFO, "Could not get a packet.\n");
+      continue;
+    }
+    last_packet_time = Time::Now();
+
+    //TODO (danielp): Do stuff here with the data we got.
+  }
+
+  aos::Cleanup();
+  return 0;
+}
diff --git a/bbb_cape/src/bbb/uart_receiver_test.cc b/bbb_cape/src/bbb/uart_receiver_test.cc
new file mode 100644
index 0000000..601dbf6
--- /dev/null
+++ b/bbb_cape/src/bbb/uart_receiver_test.cc
@@ -0,0 +1,23 @@
+#include <termios.h>
+
+#include "gtest/gtest.h"
+#include "uart_receiver.h"
+
+namespace bbb {
+namespace {
+
+class UartReceiverTest : public ::testing::Test {
+protected:
+  UartReceiver test_instance_;
+
+public:
+  UartReceiverTest () : test_instance_(UartReceiver(3000000)) {}
+};
+
+TEST_F(UartReceiverTest, SetUpTest) {
+  // Test its ability to open a file descriptor and set a baud rate.
+  ASSERT_EQ(test_instance_.SetUp(), 0);
+}
+
+} //namespace
+} //bbb
diff --git a/bbb_cape/src/cape/cows.c b/bbb_cape/src/cape/cows.c
index 22bd056..396889c 100644
--- a/bbb_cape/src/cape/cows.c
+++ b/bbb_cape/src/cape/cows.c
@@ -5,8 +5,8 @@
 // This implementation is based on
 // <http://www.jacquesf.com/2011/03/consistent-overhead-byte-stuffing/>.
 
-uint32_t cows_stuff(const void *restrict source_in, size_t source_length,
-                    void *restrict destination_in) {
+uint32_t cows_stuff(const void *__restrict__ source_in, size_t source_length,
+                    void *__restrict__ destination_in) {
   const uint32_t *restrict source = (const uint32_t *)source_in;
   uint32_t *restrict destination = (uint32_t *)destination_in;
   size_t source_index = 0;
@@ -34,8 +34,8 @@
   return destination_index;
 }
 
-uint32_t cows_unstuff(const uint32_t *restrict source, size_t source_length,
-                      uint32_t *restrict destination) {
+uint32_t cows_unstuff(const uint32_t *__restrict__ source, size_t source_length,
+                      uint32_t *__restrict__ destination) {
   size_t source_index = 0;
   size_t destination_index = 0;
   uint32_t code;
diff --git a/bbb_cape/src/cape/cows.h b/bbb_cape/src/cape/cows.h
index 27cb556..3a9e6ab 100644
--- a/bbb_cape/src/cape/cows.h
+++ b/bbb_cape/src/cape/cows.h
@@ -4,6 +4,10 @@
 #include <sys/types.h>
 #include <stdint.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 // This file implements something very similar to Consistent Overhead Byte
 // Stuffing <http://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing>. It
 // uses that algorithm except with 4-byte chunks instead of individual bytes
@@ -30,4 +34,8 @@
 uint32_t cows_unstuff(const uint32_t *__restrict__ source, size_t source_length,
                       uint32_t *__restrict__ destination);
 
+#ifdef __cplusplus
+} // extern C
+#endif
+
 #endif  // CAPE_COWS_H_
diff --git a/frc971/atom_code/atom_code.gyp b/frc971/atom_code/atom_code.gyp
index a004c4d..4803265 100644
--- a/frc971/atom_code/atom_code.gyp
+++ b/frc971/atom_code/atom_code.gyp
@@ -25,7 +25,7 @@
         #'camera/camera.gyp:frc971',
         '../../gyro_board/src/libusb-driver/libusb-driver.gyp:get',
         '../input/input.gyp:gyro_sensor_receiver',
-        '<(DEPTH)/bbb_cape/src/bbb/bbb.gyp:uart_receiver',
+        '<(DEPTH)/bbb_cape/src/bbb/bbb.gyp:*',
       ],
       'copies': [
         {