summaryrefslogtreecommitdiffstats
path: root/adb/transport.c
diff options
context:
space:
mode:
authorScott Anderson <saa@android.com>2012-05-30 18:11:27 -0700
committerScott Anderson <saa@android.com>2012-06-05 11:13:40 -0700
commit2ca3e6b35f79136418ebc32fef57580698dbd045 (patch)
treee691312df3690d47d2066cd107449ee96a23ac5e /adb/transport.c
parente82c2db05cae70a0490a1f84b7211ef42c329671 (diff)
downloadsystem_core-2ca3e6b35f79136418ebc32fef57580698dbd045.zip
system_core-2ca3e6b35f79136418ebc32fef57580698dbd045.tar.gz
system_core-2ca3e6b35f79136418ebc32fef57580698dbd045.tar.bz2
adb: Generalizing -s to take qualifiers.
Prior to this change, -s could take either a serial number or a device path (e.g. "-s 01498B1F02015015" or "-s usb:1-4.2"). This change extends -s to also allow product, model or device names (e.g. "-s product:mysid"). These new qualifiers will only be available on devices that are running an adb daemon that provides properties in the connect message per Change-Id: I09200decde4facb8fc9b4056fdae910155f2bcb9 The product, model and device are derived from the ro.product.name, ro.product.model and ro.product.device properties respectively. They are prefixed with "product:", "model:" or "device:" as appropriate. In addition, any non-alphanumerics in the model are changed to underscores. If the -s parameter matches multiple devices, the result will be the same as when multiple devices are connected but no -d, -e or -s option is specified. In general, this means the user will get "error: more than one device". However for get-state, get-devpath and get-serialno, they will get "unknown". The format of "devices -l" was changed to list all of the qualifiers that are available. The following example output (with the last digits of the serial numbers replaced with X's) is with a Galaxy Prime with an older adb daemon and another Galaxy Prime and Galaxy S both with the enhanced adb daemons: List of devices attached 016B75D60A0060XX device usb:2-5 product:mysid model:Galaxy_Nexus device:toro 3731B535FAC200XX device usb:1-4.2 product:soju model:Nexus_S device:crespo 01498B1F020150XX device usb:1-4.1 Note that the serial number and state are now column oriented instead of tab delimited. After the serial number and state, all qualifiers are listed with each preceded by a space. The output of the original devices command (without -l) is unchanged. Change-Id: Iceeb2789874effc25a630d514a375d6f1889dc56 Signed-off-by: Scott Anderson <saa@android.com>
Diffstat (limited to 'adb/transport.c')
-rw-r--r--adb/transport.c122
1 files changed, 104 insertions, 18 deletions
diff --git a/adb/transport.c b/adb/transport.c
index 359b0d6..c88b90f 100644
--- a/adb/transport.c
+++ b/adb/transport.c
@@ -743,6 +743,45 @@ void remove_transport_disconnect(atransport* t, adisconnect* dis)
dis->next = dis->prev = dis;
}
+static int qual_char_is_invalid(char ch)
+{
+ if ('A' <= ch && ch <= 'Z')
+ return 0;
+ if ('a' <= ch && ch <= 'z')
+ return 0;
+ if ('0' <= ch && ch <= '9')
+ return 0;
+ return 1;
+}
+
+static int qual_match(const char *to_test,
+ const char *prefix, const char *qual, int sanitize_qual)
+{
+ if (!to_test || !*to_test)
+ /* Return true if both the qual and to_test are null strings. */
+ return !qual || !*qual;
+
+ if (!qual)
+ return 0;
+
+ if (prefix) {
+ while (*prefix) {
+ if (*prefix++ != *to_test++)
+ return 0;
+ }
+ }
+
+ while (*qual) {
+ char ch = *qual++;
+ if (sanitize_qual && qual_char_is_invalid(ch))
+ ch = '_';
+ if (ch != *to_test++)
+ return 0;
+ }
+
+ /* Everything matched so far. Return true if *to_test is a NUL. */
+ return !*to_test;
+}
atransport *acquire_one_transport(int state, transport_type ttype, const char* serial, char** error_out)
{
@@ -764,13 +803,19 @@ retry:
/* check for matching serial number */
if (serial) {
- if (t->serial && !strcmp(serial, t->serial)) {
- result = t;
- break;
- }
- if (t->devpath && !strcmp(serial, t->devpath)) {
+ if ((t->serial && !strcmp(serial, t->serial)) ||
+ (t->devpath && !strcmp(serial, t->devpath)) ||
+ qual_match(serial, "product:", t->product, 0) ||
+ qual_match(serial, "model:", t->model, 1) ||
+ qual_match(serial, "device:", t->device, 0)) {
+ if (result) {
+ if (error_out)
+ *error_out = "more than one device";
+ ambiguous = 1;
+ result = NULL;
+ break;
+ }
result = t;
- break;
}
} else {
if (ttype == kTransportUsb && t->type == kTransportUsb) {
@@ -846,7 +891,58 @@ static const char *statename(atransport *t)
}
}
-int list_transports(char *buf, size_t bufsize, int show_devpath)
+static void add_qual(char **buf, size_t *buf_size,
+ const char *prefix, const char *qual, int sanitize_qual)
+{
+ size_t len;
+ int prefix_len;
+
+ if (!buf || !*buf || !buf_size || !*buf_size || !qual || !*qual)
+ return;
+
+ len = snprintf(*buf, *buf_size, "%s%n%s", prefix, &prefix_len, qual);
+
+ if (sanitize_qual) {
+ char *cp;
+ for (cp = *buf + prefix_len; cp < *buf + len; cp++) {
+ if (qual_char_is_invalid(*cp))
+ *cp = '_';
+ }
+ }
+
+ *buf_size -= len;
+ *buf += len;
+}
+
+static size_t format_transport(atransport *t, char *buf, size_t bufsize,
+ int long_listing)
+{
+ const char* serial = t->serial;
+ if (!serial || !serial[0])
+ serial = "????????????";
+
+ if (!long_listing) {
+ return snprintf(buf, bufsize, "%s\t%s\n", serial, statename(t));
+ } else {
+ size_t len, remaining = bufsize;
+
+ len = snprintf(buf, remaining, "%-22s %s", serial, statename(t));
+ remaining -= len;
+ buf += len;
+
+ add_qual(&buf, &remaining, " ", t->devpath, 0);
+ add_qual(&buf, &remaining, " product:", t->product, 0);
+ add_qual(&buf, &remaining, " model:", t->model, 1);
+ add_qual(&buf, &remaining, " device:", t->device, 0);
+
+ len = snprintf(buf, remaining, "\n");
+ remaining -= len;
+
+ return bufsize - remaining;
+ }
+}
+
+int list_transports(char *buf, size_t bufsize, int long_listing)
{
char* p = buf;
char* end = buf + bufsize;
@@ -856,17 +952,7 @@ int list_transports(char *buf, size_t bufsize, int show_devpath)
/* XXX OVERRUN PROBLEMS XXX */
adb_mutex_lock(&transport_lock);
for(t = transport_list.next; t != &transport_list; t = t->next) {
- const char* serial = t->serial;
- if (!serial || !serial[0])
- serial = "????????????";
- 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));
-
+ len = format_transport(t, p, end - p, long_listing);
if (p + len >= end) {
/* discard last line if buffer is too short */
break;