diff options
author | Mike Lockwood <lockwood@android.com> | 2009-08-24 15:58:40 -0700 |
---|---|---|
committer | Mike Lockwood <lockwood@android.com> | 2009-08-24 16:05:58 -0700 |
commit | ff19670d485fd5ee296e23b00b035ac22975c647 (patch) | |
tree | 7cb4b5a7f34903440f2d07aea1ba78110332c244 /adb | |
parent | 90b06ac786f859895ac503cf42759c2706205700 (diff) | |
download | system_core-ff19670d485fd5ee296e23b00b035ac22975c647.zip system_core-ff19670d485fd5ee296e23b00b035ac22975c647.tar.gz system_core-ff19670d485fd5ee296e23b00b035ac22975c647.tar.bz2 |
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: Mike Lockwood <lockwood@android.com>
Diffstat (limited to 'adb')
-rw-r--r-- | adb/adb.c | 51 | ||||
-rw-r--r-- | adb/adb.h | 6 | ||||
-rw-r--r-- | adb/commandline.c | 55 | ||||
-rw-r--r-- | adb/services.c | 56 | ||||
-rw-r--r-- | adb/transport.c | 4 | ||||
-rw-r--r-- | adb/transport_local.c | 19 |
6 files changed, 140 insertions, 51 deletions
@@ -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]; @@ -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 */ diff --git a/adb/commandline.c b/adb/commandline.c index 4ec5c8b..5d3187a 100644 --- a/adb/commandline.c +++ b/adb/commandline.c @@ -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); diff --git a/adb/services.c b/adb/services.c index 517da55..2864ac9 100644 --- a/adb/services.c +++ b/adb/services.c @@ -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)){ diff --git a/adb/transport.c b/adb/transport.c index c9e7752..617dabf 100644 --- a/adb/transport.c +++ b/adb/transport.c @@ -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; diff --git a/adb/transport_local.c b/adb/transport_local.c index be01f29..c528d1f 100644 --- a/adb/transport_local.c +++ b/adb/transport_local.c @@ -122,7 +122,7 @@ int local_connect(int port) close_on_exec(fd); disable_tcp_nagle(fd); snprintf(buf, sizeof buf, "%s%d", LOCAL_CLIENT_PREFIX, port - 1); - register_socket_transport(fd, buf, port); + register_socket_transport(fd, buf, port, 1); return 0; } return -1; @@ -147,17 +147,18 @@ static void *client_socket_thread(void *x) return 0; } -static void *server_socket_thread(void *x) +static void *server_socket_thread(void * arg) { int serverfd, fd; struct sockaddr addr; socklen_t alen; + int port = (int)arg; D("transport: server_socket_thread() starting\n"); serverfd = -1; for(;;) { if(serverfd == -1) { - serverfd = socket_inaddr_any_server(ADB_LOCAL_TRANSPORT_PORT, SOCK_STREAM); + serverfd = socket_inaddr_any_server(port, SOCK_STREAM); if(serverfd < 0) { D("server: cannot bind socket yet\n"); adb_sleep_ms(1000); @@ -167,20 +168,20 @@ static void *server_socket_thread(void *x) } alen = sizeof(addr); - D("server: trying to get new connection from %d\n", ADB_LOCAL_TRANSPORT_PORT); + D("server: trying to get new connection from %d\n", port); fd = adb_socket_accept(serverfd, &addr, &alen); if(fd >= 0) { D("server: new connection on fd %d\n", fd); close_on_exec(fd); disable_tcp_nagle(fd); - register_socket_transport(fd,"host",ADB_LOCAL_TRANSPORT_PORT); + register_socket_transport(fd, "host", port, 1); } } D("transport: server_socket_thread() exiting\n"); return 0; } -void local_init(void) +void local_init(int port) { adb_thread_t thr; void* (*func)(void *); @@ -193,7 +194,7 @@ void local_init(void) D("transport: local %s init\n", HOST ? "client" : "server"); - if(adb_thread_create(&thr, func, 0)) { + if(adb_thread_create(&thr, func, (void *)port)) { fatal_errno("cannot create local socket %s thread", HOST ? "client" : "server"); } @@ -225,7 +226,7 @@ static void remote_close(atransport *t) adb_close(t->fd); } -int init_socket_transport(atransport *t, int s, int port) +int init_socket_transport(atransport *t, int s, int port, int local) { int fail = 0; @@ -239,7 +240,7 @@ int init_socket_transport(atransport *t, int s, int port) t->type = kTransportLocal; #if ADB_HOST - if (HOST) { + if (HOST && local) { adb_mutex_lock( &local_transports_lock ); { int index = (port - ADB_LOCAL_TRANSPORT_PORT)/2; |