Example #1
0
// These error strings are checked in tcp_test.cpp and should be kept in sync.
bool TcpTransport::InitializeProtocol(std::string* error) {
    std::string handshake_message(android::base::StringPrintf("FB%02d", kProtocolVersion));

    if (!socket_->Send(handshake_message.c_str(), kHandshakeLength)) {
        *error = android::base::StringPrintf("Failed to send initialization message (%s)",
                                             Socket::GetErrorMessage().c_str());
        return false;
    }

    char buffer[kHandshakeLength];
    if (socket_->ReceiveAll(buffer, kHandshakeLength, kHandshakeTimeoutMs) != kHandshakeLength) {
        *error = android::base::StringPrintf(
                "No initialization message received (%s). Target may not support TCP fastboot",
                Socket::GetErrorMessage().c_str());
        return false;
    }

    if (memcmp(buffer, "FB", 2) != 0) {
        *error = "Unrecognized initialization message. Target may not support TCP fastboot";
        return false;
    }

    if (memcmp(buffer + 2, "01", 2) != 0) {
        *error = android::base::StringPrintf("Unknown TCP protocol version %s (host version %02d)",
                                             std::string(buffer + 2, 2).c_str(), kProtocolVersion);
        return false;
    }

    error->clear();
    return true;
}
int main(int argc, char *argv[]) {
    base::CommandLine::Init(argc, argv);
    base::CommandLine* cl = base::CommandLine::ForCurrentProcess();

    int32_t port = kDefaultPort;
    if (cl->HasSwitch(kPort)) {
        std::string value = cl->GetSwitchValueASCII(kPort);
        base::StringToInt(value, &port);
    }

    // Puch a TCP hole to accept connection
    FwDaemon daemon(std::unique_ptr<FirewallInterface>{new FirewalldFirewall()}, (uint16_t)port);
    daemon.Run();

    std::unique_ptr<Socket> server = Socket::NewServer(Socket::Protocol::kTcp, port);
    if (server == nullptr) {
        ALOGE("Failed to create fastbootd service.");
        return 1;
    }

    int fastbootd_reboot = 0;
    if (property_get_bool("persist.sys.fastbootd.reboot", 1)) {
        pthread_t hreboot;
        pthread_create(&hreboot, NULL, thread_reboot, &fastbootd_reboot);
        fastbootd_reboot = 1;
    }

    // Check if in demo mode
    if (fastbootd_reboot == 1) {
        struct stat st;
        int result = stat("/boot/DEMO", &st);
        if (result == 0 && S_ISREG(st.st_mode)) {
            fastbootd_reboot = 0;
        }
    }

    std::string handshake_message(android::base::StringPrintf("FB%02d", kProtocolVersion));
    while (true) {
        std::unique_ptr<Socket> client = server->Accept();
        if (client == nullptr) {
            ALOGE("Failed to accept client connection.");
            continue;
        }

        char buffer[4];
        ssize_t bytes = client->Receive(buffer, sizeof(buffer), 500);
        if (bytes != 4) {
            ALOGE("Failed to get client version.");
            continue;
        }

        if (memcmp(buffer, "FB01", 4) != 0) {
            ALOGE("Unsupported client: %c%c%c%c", buffer[0], buffer[1], buffer[2], buffer[3]);
            continue;
        }

        if (fastbootd_reboot) {
            fastbootd_reboot = 0;
            property_set("persist.sys.fastbootd.reboot", "0");
        }

        if (!client->Send(handshake_message.c_str(), kHandshakeLength)) {
            ALOGE("Failed to send handshake.");
            continue;
        }

        command_loop(client.get());
    }

    return 0;
}