Merge "fastboot: Fix IPv6 connect and -s host parsing"

This commit is contained in:
Treehugger Robot 2023-02-28 22:46:02 +00:00 committed by Gerrit Code Review
commit 396b107a41
2 changed files with 56 additions and 24 deletions

View file

@ -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"
<< "<protocol>:<address>:<port> (tcp:localhost:5554)";
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.
@ -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) {
@ -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) {
@ -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));
}
}
@ -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));
}
}
@ -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) {
@ -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;
{
@ -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());

View file

@ -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)>;