Loading fastboot/fastboot.cpp +46 −22 Original line number Diff line number Diff line Loading @@ -342,30 +342,49 @@ struct NetworkSerial { int port; }; static Result<NetworkSerial> ParseNetworkSerial(const std::string& serial) { const auto serial_parsed = android::base::Tokenize(serial, ":"); const auto parsed_segments_count = serial_parsed.size(); if (parsed_segments_count != 2 && parsed_segments_count != 3) { return Error() << "invalid network address: " << serial << ". Expected format:\n" << "<protocol>:<address>:<port> (tcp:localhost:5554)"; } class ParseNetworkAddressError { public: enum Type { WRONG_PREFIX = 1, WRONG_ADDRESS = 2 }; ParseNetworkAddressError(Type&& type) : type_(std::forward<Type>(type)) {} Type value() const { return type_; } operator Type() const { return value(); } std::string print() const { return ""; } private: Type type_; }; static Result<NetworkSerial, ParseNetworkAddressError> ParseNetworkSerial( const std::string& serial) { Socket::Protocol protocol; if (serial_parsed[0] == "tcp") { const char* net_address = nullptr; int port = 0; if (android::base::StartsWith(serial, "tcp:")) { protocol = Socket::Protocol::kTcp; } else if (serial_parsed[0] == "udp") { net_address = serial.c_str() + strlen("tcp:"); port = tcp::kDefaultPort; } else if (android::base::StartsWith(serial, "udp:")) { protocol = Socket::Protocol::kUdp; net_address = serial.c_str() + strlen("udp:"); port = udp::kDefaultPort; } else { return Error() << "invalid network address: " << serial << ". Expected format:\n" return Error<ParseNetworkAddressError>(ParseNetworkAddressError::Type::WRONG_PREFIX) << "protocol prefix ('tcp:' or 'udp:') is missed: " << serial << ". " << "Expected address format:\n" << "<protocol>:<address>:<port> (tcp:localhost:5554)"; } int port = 5554; if (parsed_segments_count == 3) { android::base::ParseInt(serial_parsed[2], &port, 5554); std::string error; std::string host; if (!android::base::ParseNetAddress(net_address, &host, &port, nullptr, &error)) { return Error<ParseNetworkAddressError>(ParseNetworkAddressError::Type::WRONG_ADDRESS) << "invalid network address '" << net_address << "': " << error; } return NetworkSerial{protocol, serial_parsed[1], port}; return NetworkSerial{protocol, host, port}; } // Opens a new Transport connected to the particular device. Loading @@ -380,7 +399,8 @@ static Result<NetworkSerial> ParseNetworkSerial(const std::string& serial) { // object, and the caller should not attempt to delete the returned Transport. static Transport* open_device(const char* local_serial, bool wait_for_device = true, bool announce = true) { const Result<NetworkSerial> network_serial = ParseNetworkSerial(local_serial); const Result<NetworkSerial, ParseNetworkAddressError> network_serial = ParseNetworkSerial(local_serial); Transport* transport = nullptr; while (true) { Loading @@ -397,8 +417,12 @@ static Transport* open_device(const char* local_serial, bool wait_for_device = t if (transport == nullptr && announce) { LOG(ERROR) << "error: " << error; } } else { } else if (network_serial.error().code() == ParseNetworkAddressError::Type::WRONG_PREFIX) { // WRONG_PREFIX is special because it happens when user wants to communicate with USB // device transport = usb_open(match_fastboot(local_serial)); } else { Expect(network_serial); } if (transport != nullptr) { Loading @@ -413,7 +437,7 @@ static Transport* open_device(const char* local_serial, bool wait_for_device = t announce = false; LOG(ERROR) << "< waiting for " << local_serial << ">"; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::seconds(1)); } } Loading Loading @@ -476,7 +500,7 @@ static Transport* open_device() { announce = false; LOG(ERROR) << "< waiting for any device >"; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::seconds(1)); } } Loading @@ -487,7 +511,7 @@ static int Connect(int argc, char* argv[]) { } const char* local_serial = *argv; EXPECT(ParseNetworkSerial(local_serial)); Expect(ParseNetworkSerial(local_serial)); const Transport* transport = open_device(local_serial, false); if (transport == nullptr) { Loading @@ -506,7 +530,7 @@ static int Connect(int argc, char* argv[]) { } static int Disconnect(const char* local_serial) { EXPECT(ParseNetworkSerial(local_serial)); Expect(ParseNetworkSerial(local_serial)); ConnectedDevicesStorage storage; { Loading Loading @@ -1557,7 +1581,7 @@ void reboot_to_userspace_fastboot() { delete old_transport; // Give the current connection time to close. std::this_thread::sleep_for(std::chrono::milliseconds(1000)); std::this_thread::sleep_for(std::chrono::seconds(1)); fb->set_transport(open_device()); Loading fastboot/util.h +10 −2 Original line number Diff line number Diff line Loading @@ -18,8 +18,16 @@ using android::base::Error; using android::base::Result; using android::base::ResultError; #define EXPECT(result) \ (result.ok() ? result.value() : (LOG(FATAL) << result.error().message(), result.value())) template <typename T, typename U> inline T Expect(Result<T, U> r) { if (r.ok()) { return r.value(); } LOG(FATAL) << r.error().message(); return r.value(); } using SparsePtr = std::unique_ptr<sparse_file, decltype(&sparse_file_destroy)>; Loading Loading
fastboot/fastboot.cpp +46 −22 Original line number Diff line number Diff line Loading @@ -342,30 +342,49 @@ struct NetworkSerial { int port; }; static Result<NetworkSerial> ParseNetworkSerial(const std::string& serial) { const auto serial_parsed = android::base::Tokenize(serial, ":"); const auto parsed_segments_count = serial_parsed.size(); if (parsed_segments_count != 2 && parsed_segments_count != 3) { return Error() << "invalid network address: " << serial << ". Expected format:\n" << "<protocol>:<address>:<port> (tcp:localhost:5554)"; } class ParseNetworkAddressError { public: enum Type { WRONG_PREFIX = 1, WRONG_ADDRESS = 2 }; ParseNetworkAddressError(Type&& type) : type_(std::forward<Type>(type)) {} Type value() const { return type_; } operator Type() const { return value(); } std::string print() const { return ""; } private: Type type_; }; static Result<NetworkSerial, ParseNetworkAddressError> ParseNetworkSerial( const std::string& serial) { Socket::Protocol protocol; if (serial_parsed[0] == "tcp") { const char* net_address = nullptr; int port = 0; if (android::base::StartsWith(serial, "tcp:")) { protocol = Socket::Protocol::kTcp; } else if (serial_parsed[0] == "udp") { net_address = serial.c_str() + strlen("tcp:"); port = tcp::kDefaultPort; } else if (android::base::StartsWith(serial, "udp:")) { protocol = Socket::Protocol::kUdp; net_address = serial.c_str() + strlen("udp:"); port = udp::kDefaultPort; } else { return Error() << "invalid network address: " << serial << ". Expected format:\n" return Error<ParseNetworkAddressError>(ParseNetworkAddressError::Type::WRONG_PREFIX) << "protocol prefix ('tcp:' or 'udp:') is missed: " << serial << ". " << "Expected address format:\n" << "<protocol>:<address>:<port> (tcp:localhost:5554)"; } int port = 5554; if (parsed_segments_count == 3) { android::base::ParseInt(serial_parsed[2], &port, 5554); std::string error; std::string host; if (!android::base::ParseNetAddress(net_address, &host, &port, nullptr, &error)) { return Error<ParseNetworkAddressError>(ParseNetworkAddressError::Type::WRONG_ADDRESS) << "invalid network address '" << net_address << "': " << error; } return NetworkSerial{protocol, serial_parsed[1], port}; return NetworkSerial{protocol, host, port}; } // Opens a new Transport connected to the particular device. Loading @@ -380,7 +399,8 @@ static Result<NetworkSerial> ParseNetworkSerial(const std::string& serial) { // object, and the caller should not attempt to delete the returned Transport. static Transport* open_device(const char* local_serial, bool wait_for_device = true, bool announce = true) { const Result<NetworkSerial> network_serial = ParseNetworkSerial(local_serial); const Result<NetworkSerial, ParseNetworkAddressError> network_serial = ParseNetworkSerial(local_serial); Transport* transport = nullptr; while (true) { Loading @@ -397,8 +417,12 @@ static Transport* open_device(const char* local_serial, bool wait_for_device = t if (transport == nullptr && announce) { LOG(ERROR) << "error: " << error; } } else { } else if (network_serial.error().code() == ParseNetworkAddressError::Type::WRONG_PREFIX) { // WRONG_PREFIX is special because it happens when user wants to communicate with USB // device transport = usb_open(match_fastboot(local_serial)); } else { Expect(network_serial); } if (transport != nullptr) { Loading @@ -413,7 +437,7 @@ static Transport* open_device(const char* local_serial, bool wait_for_device = t announce = false; LOG(ERROR) << "< waiting for " << local_serial << ">"; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::seconds(1)); } } Loading Loading @@ -476,7 +500,7 @@ static Transport* open_device() { announce = false; LOG(ERROR) << "< waiting for any device >"; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::seconds(1)); } } Loading @@ -487,7 +511,7 @@ static int Connect(int argc, char* argv[]) { } const char* local_serial = *argv; EXPECT(ParseNetworkSerial(local_serial)); Expect(ParseNetworkSerial(local_serial)); const Transport* transport = open_device(local_serial, false); if (transport == nullptr) { Loading @@ -506,7 +530,7 @@ static int Connect(int argc, char* argv[]) { } static int Disconnect(const char* local_serial) { EXPECT(ParseNetworkSerial(local_serial)); Expect(ParseNetworkSerial(local_serial)); ConnectedDevicesStorage storage; { Loading Loading @@ -1557,7 +1581,7 @@ void reboot_to_userspace_fastboot() { delete old_transport; // Give the current connection time to close. std::this_thread::sleep_for(std::chrono::milliseconds(1000)); std::this_thread::sleep_for(std::chrono::seconds(1)); fb->set_transport(open_device()); Loading
fastboot/util.h +10 −2 Original line number Diff line number Diff line Loading @@ -18,8 +18,16 @@ using android::base::Error; using android::base::Result; using android::base::ResultError; #define EXPECT(result) \ (result.ok() ? result.value() : (LOG(FATAL) << result.error().message(), result.value())) template <typename T, typename U> inline T Expect(Result<T, U> r) { if (r.ok()) { return r.value(); } LOG(FATAL) << r.error().message(); return r.value(); } using SparsePtr = std::unique_ptr<sparse_file, decltype(&sparse_file_destroy)>; Loading