copied everything over from 2012 and removed all of the actual robot code except the drivetrain stuff


git-svn-id: https://robotics.mvla.net/svn/frc971/2013/trunk/src@4078 f308d9b7-e957-4cde-b6ac-9a88185e7312
diff --git a/aos/crio/logging/crio_logging.cpp b/aos/crio/logging/crio_logging.cpp
new file mode 100644
index 0000000..8ebafc0
--- /dev/null
+++ b/aos/crio/logging/crio_logging.cpp
@@ -0,0 +1,110 @@
+#include <string.h>
+
+#include "WPILib/Timer.h"
+#include "WPILib/Task.h"
+
+#include "aos/aos_core.h"
+#include "aos/common/network/SendSocket.h"
+#include "aos/common/Configuration.h"
+#include "aos/common/die.h"
+
+#undef ERROR
+#define DECL_LEVEL(name, value) const log_level name = value;
+DECL_LEVELS
+#undef DECL_LEVEL
+
+//#define fprintf(...)
+
+namespace aos {
+namespace logging {
+namespace {
+
+MSG_Q_ID queue;
+uint8_t sequence = 0;
+
+// This gets run in a low-priority task to take the logs from the queue and send
+// them to the atom over a TCP socket.
+void DoTask() {
+  SendSocket sock;
+  log_crio_message msg;
+  while (true) {
+    const int ret = msgQReceive(queue, reinterpret_cast<char *>(&msg),
+                                sizeof(msg), WAIT_FOREVER);
+    if (ret == ERROR) {
+        fprintf(stderr, "logging: warning: receiving a message failed"
+                " with %d (%s)", errno, strerror(errno));
+        continue;
+    }
+    if (ret != sizeof(msg)) {
+      fprintf(stderr, "logging: warning: received a message of size %d "
+              "instead of %zd\n", ret, sizeof(msg));
+      continue;
+    }
+
+    if (sock.LastStatus() != 0) {
+      if (sock.Connect(NetworkPort::kLogs,
+                       configuration::GetIPAddress(
+                           configuration::NetworkDevice::kAtom),
+                       SOCK_STREAM) != 0) {
+        fprintf(stderr, "logging: warning: connecting failed"
+                " because of %d: %s\n", errno, strerror(errno));
+      }
+    }
+    sock.Send(&msg, sizeof(msg));
+    if (sock.LastStatus() != 0) {
+      fprintf(stderr, "logging: warning: sending '%s' failed"
+              " because of %d: %s\n", msg.message, errno, strerror(errno));
+    }
+  }
+}
+
+}  // namespace
+
+void Start() {
+  queue = msgQCreate(100,  // max messages
+                     sizeof(log_crio_message),
+                     MSG_Q_PRIORITY);
+  Task *task = new Task("LogSender",
+                        (FUNCPTR)(DoTask),
+                        150);  // priority
+  task->Start();
+}
+
+int Do(log_level level, const char *format, ...) {
+  log_crio_message msg;
+  msg.time = Timer::GetFPGATimestamp();
+  msg.level = level;
+  msg.sequence = __sync_fetch_and_add(&sequence, 1);
+
+  const char *continued = "...";
+  const size_t size = sizeof(msg.message) - strlen(continued);
+  va_list ap;
+  va_start(ap, format);
+  const int ret = vsnprintf(msg.message, size, format, ap);
+  va_end(ap);
+
+  if (ret < 0) {
+    fprintf(stderr, "logging: error: vsnprintf failed with %d (%s)\n",
+            errno, strerror(errno));
+    return -1;
+  } else if (static_cast<uintmax_t>(ret) >= static_cast<uintmax_t>(size)) {
+    // overwrite the NULL at the end of the existing one and
+    // copy in the one on the end of continued
+    memcpy(&msg.message[size - 1], continued, strlen(continued) + 1);
+  }
+  if (msgQSend(queue, reinterpret_cast<char *>(&msg), sizeof(msg),
+               NO_WAIT, MSG_PRI_NORMAL) == ERROR) {
+    fprintf(stderr, "logging: warning: sending message '%s'"
+            " failed with %d (%s)", msg.message, errno, strerror(errno));
+    return -1;
+  }
+
+  if (level == FATAL) {
+    aos::Die("%s", msg.message);
+  }
+
+  return 0;
+}
+
+}  // namespace logging
+}  // namespace aos