blob: 1f7194654d9c74c393ae61deffc7ce7bfd89f758 [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
Brian Silverman8f8b06f2013-10-30 22:04:27 -07003#include <inttypes.h>
Jim Ostrowski5d5a44f2020-06-24 19:10:15 -07004#include <netinet/in.h>
Brian Silverman8a6dac92015-02-21 20:08:24 -05005#include <stdlib.h>
Jim Ostrowski5d5a44f2020-06-24 19:10:15 -07006#include <unistd.h>
Austin Schuhbe2456e2015-02-16 02:58:00 -08007
John Park33858a32018-09-28 23:05:48 -07008#include "aos/util/string_to_num.h"
Brian Silverman431500a2013-10-28 19:50:15 -07009
Jim Ostrowski5d5a44f2020-06-24 19:10:15 -070010DEFINE_string(
11 override_hostname, "",
Jim Ostrowski2192ddb2020-06-24 19:07:31 -070012 "If set, this forces the hostname of this node to be the provided "
13 "hostname.");
Jim Ostrowski8565b402020-02-29 20:26:53 -080014
Brian Silverman431500a2013-10-28 19:50:15 -070015namespace aos {
16namespace network {
Brian Silverman3dfbfb12020-02-17 20:35:18 -080017namespace team_number_internal {
18
19std::optional<uint16_t> ParseRoborioTeamNumber(const std::string &hostname) {
Austin Schuhbe2456e2015-02-16 02:58:00 -080020 for (size_t i = 0; i < hostname.size(); i++) {
21 if (hostname[i] == '-') {
Austin Schuhdf5591e2015-12-19 22:36:50 -080022 const std::string num_as_s =
23 hostname[hostname.size() - 1] == 'C'
24 ? hostname.substr(i + 1, hostname.size() - 5 - i)
25 : hostname.substr(i + 1);
Austin Schuhbe2456e2015-02-16 02:58:00 -080026
27 int num;
28 if (!::aos::util::StringToNumber(num_as_s, &num)) {
Brian Silverman3dfbfb12020-02-17 20:35:18 -080029 return std::nullopt;
Austin Schuhbe2456e2015-02-16 02:58:00 -080030 }
31 if (hostname.substr(0, i) == "roboRIO" &&
32 std::to_string(num) == num_as_s) {
Brian Silverman3dfbfb12020-02-17 20:35:18 -080033 return num;
Austin Schuhbe2456e2015-02-16 02:58:00 -080034 }
Brian Silverman3dfbfb12020-02-17 20:35:18 -080035 return std::nullopt;
Austin Schuhbe2456e2015-02-16 02:58:00 -080036 }
37 }
Brian Silverman3dfbfb12020-02-17 20:35:18 -080038 return std::nullopt;
Austin Schuhbe2456e2015-02-16 02:58:00 -080039}
Brian Silverman3dfbfb12020-02-17 20:35:18 -080040
Brian Silverman5f06ed22020-02-17 21:49:42 -080041std::optional<uint16_t> ParsePiTeamNumber(const std::string &hostname) {
42 if (hostname.substr(0, 3) != "pi-") {
43 return std::nullopt;
44 }
45 size_t first_separator = hostname.find('-');
46 if (first_separator == hostname.npos ||
47 first_separator >= hostname.size() - 2) {
48 return std::nullopt;
49 }
50 ++first_separator;
51 const size_t second_separator = hostname.find('-', first_separator);
52 if (second_separator == hostname.npos) {
53 return std::nullopt;
54 }
55 const std::string number_string =
56 hostname.substr(first_separator, second_separator - first_separator);
57 int number;
58 if (!util::StringToNumber(number_string, &number)) {
59 return std::nullopt;
60 }
61 return number;
62}
63
Brian Silverman3dfbfb12020-02-17 20:35:18 -080064} // namespace team_number_internal
Austin Schuhdf5591e2015-12-19 22:36:50 -080065
66namespace {
67
68uint16_t override_team;
69
Brian Silverman3dfbfb12020-02-17 20:35:18 -080070uint16_t DoGetTeamNumber() {
John Parka19d1a92019-11-06 18:28:14 -080071 if (override_team != 0) {
Jim Ostrowski5d5a44f2020-06-24 19:10:15 -070072 return override_team;
John Parka19d1a92019-11-06 18:28:14 -080073 }
Brian Silverman8a6dac92015-02-21 20:08:24 -050074
75 const char *override_number = getenv("AOS_TEAM_NUMBER");
76 if (override_number != nullptr) {
Brian Silverman3dfbfb12020-02-17 20:35:18 -080077 uint16_t result;
78 if (!::aos::util::StringToNumber(override_number, &result)) {
79 LOG(FATAL) << "Error parsing AOS_TEAM_NUMBER: " << override_number;
Brian Silverman8a6dac92015-02-21 20:08:24 -050080 }
Brian Silverman3dfbfb12020-02-17 20:35:18 -080081 LOG(WARNING)
82 << "Team number overriden by AOS_TEAM_NUMBER environment variable to "
83 << result;
84 return result;
Austin Schuhbe2456e2015-02-16 02:58:00 -080085 }
Brian Silverman3dfbfb12020-02-17 20:35:18 -080086 const auto hostname = GetHostname();
87 {
88 const auto result = team_number_internal::ParseRoborioTeamNumber(hostname);
89 if (result) {
90 LOG(INFO) << "roboRIO hostname team number is: " << *result;
91 return *result;
92 }
93 }
Brian Silverman5f06ed22020-02-17 21:49:42 -080094 {
95 const auto result = team_number_internal::ParsePiTeamNumber(hostname);
96 if (result) {
97 LOG(INFO) << "Pi hostname team number is: " << *result;
98 return *result;
99 }
100 }
Brian Silverman3dfbfb12020-02-17 20:35:18 -0800101 LOG(FATAL) << "Failed to parse a team number from hostname: " << hostname;
Brian Silverman431500a2013-10-28 19:50:15 -0700102}
103
104} // namespace
105
Austin Schuh288479d2019-12-18 19:47:52 -0800106::std::string GetHostname() {
Jim Ostrowski8565b402020-02-29 20:26:53 -0800107 if (FLAGS_override_hostname.empty()) {
108 char buf[256];
109 buf[sizeof(buf) - 1] = '\0';
110 PCHECK(gethostname(buf, sizeof(buf) - 1) == 0);
111 return buf;
112 } else {
113 return FLAGS_override_hostname;
114 }
Austin Schuh288479d2019-12-18 19:47:52 -0800115}
116
Brian Silverman431500a2013-10-28 19:50:15 -0700117uint16_t GetTeamNumber() {
Brian Silverman3dfbfb12020-02-17 20:35:18 -0800118 const static uint16_t result = DoGetTeamNumber();
John Parka19d1a92019-11-06 18:28:14 -0800119 return result;
Brian Silverman431500a2013-10-28 19:50:15 -0700120}
121
Brian Silvermande0a53a2014-02-10 22:27:44 -0800122void OverrideTeamNumber(uint16_t team) { override_team = team; }
123
Austin Schuh1f2996e2020-03-15 23:09:00 -0700124std::optional<uint16_t> ParsePiNumber(const std::string &hostname) {
125 if (hostname.substr(0, 3) != "pi-") {
126 return std::nullopt;
127 }
128 size_t first_separator = hostname.find('-');
129 if (first_separator == hostname.npos ||
130 first_separator >= hostname.size() - 2) {
131 return std::nullopt;
132 }
133 ++first_separator;
134 const size_t second_separator = hostname.find('-', first_separator);
135 if (second_separator == hostname.npos) {
136 return std::nullopt;
137 }
Jim Ostrowski5d5a44f2020-06-24 19:10:15 -0700138 const std::string number_string = hostname.substr(
139 second_separator + 1, hostname.size() - second_separator - 1);
Austin Schuh1f2996e2020-03-15 23:09:00 -0700140 if (number_string.size() == 0) {
141 return std::nullopt;
142 }
143
144 int number;
145 if (!util::StringToNumber(number_string, &number)) {
146 return std::nullopt;
147 }
148 return number;
149}
150
Brian Silverman431500a2013-10-28 19:50:15 -0700151} // namespace network
152} // namespace aos