Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2f38b699 authored by Mike Lockwood's avatar Mike Lockwood
Browse files

adb: Improved support for running adb over TCP/IP



Added new commands:

adb connect <host>:<port> (to connect to a device via TCP/IP)
adb tcpip <port>          (to restart adbd on the device to listen on TCP/IP)
adb usb                   (to restart adbd on the device to listen USB)

Signed-off-by: default avatarMike Lockwood <lockwood@android.com>
parent 26f3de67
Loading
Loading
Loading
Loading
+46 −5
Original line number Diff line number Diff line
@@ -832,6 +832,7 @@ int adb_main(int is_daemon)
{
#if !ADB_HOST
    int secure = 0;
    int port;
    char value[PROPERTY_VALUE_MAX];
#endif

@@ -918,14 +919,17 @@ int adb_main(int is_daemon)
    }

        /* for the device, start the usb transport if the
        ** android usb device exists, otherwise start the
        ** network transport.
        ** android usb device exists and "service.adb.tcp"
        ** is not set, otherwise start the network transport.
        */
    if(access("/dev/android_adb", F_OK) == 0 ||
       access("/dev/android", F_OK) == 0) {
    property_get("service.adb.tcp.port", value, "0");
    if (sscanf(value, "%d", &port) == 0) {
        port = 0;
    }
    if (port == 0 && access("/dev/android_adb", F_OK) == 0) {
        usb_init();
    } else {
        local_init();
        local_init(port);
    }
    init_jdwp();
#endif
@@ -1006,6 +1010,43 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
        return 0;
    }

    // add a new TCP transport
    if (!strncmp(service, "connect:", 8)) {
        char buffer[4096];
        int port, fd;
        char* host = service + 8;
        char* portstr = strchr(host, ':');

        if (!portstr) {
            snprintf(buffer, sizeof(buffer), "unable to parse %s as <host>:<port>\n", host);
            goto done;
        }
        // zero terminate host by overwriting the ':'
        *portstr++ = 0;
        if (sscanf(portstr, "%d", &port) == 0) {
            snprintf(buffer, sizeof(buffer), "bad port number %s\n", portstr);
            goto done;
        }

        fd = socket_network_client(host, port, SOCK_STREAM);
        if (fd < 0) {
            snprintf(buffer, sizeof(buffer), "unable to connect to %s:%d\n", host, port);
            goto done;
        }

        D("client: connected on remote on fd %d\n", fd);
        close_on_exec(fd);
        disable_tcp_nagle(fd);
        snprintf(buf, sizeof buf, "%s:%d", host, port);
        register_socket_transport(fd, buf, port, 0);
        snprintf(buffer, sizeof(buffer), "connected to %s:%d\n", host, port);

done:
        snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer);
        writex(reply_fd, buf, strlen(buf));
        return 0;
    }

    // returns our value for ADB_SERVER_VERSION
    if (!strcmp(service, "version")) {
        char version[12];
+3 −3
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@
#define ADB_VERSION_MAJOR 1         // Used for help/version information
#define ADB_VERSION_MINOR 0         // Used for help/version information

#define ADB_SERVER_VERSION    23    // Increment this when we want to force users to start a new adb server
#define ADB_SERVER_VERSION    24    // Increment this when we want to force users to start a new adb server

typedef struct amessage amessage;
typedef struct apacket apacket;
@@ -262,14 +262,14 @@ void run_transport_disconnects( atransport* t );
void   kick_transport( atransport*  t );

/* initialize a transport object's func pointers and state */
int  init_socket_transport(atransport *t, int s, int port);
int  init_socket_transport(atransport *t, int s, int port, int local);
void init_usb_transport(atransport *t, usb_handle *usb, int state);

/* for MacOS X cleanup */
void close_usb_devices();

/* cause new transports to be init'd and added to the list */
void register_socket_transport(int s, const char *serial, int  port);
void register_socket_transport(int s, const char *serial, int port, int local);
void register_usb_transport(usb_handle *h, const char *serial, unsigned writeable);

/* this should only be used for transports with connection_state == CS_NOPERM */
+27 −28
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@ void help()
        "                                 environment variable is used, which must\n"
        "                                 be an absolute path.\n"
        " devices                       - list all connected devices\n"
        " connect <host>:<port>         - connect to a device via TCP/IP"
        "\n"
        "device commands:\n"
        "  adb push <local> <remote>    - copy file/dir to device\n"
@@ -149,7 +150,9 @@ void help()
        "  adb status-window            - continuously print device status for a specified device\n"
        "  adb remount                  - remounts the /system partition on the device read-write\n"
        "  adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n"
        "  adb root                     - restarts adb with root permissions\n"
        "  adb root                     - restarts the adbd daemon with root permissions\n"
        "  adb usb                      - restarts the adbd daemon listening on USB"
        "  adb tcpip <port>             - restarts the adbd daemon listening on TCP on the specified port"
        "\n"
        "networking:\n"
        "  adb ppp <tty> [parameters]   - Run PPP over USB.\n"
@@ -850,6 +853,22 @@ top:
        }
    }

    if(!strcmp(argv[0], "connect")) {
        char *tmp;
        if (argc != 2) {
            fprintf(stderr, "Usage: adb connect <host>:<port>\n");
            return 1;
        }
        snprintf(buf, sizeof buf, "host:%s:%s", argv[0], argv[1]);
        tmp = adb_query(buf);
        if(tmp) {
            printf("%s\n", tmp);
            return 0;
        } else {
            return 1;
        }
    }

    if (!strcmp(argv[0], "emu")) {
        return adb_send_emulator_command(argc, argv);
    }
@@ -908,35 +927,15 @@ top:
        return 0;
    }

    if(!strcmp(argv[0], "remount")) {
        int fd = adb_connect("remount:");
        if(fd >= 0) {
            read_and_dump(fd);
            adb_close(fd);
            return 0;
        }
        fprintf(stderr,"error: %s\n", adb_error());
        return 1;
    }

    if(!strcmp(argv[0], "reboot")) {
        int fd;
    if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot")
            || !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb")
            || !strcmp(argv[0], "reboot")) {
        char command[100];
        if (argc > 1)
            snprintf(buf, sizeof(buf), "reboot:%s", argv[1]);
            snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);
        else
            snprintf(buf, sizeof(buf), "reboot:");
        fd = adb_connect(buf);
        if(fd >= 0) {
            read_and_dump(fd);
            adb_close(fd);
            return 0;
        }
        fprintf(stderr,"error: %s\n", adb_error());
        return 1;
    }

    if(!strcmp(argv[0], "root")) {
        int fd = adb_connect("root:");
            snprintf(command, sizeof(command), "%s:", argv[0]);
        int fd = adb_connect(command);
        if(fd >= 0) {
            read_and_dump(fd);
            adb_close(fd);
+52 −4
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ void restart_root_service(int fd, void *cookie)
        if (strcmp(value, "1") != 0) {
            snprintf(buf, sizeof(buf), "adbd cannot run as root in production builds\n");
            writex(fd, buf, strlen(buf));
            adb_close(fd);
            return;
        }

@@ -134,13 +135,52 @@ void restart_root_service(int fd, void *cookie)
    }
}

void reboot_service(int fd, char *arg)
void restart_tcp_service(int fd, void *cookie)
{
    char buf[100];
    char value[PROPERTY_VALUE_MAX];
    int port = (int)cookie;

    if (port <= 0) {
        snprintf(buf, sizeof(buf), "invalid port\n");
        writex(fd, buf, strlen(buf));
        adb_close(fd);
        return;
    }

    snprintf(value, sizeof(value), "%d", port);
    property_set("service.adb.tcp.port", value);
    snprintf(buf, sizeof(buf), "restarting in TCP mode port: %d\n", port);
    writex(fd, buf, strlen(buf));
    adb_close(fd);

    // quit, and init will restart us in TCP mode
    sleep(1);
    exit(1);
}

void restart_usb_service(int fd, void *cookie)
{
    char buf[100];

    property_set("service.adb.tcp.port", "0");
    snprintf(buf, sizeof(buf), "restarting in USB mode\n");
    writex(fd, buf, strlen(buf));
    adb_close(fd);

    // quit, and init will restart us in USB mode
    sleep(1);
    exit(1);
}

void reboot_service(int fd, void *arg)
{
    char buf[100];
    int ret;

    sync();
    ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, arg);
    ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
                    LINUX_REBOOT_CMD_RESTART2, (char *)arg);
    if (ret < 0) {
        snprintf(buf, sizeof(buf), "reboot failed: %s\n", strerror(errno));
        writex(fd, buf, strlen(buf));
@@ -415,12 +455,20 @@ int service_to_fd(const char *name)
    } else if(!strncmp(name, "remount:", 8)) {
        ret = create_service_thread(remount_service, NULL);
    } else if(!strncmp(name, "reboot:", 7)) {
        char* arg = name + 7;
        const char* arg = name + 7;
        if (*name == 0)
            arg = NULL;
        ret = create_service_thread(reboot_service, arg);
        ret = create_service_thread(reboot_service, (void *)arg);
    } else if(!strncmp(name, "root:", 5)) {
        ret = create_service_thread(restart_root_service, NULL);
    } else if(!strncmp(name, "tcpip:", 6)) {
        int port;
        if (sscanf(name + 6, "%d", &port) == 0) {
            port = 0;
        }
        ret = create_service_thread(restart_tcp_service, (void *)port);
    } else if(!strncmp(name, "usb:", 4)) {
        ret = create_service_thread(restart_usb_service, NULL);
#endif
#if 0
    } else if(!strncmp(name, "echo:", 5)){
+2 −2
Original line number Diff line number Diff line
@@ -849,11 +849,11 @@ void close_usb_devices()
}
#endif // ADB_HOST

void register_socket_transport(int s, const char *serial, int  port)
void register_socket_transport(int s, const char *serial, int port, int local)
{
    atransport *t = calloc(1, sizeof(atransport));
    D("transport: %p init'ing for socket %d, on port %d\n", t, s, port);
    if ( init_socket_transport(t, s, port) < 0 ) {
    if ( init_socket_transport(t, s, port, local) < 0 ) {
        adb_close(s);
        free(t);
        return;
Loading