blob: 8885b52526aacd0f2a219bfa49f9d2f99a4259a5 [file] [log] [blame]
John Park33858a32018-09-28 23:05:48 -07001#include "aos/network/team_number.h"
Brian Silverman431500a2013-10-28 19:50:15 -07002
Jim Ostrowski5d5a44f2020-06-24 19:10:15 -07003#include <netinet/in.h>
Jim Ostrowski5d5a44f2020-06-24 19:10:15 -07004#include <unistd.h>
Austin Schuhbe2456e2015-02-16 02:58:00 -08005
Tyler Chatowbf0609c2021-07-31 16:13:27 -07006#include <cinttypes>
7#include <cstdlib>
8
Austin Schuh4c84abb2021-06-20 18:16:32 -07009#include "absl/strings/numbers.h"
Brian Silverman431500a2013-10-28 19:50:15 -070010
Jim Ostrowski5d5a44f2020-06-24 19:10:15 -070011DEFINE_string(
12 override_hostname, "",
Jim Ostrowski2192ddb2020-06-24 19:07:31 -070013 "If set, this forces the hostname of this node to be the provided "
14 "hostname.");
Jim Ostrowski8565b402020-02-29 20:26:53 -080015
Brian Silverman431500a2013-10-28 19:50:15 -070016namespace aos {
17namespace network {
Brian Silverman3dfbfb12020-02-17 20:35:18 -080018namespace team_number_internal {
19
Austin Schuh4c84abb2021-06-20 18:16:32 -070020std::optional<uint16_t> ParseRoborioTeamNumber(
21 const std::string_view hostname) {
Austin Schuhbe2456e2015-02-16 02:58:00 -080022 for (size_t i = 0; i < hostname.size(); i++) {
23 if (hostname[i] == '-') {
Austin Schuh4c84abb2021-06-20 18:16:32 -070024 const std::string_view num_as_s =
Austin Schuhdf5591e2015-12-19 22:36:50 -080025 hostname[hostname.size() - 1] == 'C'
26 ? hostname.substr(i + 1, hostname.size() - 5 - i)
27 : hostname.substr(i + 1);
Austin Schuhbe2456e2015-02-16 02:58:00 -080028
29 int num;
Austin Schuh4c84abb2021-06-20 18:16:32 -070030 if (!absl::SimpleAtoi(num_as_s, &num)) {
Brian Silverman3dfbfb12020-02-17 20:35:18 -080031 return std::nullopt;
Austin Schuhbe2456e2015-02-16 02:58:00 -080032 }
33 if (hostname.substr(0, i) == "roboRIO" &&
34 std::to_string(num) == num_as_s) {
Brian Silverman3dfbfb12020-02-17 20:35:18 -080035 return num;
Austin Schuhbe2456e2015-02-16 02:58:00 -080036 }
Brian Silverman3dfbfb12020-02-17 20:35:18 -080037 return std::nullopt;
Austin Schuhbe2456e2015-02-16 02:58:00 -080038 }
39 }
Brian Silverman3dfbfb12020-02-17 20:35:18 -080040 return std::nullopt;
Austin Schuhbe2456e2015-02-16 02:58:00 -080041}
Brian Silverman3dfbfb12020-02-17 20:35:18 -080042
Austin Schuh4c84abb2021-06-20 18:16:32 -070043std::optional<uint16_t> ParsePiTeamNumber(const std::string_view hostname) {
Brian Silverman5f06ed22020-02-17 21:49:42 -080044 if (hostname.substr(0, 3) != "pi-") {
45 return std::nullopt;
46 }
47 size_t first_separator = hostname.find('-');
48 if (first_separator == hostname.npos ||
49 first_separator >= hostname.size() - 2) {
50 return std::nullopt;
51 }
52 ++first_separator;
53 const size_t second_separator = hostname.find('-', first_separator);
54 if (second_separator == hostname.npos) {
55 return std::nullopt;
56 }
Austin Schuh4c84abb2021-06-20 18:16:32 -070057 const std::string_view number_string =
Brian Silverman5f06ed22020-02-17 21:49:42 -080058 hostname.substr(first_separator, second_separator - first_separator);
59 int number;
Austin Schuh4c84abb2021-06-20 18:16:32 -070060 if (!absl::SimpleAtoi(number_string, &number)) {
Brian Silverman5f06ed22020-02-17 21:49:42 -080061 return std::nullopt;
62 }
63 return number;
64}
65
Brian Silverman3dfbfb12020-02-17 20:35:18 -080066} // namespace team_number_internal
Austin Schuhdf5591e2015-12-19 22:36:50 -080067
68namespace {
69
70uint16_t override_team;
71
Brian Silverman3dfbfb12020-02-17 20:35:18 -080072uint16_t DoGetTeamNumber() {
John Parka19d1a92019-11-06 18:28:14 -080073 if (override_team != 0) {
Jim Ostrowski5d5a44f2020-06-24 19:10:15 -070074 return override_team;
John Parka19d1a92019-11-06 18:28:14 -080075 }
Brian Silverman8a6dac92015-02-21 20:08:24 -050076
77 const char *override_number = getenv("AOS_TEAM_NUMBER");
78 if (override_number != nullptr) {
Austin Schuh4c84abb2021-06-20 18:16:32 -070079 uint32_t result;
80 if (!absl::SimpleAtoi(override_number, &result)) {
Brian Silverman3dfbfb12020-02-17 20:35:18 -080081 LOG(FATAL) << "Error parsing AOS_TEAM_NUMBER: " << override_number;
Brian Silverman8a6dac92015-02-21 20:08:24 -050082 }
Brian Silverman3dfbfb12020-02-17 20:35:18 -080083 LOG(WARNING)
84 << "Team number overriden by AOS_TEAM_NUMBER environment variable to "
85 << result;
86 return result;
Austin Schuhbe2456e2015-02-16 02:58:00 -080087 }
Brian Silverman3dfbfb12020-02-17 20:35:18 -080088 const auto hostname = GetHostname();
89 {
90 const auto result = team_number_internal::ParseRoborioTeamNumber(hostname);
91 if (result) {
92 LOG(INFO) << "roboRIO hostname team number is: " << *result;
93 return *result;
94 }
95 }
Brian Silverman5f06ed22020-02-17 21:49:42 -080096 {
97 const auto result = team_number_internal::ParsePiTeamNumber(hostname);
98 if (result) {
99 LOG(INFO) << "Pi hostname team number is: " << *result;
100 return *result;
101 }
102 }
Brian Silverman3dfbfb12020-02-17 20:35:18 -0800103 LOG(FATAL) << "Failed to parse a team number from hostname: " << hostname;
Brian Silverman431500a2013-10-28 19:50:15 -0700104}
105
106} // namespace
107
Austin Schuh288479d2019-12-18 19:47:52 -0800108::std::string GetHostname() {
Jim Ostrowski8565b402020-02-29 20:26:53 -0800109 if (FLAGS_override_hostname.empty()) {
110 char buf[256];
111 buf[sizeof(buf) - 1] = '\0';
112 PCHECK(gethostname(buf, sizeof(buf) - 1) == 0);
113 return buf;
114 } else {
115 return FLAGS_override_hostname;
116 }
Austin Schuh288479d2019-12-18 19:47:52 -0800117}
118
Brian Silverman431500a2013-10-28 19:50:15 -0700119uint16_t GetTeamNumber() {
Brian Silverman3dfbfb12020-02-17 20:35:18 -0800120 const static uint16_t result = DoGetTeamNumber();
John Parka19d1a92019-11-06 18:28:14 -0800121 return result;
Brian Silverman431500a2013-10-28 19:50:15 -0700122}
123
Brian Silvermande0a53a2014-02-10 22:27:44 -0800124void OverrideTeamNumber(uint16_t team) { override_team = team; }
125
Austin Schuh4c84abb2021-06-20 18:16:32 -0700126std::optional<uint16_t> ParsePiNumber(const std::string_view hostname) {
Austin Schuh1f2996e2020-03-15 23:09:00 -0700127 if (hostname.substr(0, 3) != "pi-") {
128 return std::nullopt;
129 }
130 size_t first_separator = hostname.find('-');
131 if (first_separator == hostname.npos ||
132 first_separator >= hostname.size() - 2) {
133 return std::nullopt;
134 }
135 ++first_separator;
136 const size_t second_separator = hostname.find('-', first_separator);
137 if (second_separator == hostname.npos) {
138 return std::nullopt;
139 }
Austin Schuh4c84abb2021-06-20 18:16:32 -0700140 const std::string_view number_string = hostname.substr(
Jim Ostrowski5d5a44f2020-06-24 19:10:15 -0700141 second_separator + 1, hostname.size() - second_separator - 1);
Austin Schuh1f2996e2020-03-15 23:09:00 -0700142 if (number_string.size() == 0) {
143 return std::nullopt;
144 }
145
146 int number;
Austin Schuh4c84abb2021-06-20 18:16:32 -0700147 if (!absl::SimpleAtoi(number_string, &number)) {
Austin Schuh1f2996e2020-03-15 23:09:00 -0700148 return std::nullopt;
149 }
150 return number;
151}
152
Brian Silverman431500a2013-10-28 19:50:15 -0700153} // namespace network
154} // namespace aos