Ejemplo n.º 1
0
static int _adb_connect(const std::string& service, std::string* error) {
    D("_adb_connect: %s", service.c_str());
    if (service.empty() || service.size() > MAX_PAYLOAD) {
        *error = android::base::StringPrintf("bad service name length (%zd)",
                                             service.size());
        return -1;
    }

    std::string reason;
    int fd = socket_spec_connect(__adb_server_socket_spec, &reason);
    if (fd < 0) {
        *error = android::base::StringPrintf("cannot connect to daemon at %s: %s",
                                             __adb_server_socket_spec, reason.c_str());
        return -2;
    }

    if (memcmp(&service[0], "host", 4) != 0 && switch_socket_transport(fd, error)) {
        return -1;
    }

    if (!SendProtocolString(fd, service)) {
        *error = perror_str("write failure during connection");
        adb_close(fd);
        return -1;
    }

    if (!adb_status(fd, error)) {
        adb_close(fd);
        return -1;
    }

    D("_adb_connect: return fd %d", fd);
    return fd;
}
Ejemplo n.º 2
0
static void connect_service(int fd, void* data) {
    char* host = reinterpret_cast<char*>(data);
    std::string response;
    if (!strncmp(host, "emu:", 4)) {
        connect_emulator(host + 4, &response);
    } else {
        connect_device(host, &response);
    }
    free(host);

    // Send response for emulator and device
    SendProtocolString(fd, response);
    adb_close(fd);
}
Ejemplo n.º 3
0
int _adb_connect(const std::string& service, std::string* error) {
    D("_adb_connect: %s", service.c_str());
    if (service.empty() || service.size() > MAX_PAYLOAD_V1) {
        *error = android::base::StringPrintf("bad service name length (%zd)",
                                             service.size());
        return -1;
    }

    int fd;
    std::string reason;
    if (__adb_server_name) {
        fd = network_connect(__adb_server_name, __adb_server_port, SOCK_STREAM, 0, &reason);
        if (fd == -1) {
            *error = android::base::StringPrintf("can't connect to %s:%d: %s",
                                                 __adb_server_name, __adb_server_port,
                                                 reason.c_str());
            return -2;
        }
    } else {
        fd = network_loopback_client(__adb_server_port, SOCK_STREAM, &reason);
        if (fd == -1) {
            *error = android::base::StringPrintf("cannot connect to daemon: %s",
                                                 reason.c_str());
            return -2;
        }
    }

    if ((memcmp(&service[0],"host",4) != 0 || service == "host:reconnect") &&
        switch_socket_transport(fd, error)) {
        return -1;
    }

    if (!SendProtocolString(fd, service)) {
        *error = perror_str("write failure during connection");
        adb_close(fd);
        return -1;
    }

    if (service != "reconnect") {
        if (!adb_status(fd, error)) {
            adb_close(fd);
            return -1;
        }
    }

    D("_adb_connect: return fd %d", fd);
    return fd;
}
Ejemplo n.º 4
0
static int switch_socket_transport(int fd, std::string* error) {
    std::string service;
    if (__adb_transport_id) {
        service += "host:transport-id:";
        service += std::to_string(__adb_transport_id);
    } else if (__adb_serial) {
        service += "host:transport:";
        service += __adb_serial;
    } else {
        const char* transport_type = "???";
        switch (__adb_transport) {
          case kTransportUsb:
            transport_type = "transport-usb";
            break;
          case kTransportLocal:
            transport_type = "transport-local";
            break;
          case kTransportAny:
            transport_type = "transport-any";
            break;
          case kTransportHost:
            // no switch necessary
            return 0;
        }
        service += "host:";
        service += transport_type;
    }

    if (!SendProtocolString(fd, service)) {
        *error = perror_str("write failure during connection");
        adb_close(fd);
        return -1;
    }
    D("Switch transport in progress");

    if (!adb_status(fd, error)) {
        adb_close(fd);
        D("Switch transport failed: %s", error->c_str());
        return -1;
    }
    D("Switch transport success");
    return 0;
}
Ejemplo n.º 5
0
bool adb_kill_server() {
    D("adb_kill_server");
    std::string reason;
    int fd = socket_spec_connect(__adb_server_socket_spec, &reason);
    if (fd < 0) {
        fprintf(stderr, "cannot connect to daemon at %s: %s\n", __adb_server_socket_spec,
                reason.c_str());
        return true;
    }

    if (!SendProtocolString(fd, "host:kill")) {
        fprintf(stderr, "error: write failure during connection: %s\n", strerror(errno));
        return false;
    }

    // The server might send OKAY, so consume that.
    char buf[4];
    ReadFdExactly(fd, buf, 4);
    // Now that no more data is expected, wait for socket orderly shutdown or error, indicating
    // server death.
    ReadOrderlyShutdown(fd);
    return true;
}
Ejemplo n.º 6
0
int _adb_connect(const std::string& service, std::string* error) {
    D("_adb_connect: %s\n", service.c_str());
    if (service.empty() || service.size() > 1024) {
        *error = android::base::StringPrintf("bad service name length (%d)",
                                             static_cast<int>(service.size()));
        return -1;
    }

    int fd;
    if (__adb_server_name) {
        fd = socket_network_client(__adb_server_name, __adb_server_port, SOCK_STREAM);
    } else {
        fd = socket_loopback_client(__adb_server_port, SOCK_STREAM);
    }
    if (fd < 0) {
        *error = perror_str("cannot connect to daemon");
        return -2;
    }

    if (memcmp(&service[0],"host",4) != 0 && switch_socket_transport(fd, error)) {
        return -1;
    }

    if(!SendProtocolString(fd, service)) {
        *error = perror_str("write failure during connection");
        adb_close(fd);
        return -1;
    }

    if (!adb_status(fd, error)) {
        adb_close(fd);
        return -1;
    }

    D("_adb_connect: return fd %d\n", fd);
    return fd;
}
Ejemplo n.º 7
0
int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
{
    if(!strcmp(service, "kill")) {
        fprintf(stderr,"adb server killed by remote request\n");
        fflush(stdout);
        SendOkay(reply_fd);
        usb_cleanup();
        exit(0);
    }

#if ADB_HOST
    atransport *transport = NULL;
    // "transport:" is used for switching transport with a specified serial number
    // "transport-usb:" is used for switching transport to the only USB transport
    // "transport-local:" is used for switching transport to the only local transport
    // "transport-any:" is used for switching transport to the only transport
    if (!strncmp(service, "transport", strlen("transport"))) {
        transport_type type = kTransportAny;

        if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
            type = kTransportUsb;
        } else if (!strncmp(service, "transport-local", strlen("transport-local"))) {
            type = kTransportLocal;
        } else if (!strncmp(service, "transport-any", strlen("transport-any"))) {
            type = kTransportAny;
        } else if (!strncmp(service, "transport:", strlen("transport:"))) {
            service += strlen("transport:");
            serial = service;
        }

        std::string error_msg = "unknown failure";
        transport = acquire_one_transport(CS_ANY, type, serial, &error_msg);

        if (transport) {
            s->transport = transport;
            SendOkay(reply_fd);
        } else {
            SendFail(reply_fd, error_msg);
        }
        return 1;
    }

    // return a list of all connected devices
    if (!strncmp(service, "devices", 7)) {
        bool long_listing = (strcmp(service+7, "-l") == 0);
        if (long_listing || service[7] == 0) {
            D("Getting device list...\n");
            std::string device_list = list_transports(long_listing);
            D("Sending device list...\n");
            SendOkay(reply_fd);
            SendProtocolString(reply_fd, device_list);
            return 0;
        }
        return 1;
    }

    // remove TCP transport
    if (!strncmp(service, "disconnect:", 11)) {
        char buffer[4096];
        memset(buffer, 0, sizeof(buffer));
        char* serial = service + 11;
        if (serial[0] == 0) {
            // disconnect from all TCP devices
            unregister_all_tcp_transports();
        } else {
            char hostbuf[100];
            // assume port 5555 if no port is specified
            if (!strchr(serial, ':')) {
                snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial);
                serial = hostbuf;
            }
            atransport *t = find_transport(serial);

            if (t) {
                unregister_transport(t);
            } else {
                snprintf(buffer, sizeof(buffer), "No such device %s", serial);
            }
        }

        SendOkay(reply_fd);
        SendProtocolString(reply_fd, buffer);
        return 0;
    }

    // returns our value for ADB_SERVER_VERSION
    if (!strcmp(service, "version")) {
        SendOkay(reply_fd);
        SendProtocolString(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION));
        return 0;
    }

    if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {
        const char *out = "unknown";
        transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
        if (transport && transport->serial) {
            out = transport->serial;
        }
        SendOkay(reply_fd);
        SendProtocolString(reply_fd, out);
        return 0;
    }
    if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
        const char *out = "unknown";
        transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
        if (transport && transport->devpath) {
            out = transport->devpath;
        }
        SendOkay(reply_fd);
        SendProtocolString(reply_fd, out);
        return 0;
    }
    // indicates a new emulator instance has started
    if (!strncmp(service,"emulator:",9)) {
        int  port = atoi(service+9);
        local_connect(port);
        /* we don't even need to send a reply */
        return 0;
    }

    if(!strncmp(service,"get-state",strlen("get-state"))) {
        transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
        SendOkay(reply_fd);
        SendProtocolString(reply_fd, transport ? transport->connection_state_name() : "unknown");
        return 0;
    }
#endif // ADB_HOST

    int ret = handle_forward_request(service, ttype, serial, reply_fd);
    if (ret >= 0)
      return ret - 1;
    return -1;
}
Ejemplo n.º 8
0
// Try to handle a network forwarding request.
// This returns 1 on success, 0 on failure, and -1 to indicate this is not
// a forwarding-related request.
int handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd)
{
    if (!strcmp(service, "list-forward")) {
        // Create the list of forward redirections.
        std::string listeners = format_listeners();
#if ADB_HOST
        SendOkay(reply_fd);
#endif
        SendProtocolString(reply_fd, listeners);
        return 1;
    }

    if (!strcmp(service, "killforward-all")) {
        remove_all_listeners();
#if ADB_HOST
        /* On the host: 1st OKAY is connect, 2nd OKAY is status */
        SendOkay(reply_fd);
#endif
        SendOkay(reply_fd);
        return 1;
    }

    if (!strncmp(service, "forward:",8) ||
        !strncmp(service, "killforward:",12)) {
        char *local, *remote;
        atransport *transport;

        int createForward = strncmp(service, "kill", 4);
        int no_rebind = 0;

        local = strchr(service, ':') + 1;

        // Handle forward:norebind:<local>... here
        if (createForward && !strncmp(local, "norebind:", 9)) {
            no_rebind = 1;
            local = strchr(local, ':') + 1;
        }

        remote = strchr(local,';');

        if (createForward) {
            // Check forward: parameter format: '<local>;<remote>'
            if(remote == 0) {
                SendFail(reply_fd, "malformed forward spec");
                return 1;
            }

            *remote++ = 0;
            if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) {
                SendFail(reply_fd, "malformed forward spec");
                return 1;
            }
        } else {
            // Check killforward: parameter format: '<local>'
            if (local[0] == 0) {
                SendFail(reply_fd, "malformed forward spec");
                return 1;
            }
        }

        std::string error_msg;
        transport = acquire_one_transport(CS_ANY, ttype, serial, &error_msg);
        if (!transport) {
            SendFail(reply_fd, error_msg);
            return 1;
        }

        install_status_t r;
        if (createForward) {
            r = install_listener(local, remote, transport, no_rebind);
        } else {
            r = remove_listener(local, transport);
        }
        if (r == INSTALL_STATUS_OK) {
#if ADB_HOST
            /* On the host: 1st OKAY is connect, 2nd OKAY is status */
            SendOkay(reply_fd);
#endif
            SendOkay(reply_fd);
            return 1;
        }

        std::string message;
        switch (r) {
          case INSTALL_STATUS_OK: message = " "; break;
          case INSTALL_STATUS_INTERNAL_ERROR: message = "internal error"; break;
          case INSTALL_STATUS_CANNOT_BIND:
            message = android::base::StringPrintf("cannot bind to socket: %s", strerror(errno));
            break;
          case INSTALL_STATUS_CANNOT_REBIND:
            message = android::base::StringPrintf("cannot rebind existing socket: %s", strerror(errno));
            break;
          case INSTALL_STATUS_LISTENER_NOT_FOUND: message = "listener not found"; break;
        }
        SendFail(reply_fd, message);
        return 1;
    }
    return 0;
}
bool SendFail(int fd, const std::string& reason) {
    return WriteFdExactly(fd, "FAIL", 4) && SendProtocolString(fd, reason);
}
Ejemplo n.º 10
0
// Try to handle a network forwarding request.
// This returns 1 on success, 0 on failure, and -1 to indicate this is not
// a forwarding-related request.
int handle_forward_request(const char* service, TransportType type, const char* serial, int reply_fd)
{
    if (!strcmp(service, "list-forward")) {
        // Create the list of forward redirections.
        std::string listeners = format_listeners();
#if ADB_HOST
        SendOkay(reply_fd);
#endif
        return SendProtocolString(reply_fd, listeners);
    }

    if (!strcmp(service, "killforward-all")) {
        remove_all_listeners();
#if ADB_HOST
        /* On the host: 1st OKAY is connect, 2nd OKAY is status */
        SendOkay(reply_fd);
#endif
        SendOkay(reply_fd);
        return 1;
    }

    if (!strncmp(service, "forward:", 8) || !strncmp(service, "killforward:", 12)) {
        // killforward:local
        // forward:(norebind:)?local;remote
        bool kill_forward = false;
        bool no_rebind = false;
        if (android::base::StartsWith(service, "killforward:")) {
            kill_forward = true;
            service += 12;
        } else {
            service += 8;   // skip past "forward:"
            if (android::base::StartsWith(service, "norebind:")) {
                no_rebind = true;
                service += 9;
            }
        }

        std::vector<std::string> pieces = android::base::Split(service, ";");

        if (kill_forward) {
            // Check killforward: parameter format: '<local>'
            if (pieces.size() != 1 || pieces[0].empty()) {
                SendFail(reply_fd, android::base::StringPrintf("bad killforward: %s", service));
                return 1;
            }
        } else {
            // Check forward: parameter format: '<local>;<remote>'
            if (pieces.size() != 2 || pieces[0].empty() || pieces[1].empty() || pieces[1][0] == '*') {
                SendFail(reply_fd, android::base::StringPrintf("bad forward: %s", service));
                return 1;
            }
        }

        std::string error_msg;
        atransport* transport = acquire_one_transport(type, serial, nullptr, &error_msg);
        if (!transport) {
            SendFail(reply_fd, error_msg);
            return 1;
        }

        std::string error;
        InstallStatus r;
        int resolved_tcp_port = 0;
        if (kill_forward) {
            r = remove_listener(pieces[0].c_str(), transport);
        } else {
            r = install_listener(pieces[0], pieces[1].c_str(), transport, no_rebind,
                                 &resolved_tcp_port, &error);
        }
        if (r == INSTALL_STATUS_OK) {
#if ADB_HOST
            // On the host: 1st OKAY is connect, 2nd OKAY is status.
            SendOkay(reply_fd);
#endif
            SendOkay(reply_fd);

            // If a TCP port was resolved, send the actual port number back.
            if (resolved_tcp_port != 0) {
                SendProtocolString(reply_fd, android::base::StringPrintf("%d", resolved_tcp_port));
            }

            return 1;
        }

        std::string message;
        switch (r) {
          case INSTALL_STATUS_OK: message = "success (!)"; break;
          case INSTALL_STATUS_INTERNAL_ERROR: message = "internal error"; break;
          case INSTALL_STATUS_CANNOT_BIND:
            message = android::base::StringPrintf("cannot bind listener: %s",
                                                  error.c_str());
            break;
          case INSTALL_STATUS_CANNOT_REBIND:
            message = android::base::StringPrintf("cannot rebind existing socket");
            break;
          case INSTALL_STATUS_LISTENER_NOT_FOUND:
            message = android::base::StringPrintf("listener '%s' not found", service);
            break;
        }
        SendFail(reply_fd, message);
        return 1;
    }
    return 0;
}
Ejemplo n.º 11
0
static int SendOkay(int fd, const std::string& s) {
    SendOkay(fd);
    SendProtocolString(fd, s);
    return 0;
}