summaryrefslogtreecommitdiffstats
path: root/adb
diff options
context:
space:
mode:
authorScott Anderson <saa@android.com>2012-04-20 11:21:14 -0700
committerScott Anderson <saa@android.com>2012-04-20 11:21:14 -0700
commite109d266c12c5f537d429ca4b892f2719e02c2da (patch)
tree61222590bc0f380f6c46bf922db48772e04ab3a1 /adb
parent5383476727659544875b90d49a5371886a31c1fe (diff)
downloadsystem_core-e109d266c12c5f537d429ca4b892f2719e02c2da.zip
system_core-e109d266c12c5f537d429ca4b892f2719e02c2da.tar.gz
system_core-e109d266c12c5f537d429ca4b892f2719e02c2da.tar.bz2
adb: Add ability to specify device path
For manufacturing and testing, there is a need to talk to whatever device is connected to a given port on the host. This change modifies adb's "-s" option to take either a serial number or a device path. The device paths of the connected devices can be listed using "adb devices -l" whose output will resemble: List of devices attached 016B75D60A00600D usb:2-5 device 3031D0B2E71D00EC usb:1-4.3 device The second column lists the device paths. If the -l option is not given, the output from "adb devices" will be the same as it used to be (i.e. the paths will not be printed). The device path can also be obtained with the get-devpath command: $adb -s 3031D0B2E71D00EC get-devpath usb:1-4.3 Note that the format of the device paths are platform dependent. The example above is from Linux. On OS-X, the paths will be "usb:" followed by hex digits. For other platforms, the device paths will be printed as "????????????" and the -s option will not be able to select a device until someone implements the underlying functionality. Change-Id: I057d5d9f8c5bb72eddf5b8088aae110763f809d7 Signed-off-by: Scott Anderson <saa@android.com>
Diffstat (limited to 'adb')
-rw-r--r--adb/SERVICES.TXT7
-rw-r--r--adb/adb.c31
-rw-r--r--adb/adb.h5
-rw-r--r--adb/commandline.c22
-rw-r--r--adb/transport.c26
-rw-r--r--adb/usb_libusb.c2
-rw-r--r--adb/usb_linux.c35
-rw-r--r--adb/usb_linux_client.c2
-rw-r--r--adb/usb_osx.c10
-rw-r--r--adb/usb_windows.c2
10 files changed, 112 insertions, 30 deletions
diff --git a/adb/SERVICES.TXT b/adb/SERVICES.TXT
index be4d50b..d9aa09c 100644
--- a/adb/SERVICES.TXT
+++ b/adb/SERVICES.TXT
@@ -17,8 +17,10 @@ host:kill
upgrade.
host:devices
+host:devices-l
Ask to return the list of available Android devices and their
- state. After the OKAY, this is followed by a 4-byte hex len,
+ state. devices-l includes the device paths in the state.
+ After the OKAY, this is followed by a 4-byte hex len,
and a string that will be dumped as-is by the client, then
the connection is closed
@@ -88,6 +90,9 @@ host:<request>
Returns the serial number of the corresponding device/emulator.
Note that emulator serial numbers are of the form "emulator-5554"
+<host-prefix>:get-devpath
+ Returns the device path of the corresponding device/emulator.
+
<host-prefix>:get-state
Returns the state of a given device as a string.
diff --git a/adb/adb.c b/adb/adb.c
index e7a28d2..92ef97c 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -1132,16 +1132,19 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
}
// return a list of all connected devices
- if (!strcmp(service, "devices")) {
+ if (!strncmp(service, "devices", 7)) {
char buffer[4096];
- memset(buf, 0, sizeof(buf));
- memset(buffer, 0, sizeof(buffer));
- D("Getting device list \n");
- list_transports(buffer, sizeof(buffer));
- snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer);
- D("Wrote device list \n");
- writex(reply_fd, buf, strlen(buf));
- return 0;
+ int use_long = !strcmp(service+7, "-l");
+ if (use_long || service[7] == 0) {
+ memset(buf, 0, sizeof(buf));
+ memset(buffer, 0, sizeof(buffer));
+ D("Getting device list \n");
+ list_transports(buffer, sizeof(buffer), use_long);
+ snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer);
+ D("Wrote device list \n");
+ writex(reply_fd, buf, strlen(buf));
+ return 0;
+ }
}
// add a new TCP transport, device or emulator
@@ -1207,6 +1210,16 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
writex(reply_fd, buf, strlen(buf));
return 0;
}
+ if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
+ char *out = "unknown";
+ transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
+ if (transport && transport->devpath) {
+ out = transport->devpath;
+ }
+ snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out);
+ writex(reply_fd, buf, strlen(buf));
+ return 0;
+ }
// indicates a new emulator instance has started
if (!strncmp(service,"emulator:",9)) {
int port = atoi(service+9);
diff --git a/adb/adb.h b/adb/adb.h
index ac31f11..b99d7ac 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -185,6 +185,7 @@ struct atransport
/* used to identify transports for clients */
char *serial;
char *product;
+ char *devpath;
int adb_port; // Use for emulators (local transport)
/* a list of adisconnect callbacks called when the transport is kicked */
@@ -248,7 +249,7 @@ int adb_main(int is_daemon, int server_port);
** get_device_transport does an acquire on your behalf before returning
*/
void init_transport_registration(void);
-int list_transports(char *buf, size_t bufsize);
+int list_transports(char *buf, size_t bufsize, int show_devpath);
void update_transports(void);
asocket* create_device_tracker(void);
@@ -281,7 +282,7 @@ void register_socket_transport(int s, const char *serial, int port, int local);
void unregister_transport(atransport *t);
void unregister_all_tcp_transports();
-void register_usb_transport(usb_handle *h, const char *serial, unsigned writeable);
+void register_usb_transport(usb_handle *h, const char *serial, const char *devpath, unsigned writeable);
/* this should only be used for transports with connection_state == CS_NOPERM */
void unregister_usb_transport(usb_handle *usb);
diff --git a/adb/commandline.c b/adb/commandline.c
index ffc120f..2de0516 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -84,8 +84,8 @@ void help()
" returns an error if more than one USB device is present.\n"
" -e - directs command to the only running emulator.\n"
" returns an error if more than one emulator is running.\n"
- " -s <serial number> - directs command to the USB device or emulator with\n"
- " the given serial number. Overrides ANDROID_SERIAL\n"
+ " -s <specific device> - directs command to the device or emulator with the given\n"
+ " serial number or device path. Overrides ANDROID_SERIAL\n"
" environment variable.\n"
" -p <product name or path> - simple product name like 'sooner', or\n"
" a relative/absolute path to a product\n"
@@ -93,7 +93,8 @@ void help()
" If -p is not specified, the ANDROID_PRODUCT_OUT\n"
" environment variable is used, which must\n"
" be an absolute path.\n"
- " devices - list all connected devices\n"
+ " devices [-l] - list all connected devices\n"
+ " ('-l' means list device paths)\n"
" connect <host>[:<port>] - connect to a device via TCP/IP\n"
" Port 5555 is used by default if no port number is specified.\n"
" disconnect [<host>[:<port>]] - disconnect from a TCP/IP device.\n"
@@ -157,6 +158,7 @@ void help()
" adb kill-server - kill the server if it is running\n"
" adb get-state - prints: offline | bootloader | device\n"
" adb get-serialno - prints: <serial-number>\n"
+ " adb get-devpath - prints: <device-path>\n"
" 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"
@@ -931,7 +933,16 @@ top:
if(!strcmp(argv[0], "devices")) {
char *tmp;
- snprintf(buf, sizeof buf, "host:%s", argv[0]);
+ char *listopt;
+ if (argc < 2)
+ listopt = "";
+ else if (argc == 2 && !strcmp(argv[1], "-l"))
+ listopt = argv[1];
+ else {
+ fprintf(stderr, "Usage: adb devices [-l]\n");
+ return 1;
+ }
+ snprintf(buf, sizeof buf, "host:%s%s", argv[0], listopt);
tmp = adb_query(buf);
if(tmp) {
printf("List of devices attached \n");
@@ -1204,7 +1215,8 @@ top:
/* passthrough commands */
if(!strcmp(argv[0],"get-state") ||
- !strcmp(argv[0],"get-serialno"))
+ !strcmp(argv[0],"get-serialno") ||
+ !strcmp(argv[0],"get-devpath"))
{
char *tmp;
diff --git a/adb/transport.c b/adb/transport.c
index 83a349a..70fc58e 100644
--- a/adb/transport.c
+++ b/adb/transport.c
@@ -370,7 +370,7 @@ static int list_transports_msg(char* buffer, size_t bufferlen)
char head[5];
int len;
- len = list_transports(buffer+4, bufferlen-4);
+ len = list_transports(buffer+4, bufferlen-4, 0);
snprintf(head, sizeof(head), "%04x", len);
memcpy(buffer, head, 4);
len += 4;
@@ -601,6 +601,8 @@ static void transport_registration_func(int _fd, unsigned ev, void *data)
free(t->product);
if (t->serial)
free(t->serial);
+ if (t->devpath)
+ free(t->devpath);
memset(t,0xee,sizeof(atransport));
free(t);
@@ -762,6 +764,10 @@ retry:
result = t;
break;
}
+ if (t->devpath && !strcmp(serial, t->devpath)) {
+ result = t;
+ break;
+ }
} else {
if (ttype == kTransportUsb && t->type == kTransportUsb) {
if (result) {
@@ -836,7 +842,7 @@ static const char *statename(atransport *t)
}
}
-int list_transports(char *buf, size_t bufsize)
+int list_transports(char *buf, size_t bufsize, int show_devpath)
{
char* p = buf;
char* end = buf + bufsize;
@@ -849,7 +855,13 @@ int list_transports(char *buf, size_t bufsize)
const char* serial = t->serial;
if (!serial || !serial[0])
serial = "????????????";
- len = snprintf(p, end - p, "%s\t%s\n", serial, statename(t));
+ if (show_devpath) {
+ const char* devpath = t->devpath;
+ if (!devpath || !devpath[0])
+ devpath = "????????????";
+ len = snprintf(p, end - p, "%s\t%s\t%s\n", serial, devpath, statename(t));
+ } else
+ len = snprintf(p, end - p, "%s\t%s\n", serial, statename(t));
if (p + len >= end) {
/* discard last line if buffer is too short */
@@ -910,6 +922,9 @@ atransport *find_transport(const char *serial)
if (t->serial && !strcmp(serial, t->serial)) {
break;
}
+ if (t->devpath && !strcmp(serial, t->devpath)) {
+ break;
+ }
}
adb_mutex_unlock(&transport_lock);
@@ -955,7 +970,7 @@ void unregister_all_tcp_transports()
#endif
-void register_usb_transport(usb_handle *usb, const char *serial, unsigned writeable)
+void register_usb_transport(usb_handle *usb, const char *serial, const char *devpath, unsigned writeable)
{
atransport *t = calloc(1, sizeof(atransport));
D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb,
@@ -964,6 +979,9 @@ void register_usb_transport(usb_handle *usb, const char *serial, unsigned writea
if(serial) {
t->serial = strdup(serial);
}
+ if(devpath) {
+ t->devpath = strdup(devpath);
+ }
register_transport(t);
}
diff --git a/adb/usb_libusb.c b/adb/usb_libusb.c
index 8c75266..06ff5dc 100644
--- a/adb/usb_libusb.c
+++ b/adb/usb_libusb.c
@@ -347,7 +347,7 @@ register_device(struct usb_handle *uh, const char *serial)
adb_mutex_unlock(&usb_lock);
- register_usb_transport(usb, serial, 1);
+ register_usb_transport(usb, serial, NULL, 1);
return (1);
}
diff --git a/adb/usb_linux.c b/adb/usb_linux.c
index 4d55b74..7bf2057 100644
--- a/adb/usb_linux.c
+++ b/adb/usb_linux.c
@@ -116,7 +116,8 @@ static void kick_disconnected_devices()
}
-static void register_device(const char *dev_name, unsigned char ep_in, unsigned char ep_out,
+static void register_device(const char *dev_name, const char *devpath,
+ unsigned char ep_in, unsigned char ep_out,
int ifc, int serial_index, unsigned zero_mask);
static inline int badname(const char *name)
@@ -129,7 +130,7 @@ static inline int badname(const char *name)
static void find_usb_device(const char *base,
void (*register_device_callback)
- (const char *, unsigned char, unsigned char, int, int, unsigned))
+ (const char *, const char *, unsigned char, unsigned char, int, int, unsigned))
{
char busname[32], devname[32];
unsigned char local_ep_in, local_ep_out;
@@ -227,6 +228,11 @@ static void find_usb_device(const char *base,
is_adb_interface(vid, pid, interface->bInterfaceClass,
interface->bInterfaceSubClass, interface->bInterfaceProtocol)) {
+ struct stat st;
+ char pathbuf[128];
+ char link[256];
+ char *devpath = NULL;
+
DBGX("looking for bulk endpoints\n");
// looks like ADB...
ep1 = (struct usb_endpoint_descriptor *)bufptr;
@@ -263,7 +269,26 @@ static void find_usb_device(const char *base,
local_ep_out = ep1->bEndpointAddress;
}
- register_device_callback(devname, local_ep_in, local_ep_out,
+ // Determine the device path
+ if (!fstat(fd, &st) && S_ISCHR(st.st_mode)) {
+ char *slash;
+ ssize_t link_len;
+ snprintf(pathbuf, sizeof(pathbuf), "/sys/dev/char/%d:%d",
+ major(st.st_rdev), minor(st.st_rdev));
+ link_len = readlink(pathbuf, link, sizeof(link) - 1);
+ if (link_len > 0) {
+ link[link_len] = '\0';
+ slash = strrchr(link, '/');
+ if (slash) {
+ snprintf(pathbuf, sizeof(pathbuf),
+ "usb:%s", slash + 1);
+ devpath = pathbuf;
+ }
+ }
+ }
+
+ register_device_callback(devname, devpath,
+ local_ep_in, local_ep_out,
interface->bInterfaceNumber, device->iSerialNumber, zero_mask);
break;
}
@@ -532,7 +557,7 @@ int usb_close(usb_handle *h)
return 0;
}
-static void register_device(const char *dev_name,
+static void register_device(const char *dev_name, const char *devpath,
unsigned char ep_in, unsigned char ep_out,
int interface, int serial_index, unsigned zero_mask)
{
@@ -644,7 +669,7 @@ static void register_device(const char *dev_name,
usb->next->prev = usb;
adb_mutex_unlock(&usb_lock);
- register_usb_transport(usb, serial, usb->writeable);
+ register_usb_transport(usb, serial, devpath, usb->writeable);
return;
fail:
diff --git a/adb/usb_linux_client.c b/adb/usb_linux_client.c
index 635fa4b..b110ed8 100644
--- a/adb/usb_linux_client.c
+++ b/adb/usb_linux_client.c
@@ -72,7 +72,7 @@ static void *usb_open_thread(void *x)
usb->fd = fd;
D("[ usb_thread - registering device ]\n");
- register_usb_transport(usb, 0, 1);
+ register_usb_transport(usb, 0, 0, 1);
}
// never gets here
diff --git a/adb/usb_osx.c b/adb/usb_osx.c
index 00d02da..45ce444 100644
--- a/adb/usb_osx.c
+++ b/adb/usb_osx.c
@@ -125,10 +125,13 @@ AndroidInterfaceAdded(void *refCon, io_iterator_t iterator)
IOUSBDeviceInterface197 **dev = NULL;
HRESULT result;
SInt32 score;
+ UInt32 locationId;
UInt16 vendor;
UInt16 product;
UInt8 serialIndex;
char serial[256];
+ char devpathBuf[64];
+ char *devpath = NULL;
while ((usbInterface = IOIteratorNext(iterator))) {
//* Create an intermediate interface plugin
@@ -192,6 +195,11 @@ AndroidInterfaceAdded(void *refCon, io_iterator_t iterator)
kr = (*dev)->GetDeviceVendor(dev, &vendor);
kr = (*dev)->GetDeviceProduct(dev, &product);
+ kr = (*dev)->GetLocationID(dev, &locationId);
+ if (kr == 0) {
+ snprintf(devpathBuf, sizeof(devpathBuf), "usb:%lX", locationId);
+ devpath = devpathBuf;
+ }
kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex);
if (serialIndex > 0) {
@@ -256,7 +264,7 @@ AndroidInterfaceAdded(void *refCon, io_iterator_t iterator)
}
DBG("AndroidDeviceAdded calling register_usb_transport\n");
- register_usb_transport(handle, (serial[0] ? serial : NULL), 1);
+ register_usb_transport(handle, (serial[0] ? serial : NULL), devpath, 1);
// Register for an interest notification of this device being removed.
// Pass the reference to our private data as the refCon for the
diff --git a/adb/usb_windows.c b/adb/usb_windows.c
index b216999..a2fbb79 100644
--- a/adb/usb_windows.c
+++ b/adb/usb_windows.c
@@ -490,7 +490,7 @@ void find_devices() {
true)) {
// Lets make sure that we don't duplicate this device
if (register_new_device(handle)) {
- register_usb_transport(handle, serial_number, 1);
+ register_usb_transport(handle, serial_number, NULL, 1);
} else {
D("register_new_device failed for %s\n", interf_name);
usb_cleanup_handle(handle);