Example #1
0
void reverse_service(int fd, void* arg)
{
    const char* command = arg;

    if (handle_forward_request(command, kTransportAny, NULL, fd) < 0) {
        sendfailmsg(fd, "not a reverse forwarding command");
    }
    free(arg);
    adb_close(fd);
}
void reverse_service(int fd, void* arg)
{
    const char* command = reinterpret_cast<const char*>(arg);

    if (handle_forward_request(command, kTransportAny, NULL, fd) < 0) {
        SendFail(fd, "not a reverse forwarding command");
    }
    free(arg);
    adb_close(fd);
}
Example #3
0
int reverse_service(const char* command) {
    int s[2];
    if (adb_socketpair(s)) {
        PLOG(ERROR) << "cannot create service socket pair.";
        return -1;
    }
    VLOG(SERVICES) << "service socketpair: " << s[0] << ", " << s[1];
    if (handle_forward_request(command, kTransportAny, nullptr, s[1]) < 0) {
        SendFail(s[1], "not a reverse forwarding command");
    }
    adb_close(s[1]);
    return s[0];
}
Example #4
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;
}
Example #5
0
int handle_host_request(const char* service, TransportType type,
                        const char* serial, int reply_fd, asocket* s) {
    if (strcmp(service, "kill") == 0) {
        fprintf(stderr, "adb server killed by remote request\n");
        fflush(stdout);
        SendOkay(reply_fd);

        // On Windows, if the process exits with open sockets that
        // shutdown(SD_SEND) has not been called on, TCP RST segments will be
        // sent to the peers which will cause their next recv() to error-out
        // with WSAECONNRESET. In the case of this code, that means the client
        // may not read the OKAY sent above.
        adb_shutdown(reply_fd);

        exit(0);
    }

#if ADB_HOST
    // "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"))) {
        TransportType 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;
        atransport* t = acquire_one_transport(type, serial, nullptr, &error);
        if (t != nullptr) {
            s->transport = t;
            SendOkay(reply_fd);
        } else {
            SendFail(reply_fd, error);
        }
        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...");
            std::string device_list = list_transports(long_listing);
            D("Sending device list...");
            return SendOkay(reply_fd, device_list);
        }
        return 1;
    }

    if (!strcmp(service, "features")) {
        std::string error;
        atransport* t = acquire_one_transport(type, serial, nullptr, &error);
        if (t != nullptr) {
            SendOkay(reply_fd, FeatureSetToString(t->features()));
        } else {
            SendFail(reply_fd, error);
        }
        return 0;
    }

    // remove TCP transport
    if (!strncmp(service, "disconnect:", 11)) {
        const std::string address(service + 11);
        if (address.empty()) {
            kick_all_tcp_devices();
            return SendOkay(reply_fd, "disconnected everything");
        }

        std::string serial;
        std::string host;
        int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
        std::string error;
        if (!android::base::ParseNetAddress(address, &host, &port, &serial, &error)) {
            return SendFail(reply_fd, android::base::StringPrintf("couldn't parse '%s': %s",
                                                                  address.c_str(), error.c_str()));
        }
        atransport* t = find_transport(serial.c_str());
        if (t == nullptr) {
            return SendFail(reply_fd, android::base::StringPrintf("no such device '%s'",
                                                                  serial.c_str()));
        }
        kick_transport(t);
        return SendOkay(reply_fd, android::base::StringPrintf("disconnected %s", address.c_str()));
    }

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

    // These always report "unknown" rather than the actual error, for scripts.
    if (!strcmp(service, "get-serialno")) {
        std::string error;
        atransport* t = acquire_one_transport(type, serial, nullptr, &error);
        if (t) {
            return SendOkay(reply_fd, t->serial ? t->serial : "unknown");
        } else {
            return SendFail(reply_fd, error);
        }
    }
    if (!strcmp(service, "get-devpath")) {
        std::string error;
        atransport* t = acquire_one_transport(type, serial, nullptr, &error);
        if (t) {
            return SendOkay(reply_fd, t->devpath ? t->devpath : "unknown");
        } else {
            return SendFail(reply_fd, error);
        }
    }
    if (!strcmp(service, "get-state")) {
        std::string error;
        atransport* t = acquire_one_transport(type, serial, nullptr, &error);
        if (t) {
            return SendOkay(reply_fd, t->connection_state_name());
        } else {
            return SendFail(reply_fd, error);
        }
    }

    // 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 (!strcmp(service, "reconnect")) {
        if (s->transport != nullptr) {
            kick_transport(s->transport);
        }
        return SendOkay(reply_fd, "done");
    }
#endif // ADB_HOST

    int ret = handle_forward_request(service, type, serial, reply_fd);
    if (ret >= 0)
      return ret - 1;
    return -1;
}
Example #6
0
int handle_host_request(const char* service, TransportType type,
                        const char* serial, int reply_fd, asocket* s) {
    if (strcmp(service, "kill") == 0) {
        fprintf(stderr, "adb server killed by remote request\n");
        fflush(stdout);
        SendOkay(reply_fd);
        exit(0);
    }

#if ADB_HOST
    // "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"))) {
        TransportType 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;
        atransport* t = acquire_one_transport(kCsAny, type, serial, &error_msg);
        if (t != nullptr) {
            s->transport = t;
            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");
            return SendOkay(reply_fd, device_list);
        }
        return 1;
    }

    // remove TCP transport
    if (!strncmp(service, "disconnect:", 11)) {
        const std::string address(service + 11);
        if (address.empty()) {
            // disconnect from all TCP devices
            unregister_all_tcp_transports();
            return SendOkay(reply_fd, "disconnected everything");
        }

        std::string serial;
        std::string host;
        int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
        std::string error;
        if (!parse_host_and_port(address, &serial, &host, &port, &error)) {
            return SendFail(reply_fd, android::base::StringPrintf("couldn't parse '%s': %s",
                            address.c_str(), error.c_str()));
        }
        atransport* t = find_transport(serial.c_str());
        if (t == nullptr) {
            return SendFail(reply_fd, android::base::StringPrintf("no such device '%s'",
                            serial.c_str()));
        }
        unregister_transport(t);
        return SendOkay(reply_fd, android::base::StringPrintf("disconnected %s", address.c_str()));
    }

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

    // These always report "unknown" rather than the actual error, for scripts.
    if (!strcmp(service, "get-serialno")) {
        std::string ignored;
        atransport* t = acquire_one_transport(kCsAny, type, serial, &ignored);
        return SendOkay(reply_fd, (t && t->serial) ? t->serial : "unknown");
    }
    if (!strcmp(service, "get-devpath")) {
        std::string ignored;
        atransport* t = acquire_one_transport(kCsAny, type, serial, &ignored);
        return SendOkay(reply_fd, (t && t->devpath) ? t->devpath : "unknown");
    }
    if (!strcmp(service, "get-state")) {
        std::string ignored;
        atransport* t = acquire_one_transport(kCsAny, type, serial, &ignored);
        return SendOkay(reply_fd, t ? t->connection_state_name() : "unknown");
    }

    // 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;
    }
#endif // ADB_HOST

    int ret = handle_forward_request(service, type, serial, reply_fd);
    if (ret >= 0)
        return ret - 1;
    return -1;
}
Example #7
0
int handle_host_request(const char* service, TransportType type,
                        const char* serial, int reply_fd, asocket* s) {
    if (strcmp(service, "kill") == 0) {
        fprintf(stderr, "adb server killed by remote request\n");
        fflush(stdout);
        SendOkay(reply_fd);

        // At least on Windows, if we exit() without shutdown(SD_SEND) or
        // closesocket(), the client's next recv() will error-out with
        // WSAECONNRESET and they'll never read the OKAY.
        adb_shutdown(reply_fd);

        exit(0);
    }

#if ADB_HOST
    // "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"))) {
        TransportType 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;
        atransport* t = acquire_one_transport(kCsAny, type, serial, &error_msg);
        if (t != nullptr) {
            s->transport = t;
            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...");
            std::string device_list = list_transports(long_listing);
            D("Sending device list...");
            return SendOkay(reply_fd, device_list);
        }
        return 1;
    }

    if (!strcmp(service, "features")) {
        std::string error_msg;
        atransport* t = acquire_one_transport(kCsAny, type, serial, &error_msg);
        if (t != nullptr) {
            SendOkay(reply_fd, android::base::Join(t->features(), '\n'));
        } else {
            SendFail(reply_fd, error_msg);
        }
        return 0;
    }

    if (!strncmp(service, "check-feature:", strlen("check-feature:"))) {
        std::string error_msg;
        atransport* t = acquire_one_transport(kCsAny, type, serial, &error_msg);
        if (t && t->CanUseFeature(service + strlen("check-feature:"))) {
            // We could potentially extend this to reply with the feature
            // version if that becomes necessary.
            SendOkay(reply_fd, "1");
        } else {
            // Empty response means unsupported feature.
            SendOkay(reply_fd, "");
        }
        return 0;
    }

    // remove TCP transport
    if (!strncmp(service, "disconnect:", 11)) {
        const std::string address(service + 11);
        if (address.empty()) {
            kick_all_tcp_devices();
            return SendOkay(reply_fd, "disconnected everything");
        }

        std::string serial;
        std::string host;
        int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
        std::string error;
        if (!parse_host_and_port(address, &serial, &host, &port, &error)) {
            return SendFail(reply_fd, android::base::StringPrintf("couldn't parse '%s': %s",
                                                                  address.c_str(), error.c_str()));
        }
        atransport* t = find_transport(serial.c_str());
        if (t == nullptr) {
            return SendFail(reply_fd, android::base::StringPrintf("no such device '%s'",
                                                                  serial.c_str()));
        }
        kick_transport(t);
        return SendOkay(reply_fd, android::base::StringPrintf("disconnected %s", address.c_str()));
    }

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

    // These always report "unknown" rather than the actual error, for scripts.
    if (!strcmp(service, "get-serialno")) {
        std::string ignored;
        atransport* t = acquire_one_transport(kCsAny, type, serial, &ignored);
        return SendOkay(reply_fd, (t && t->serial) ? t->serial : "unknown");
    }
    if (!strcmp(service, "get-devpath")) {
        std::string ignored;
        atransport* t = acquire_one_transport(kCsAny, type, serial, &ignored);
        return SendOkay(reply_fd, (t && t->devpath) ? t->devpath : "unknown");
    }
    if (!strcmp(service, "get-state")) {
        std::string ignored;
        atransport* t = acquire_one_transport(kCsAny, type, serial, &ignored);
        return SendOkay(reply_fd, t ? t->connection_state_name() : "unknown");
    }

    // 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;
    }
#endif // ADB_HOST

    int ret = handle_forward_request(service, type, serial, reply_fd);
    if (ret >= 0)
      return ret - 1;
    return -1;
}