Removed Common

Change-Id: I01ea8f07220375c2ad9bc0092281d4f27c642303
diff --git a/aos/network/BUILD b/aos/network/BUILD
new file mode 100644
index 0000000..5c1eb03
--- /dev/null
+++ b/aos/network/BUILD
@@ -0,0 +1,31 @@
+package(default_visibility = ["//visibility:public"])
+
+cc_library(
+    name = "team_number",
+    srcs = [
+        "team_number.cc",
+    ],
+    hdrs = [
+        "team_number.h",
+    ],
+    compatible_with = [
+        "//tools:armhf-debian",
+    ],
+    deps = [
+        "//aos:once",
+        "//aos/logging",
+        "//aos/util:string_to_num",
+        "//aos/linux_code:configuration",
+    ],
+)
+
+cc_test(
+    name = "team_number_test",
+    srcs = [
+        "team_number_test.cc",
+    ],
+    deps = [
+        ":team_number",
+        "//aos/testing:googletest",
+    ],
+)
diff --git a/aos/network/team_number.cc b/aos/network/team_number.cc
new file mode 100644
index 0000000..eb17e7a
--- /dev/null
+++ b/aos/network/team_number.cc
@@ -0,0 +1,86 @@
+#include "aos/network/team_number.h"
+
+#include <netinet/in.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <string>
+
+#include "aos/logging/logging.h"
+#include "aos/util/string_to_num.h"
+#include "aos/linux_code/configuration.h"
+#include "aos/once.h"
+
+namespace aos {
+namespace network {
+namespace internal {
+int ParseTeamNumber(const std::string &hostname, uint16_t *teamnumber) {
+  for (size_t i = 0; i < hostname.size(); i++) {
+    if (hostname[i] == '-') {
+      const std::string num_as_s =
+          hostname[hostname.size() - 1] == 'C'
+              ? hostname.substr(i + 1, hostname.size() - 5 - i)
+              : hostname.substr(i + 1);
+
+      int num;
+      if (!::aos::util::StringToNumber(num_as_s, &num)) {
+        return -1;
+      }
+      if (hostname.substr(0, i) == "roboRIO" &&
+          std::to_string(num) == num_as_s) {
+        *teamnumber = num;
+        return 0;
+      } else {
+        return -1;
+      }
+    }
+  }
+  return -1;
+}
+}  // namespace internal
+
+namespace {
+
+uint16_t override_team;
+
+::std::string GetHostname() {
+  char buf[256];
+  buf[sizeof(buf) - 1] = '\0';
+  PCHECK(gethostname(buf, sizeof(buf) - 1));
+  return buf;
+}
+
+uint16_t *DoGetTeamNumber() {
+  if (override_team != 0) return &override_team;
+
+  static uint16_t r;
+
+  const char *override_number = getenv("AOS_TEAM_NUMBER");
+  if (override_number != nullptr) {
+    if (!::aos::util::StringToNumber(override_number, &r)) {
+      LOG(FATAL, "error parsing AOS_TEAM_NUMBER '%s'\n", override_number);
+    }
+    LOG(WARNING, "team number overridden by AOS_TEAM_NUMBER to %" PRIu16 "\n",
+        r);
+  } else {
+    int error = internal::ParseTeamNumber(GetHostname(), &r);
+    if (error) {
+      LOG(FATAL, "Invalid hostname %s\n", GetHostname().c_str());
+    }
+    LOG(INFO, "team number is %" PRIu16 "\n", r);
+  }
+  return &r;
+}
+
+}  // namespace
+
+uint16_t GetTeamNumber() {
+  static Once<uint16_t> once(DoGetTeamNumber);
+  return *once.Get();
+}
+
+void OverrideTeamNumber(uint16_t team) { override_team = team; }
+
+}  // namespace network
+}  // namespace aos
diff --git a/aos/network/team_number.h b/aos/network/team_number.h
new file mode 100644
index 0000000..6540283
--- /dev/null
+++ b/aos/network/team_number.h
@@ -0,0 +1,29 @@
+#ifndef AOS_NETWORK_TEAM_NUMBER_H_
+#define AOS_NETWORK_TEAM_NUMBER_H_
+
+#include <stdint.h>
+
+#include <string>
+
+namespace aos {
+namespace network {
+
+// Retrieves the current team number based off of the network address.
+// This function will only do the complicated stuff once so it is cheap to call
+// repeatedly.
+uint16_t GetTeamNumber();
+
+// Overrides the team number returned from GetTeamNumber(). Must be called
+// before GetTeamNumber() is ever called.
+// Overriding to team 0 won't work.
+// Intended only for tests.
+// Guaranteed to be safe to call during static initialization time.
+void OverrideTeamNumber(uint16_t team);
+
+namespace internal {
+int ParseTeamNumber(const std::string &hostname, uint16_t *teamnumber);
+}  // namespace internal
+}  // namespace network
+}  // namespace aos
+
+#endif  // AOS_NETWORK_TEAM_NUMBER_H_
diff --git a/aos/network/team_number_test.cc b/aos/network/team_number_test.cc
new file mode 100644
index 0000000..ee3f2db
--- /dev/null
+++ b/aos/network/team_number_test.cc
@@ -0,0 +1,33 @@
+#include "aos/network/team_number.h"
+
+#include "gtest/gtest.h"
+
+#include "aos/macros.h"
+
+namespace aos {
+namespace network {
+namespace internal {
+namespace testing {
+
+TEST(TeamNumberTest, Parse2015TeamNumber) {
+  uint16_t team_number;
+  EXPECT_EQ(0, ParseTeamNumber("roboRIO-971", &team_number));
+  EXPECT_EQ(971u, team_number);
+
+  EXPECT_EQ(0, ParseTeamNumber("roboRIO-8971", &team_number));
+  EXPECT_EQ(8971u, team_number);
+}
+
+TEST(TeamNumberTest, Parse2016TeamNumber) {
+  uint16_t team_number;
+  EXPECT_EQ(0, ParseTeamNumber("roboRIO-971-FRC", &team_number));
+  EXPECT_EQ(971u, team_number);
+
+  EXPECT_EQ(0, ParseTeamNumber("roboRIO-8971-FRC", &team_number));
+  EXPECT_EQ(8971u, team_number);
+}
+
+}  // namespace testing
+}  // namespace internal
+}  // namespace network
+}  // namespace aos