summaryrefslogtreecommitdiffstats
path: root/adb
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2015-04-30 17:32:03 -0700
committerElliott Hughes <enh@google.com>2015-05-01 17:09:34 -0700
commit92af733ee202caa3b5475fe27fcc81582f11e7c8 (patch)
tree0e5d4bc49cc6299f80a0cccd4ba205d5dfcbb3cb /adb
parent5cffd971997ace97ebfd2ecb7d43a64c03cf3169 (diff)
downloadsystem_core-92af733ee202caa3b5475fe27fcc81582f11e7c8.zip
system_core-92af733ee202caa3b5475fe27fcc81582f11e7c8.tar.gz
system_core-92af733ee202caa3b5475fe27fcc81582f11e7c8.tar.bz2
More adb buffer fixes.
This patch factors out a lot of the basic protocol code: sending OKAY, sending FAIL, and sending a length-prefixed string. ADB_TRACE has been non-optional for a long time, so let's just remove the #ifs. Also actually build the device tracker test tool (and remove its duplicate). Bug: http://b/20666660 Change-Id: I6c7d59f18707bdc62ca69dea45547617f9f31fc6 (cherry picked from commit e67f1f87d9b1188ec8617035db7006c37ee7b21e)
Diffstat (limited to 'adb')
-rw-r--r--adb/Android.mk15
-rw-r--r--adb/adb.cpp123
-rw-r--r--adb/adb.h3
-rw-r--r--adb/adb_client.cpp10
-rw-r--r--adb/adb_io.cpp35
-rw-r--r--adb/adb_io.h20
-rw-r--r--adb/adb_io_test.cpp4
-rw-r--r--adb/adb_listeners.cpp52
-rw-r--r--adb/adb_listeners.h4
-rw-r--r--adb/adb_trace.h31
-rw-r--r--adb/adb_utils.cpp29
-rw-r--r--adb/adb_utils.h2
-rw-r--r--adb/commandline.cpp13
-rw-r--r--adb/remount_service.cpp17
-rw-r--r--adb/services.cpp135
-rw-r--r--adb/set_verity_enable_state_service.cpp1
-rw-r--r--adb/sockets.cpp37
-rw-r--r--adb/sysdeps_win32.cpp1
-rw-r--r--adb/test_track_devices.cpp65
-rw-r--r--adb/test_track_jdwp.cpp97
-rw-r--r--adb/transport.cpp205
-rw-r--r--adb/transport.h6
22 files changed, 306 insertions, 599 deletions
diff --git a/adb/Android.mk b/adb/Android.mk
index 9b6e147..dd1343b 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -124,6 +124,21 @@ endif
include $(BUILD_HOST_NATIVE_TEST)
+# adb device tracker (used by ddms) test tool
+# =========================================================
+
+ifeq ($(HOST_OS),linux)
+include $(CLEAR_VARS)
+LOCAL_CLANG := $(adb_host_clang)
+LOCAL_MODULE := adb_device_tracker_test
+LOCAL_CFLAGS := -DADB_HOST=1 $(LIBADB_CFLAGS)
+LOCAL_SRC_FILES := test_track_devices.cpp
+LOCAL_SHARED_LIBRARIES := liblog libbase
+LOCAL_STATIC_LIBRARIES := libadb libcrypto_static libcutils
+LOCAL_LDLIBS += -lrt -ldl -lpthread
+include $(BUILD_HOST_EXECUTABLE)
+endif
+
# adb host tool
# =========================================================
include $(CLEAR_VARS)
diff --git a/adb/adb.cpp b/adb/adb.cpp
index e526914..11c65da 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -48,9 +48,7 @@
#include <sys/mount.h>
#endif
-#if ADB_TRACE
ADB_MUTEX_DEFINE( D_lock );
-#endif
int HOST = 0;
@@ -322,28 +320,6 @@ static size_t fill_connect_data(char *buf, size_t bufsize)
#endif
}
-#if !ADB_HOST
-static void send_msg_with_header(int fd, const char* msg, size_t msglen) {
- char header[5];
- if (msglen > 0xffff)
- msglen = 0xffff;
- snprintf(header, sizeof(header), "%04x", (unsigned)msglen);
- WriteFdExactly(fd, header, 4);
- WriteFdExactly(fd, msg, msglen);
-}
-#endif
-
-#if ADB_HOST
-static void send_msg_with_okay(int fd, const char* msg, size_t msglen) {
- char header[9];
- if (msglen > 0xffff)
- msglen = 0xffff;
- snprintf(header, sizeof(header), "OKAY%04x", (unsigned)msglen);
- WriteFdExactly(fd, header, 8);
- WriteFdExactly(fd, msg, msglen);
-}
-#endif // ADB_HOST
-
void send_connect(atransport *t)
{
D("Calling send_connect \n");
@@ -356,32 +332,6 @@ void send_connect(atransport *t)
send_packet(cp, t);
}
-#if ADB_HOST
-static const char* connection_state_name(atransport *t)
-{
- if (t == NULL) {
- return "unknown";
- }
-
- switch(t->connection_state) {
- case CS_BOOTLOADER:
- return "bootloader";
- case CS_DEVICE:
- return "device";
- case CS_RECOVERY:
- return "recovery";
- case CS_SIDELOAD:
- return "sideload";
- case CS_OFFLINE:
- return "offline";
- case CS_UNAUTHORIZED:
- return "unauthorized";
- default:
- return "unknown";
- }
-}
-#endif // ADB_HOST
-
// qual_overwrite is used to overwrite a qualifier string. dst is a
// pointer to a char pointer. It is assumed that if *dst is non-NULL, it
// was malloc'ed and needs to freed. *dst will be set to a dup of src.
@@ -752,20 +702,11 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri
{
if (!strcmp(service, "list-forward")) {
// Create the list of forward redirections.
- int buffer_size = format_listeners(NULL, 0);
- // Add one byte for the trailing zero.
- char* buffer = reinterpret_cast<char*>(malloc(buffer_size + 1));
- if (buffer == nullptr) {
- sendfailmsg(reply_fd, "not enough memory");
- return 1;
- }
- (void) format_listeners(buffer, buffer_size + 1);
+ std::string listeners = format_listeners();
#if ADB_HOST
- send_msg_with_okay(reply_fd, buffer, buffer_size);
-#else
- send_msg_with_header(reply_fd, buffer, buffer_size);
+ SendOkay(reply_fd);
#endif
- free(buffer);
+ SendProtocolString(reply_fd, listeners);
return 1;
}
@@ -773,9 +714,9 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri
remove_all_listeners();
#if ADB_HOST
/* On the host: 1st OKAY is connect, 2nd OKAY is status */
- adb_write(reply_fd, "OKAY", 4);
+ SendOkay(reply_fd);
#endif
- adb_write(reply_fd, "OKAY", 4);
+ SendOkay(reply_fd);
return 1;
}
@@ -800,19 +741,19 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri
if (createForward) {
// Check forward: parameter format: '<local>;<remote>'
if(remote == 0) {
- sendfailmsg(reply_fd, "malformed forward spec");
+ SendFail(reply_fd, "malformed forward spec");
return 1;
}
*remote++ = 0;
if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) {
- sendfailmsg(reply_fd, "malformed forward spec");
+ SendFail(reply_fd, "malformed forward spec");
return 1;
}
} else {
// Check killforward: parameter format: '<local>'
if (local[0] == 0) {
- sendfailmsg(reply_fd, "malformed forward spec");
+ SendFail(reply_fd, "malformed forward spec");
return 1;
}
}
@@ -820,7 +761,7 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri
std::string error_msg;
transport = acquire_one_transport(CS_ANY, ttype, serial, &error_msg);
if (!transport) {
- sendfailmsg(reply_fd, error_msg.c_str());
+ SendFail(reply_fd, error_msg);
return 1;
}
@@ -833,9 +774,9 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri
if (r == INSTALL_STATUS_OK) {
#if ADB_HOST
/* On the host: 1st OKAY is connect, 2nd OKAY is status */
- WriteFdExactly(reply_fd, "OKAY", 4);
+ SendOkay(reply_fd);
#endif
- WriteFdExactly(reply_fd, "OKAY", 4);
+ SendOkay(reply_fd);
return 1;
}
@@ -851,7 +792,7 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri
break;
case INSTALL_STATUS_LISTENER_NOT_FOUND: message = "listener not found"; break;
}
- sendfailmsg(reply_fd, message.c_str());
+ SendFail(reply_fd, message);
return 1;
}
return 0;
@@ -862,7 +803,7 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
if(!strcmp(service, "kill")) {
fprintf(stderr,"adb server killed by remote request\n");
fflush(stdout);
- adb_write(reply_fd, "OKAY", 4);
+ SendOkay(reply_fd);
usb_cleanup();
exit(0);
}
@@ -892,25 +833,25 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
if (transport) {
s->transport = transport;
- adb_write(reply_fd, "OKAY", 4);
+ SendOkay(reply_fd);
} else {
- sendfailmsg(reply_fd, error_msg.c_str());
+ SendFail(reply_fd, error_msg);
}
return 1;
}
// return a list of all connected devices
if (!strncmp(service, "devices", 7)) {
- char buffer[4096];
- int use_long = !strcmp(service+7, "-l");
- if (use_long || service[7] == 0) {
- memset(buffer, 0, sizeof(buffer));
- D("Getting device list \n");
- list_transports(buffer, sizeof(buffer), use_long);
- D("Wrote device list \n");
- send_msg_with_okay(reply_fd, buffer, strlen(buffer));
+ 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
@@ -937,15 +878,15 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
}
}
- send_msg_with_okay(reply_fd, buffer, strlen(buffer));
+ SendOkay(reply_fd);
+ SendProtocolString(reply_fd, buffer);
return 0;
}
// returns our value for ADB_SERVER_VERSION
if (!strcmp(service, "version")) {
- char version[12];
- snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION);
- send_msg_with_okay(reply_fd, version, strlen(version));
+ SendOkay(reply_fd);
+ SendProtocolString(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION));
return 0;
}
@@ -955,7 +896,8 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
if (transport && transport->serial) {
out = transport->serial;
}
- send_msg_with_okay(reply_fd, out, strlen(out));
+ SendOkay(reply_fd);
+ SendProtocolString(reply_fd, out);
return 0;
}
if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
@@ -964,7 +906,8 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
if (transport && transport->devpath) {
out = transport->devpath;
}
- send_msg_with_okay(reply_fd, out, strlen(out));
+ SendOkay(reply_fd);
+ SendProtocolString(reply_fd, out);
return 0;
}
// indicates a new emulator instance has started
@@ -977,8 +920,8 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
if(!strncmp(service,"get-state",strlen("get-state"))) {
transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
- const char *state = connection_state_name(transport);
- send_msg_with_okay(reply_fd, state, strlen(state));
+ SendOkay(reply_fd);
+ SendProtocolString(reply_fd, transport->connection_state_name());
return 0;
}
#endif // ADB_HOST
diff --git a/adb/adb.h b/adb/adb.h
index b8c6156..fd9d0e6 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -209,6 +209,8 @@ struct atransport
unsigned char token[TOKEN_SIZE];
fdevent auth_fde;
unsigned failed_auth_attempts;
+
+ const char* connection_state_name() const;
};
@@ -369,7 +371,6 @@ enum subproc_mode {
#define USB_FFS_ADB_IN USB_FFS_ADB_EP(ep2)
#endif
-int sendfailmsg(int fd, const char *reason);
int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s);
void handle_online(atransport *t);
diff --git a/adb/adb_client.cpp b/adb/adb_client.cpp
index 62f79fa..33eee82 100644
--- a/adb/adb_client.cpp
+++ b/adb/adb_client.cpp
@@ -56,7 +56,7 @@ static bool ReadProtocolString(int fd, std::string* s, std::string* error) {
buf[4] = 0;
unsigned long len = strtoul(buf, 0, 16);
- s->resize(len + 1, '\0'); // Ensure NUL-termination.
+ s->resize(len, '\0');
if (!ReadFdExactly(fd, &(*s)[0], len)) {
*error = perror_str("protocol fault (couldn't read status message)");
return false;
@@ -136,9 +136,7 @@ static int switch_socket_transport(int fd, std::string* error) {
service += transport_type;
}
- char tmp[5];
- snprintf(tmp, sizeof(tmp), "%04zx", service.size());
- if (!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, service.c_str(), service.size())) {
+ if (!SendProtocolString(fd, service)) {
*error = perror_str("write failure during connection");
adb_close(fd);
return -1;
@@ -199,9 +197,7 @@ int _adb_connect(const std::string& service, std::string* error) {
return -1;
}
- char tmp[5];
- snprintf(tmp, sizeof(tmp), "%04zx", service.size());
- if(!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, &service[0], service.size())) {
+ if(!SendProtocolString(fd, service)) {
*error = perror_str("write failure during connection");
adb_close(fd);
return -1;
diff --git a/adb/adb_io.cpp b/adb/adb_io.cpp
index d89f304..c34daf9 100644
--- a/adb/adb_io.cpp
+++ b/adb/adb_io.cpp
@@ -22,14 +22,31 @@
#include <unistd.h>
#include "adb_trace.h"
-#include "transport.h"
+#include "adb_utils.h"
+
+bool SendProtocolString(int fd, const std::string& s) {
+ int length = s.size();
+ if (length > 0xffff) {
+ length = 0xffff;
+ }
+
+ char buf[5];
+ snprintf(buf, sizeof(buf), "%04x", length);
+ return WriteFdExactly(fd, buf, 4) && WriteFdExactly(fd, s);
+}
+
+bool SendOkay(int fd) {
+ return WriteFdExactly(fd, "OKAY", 4);
+}
+
+bool SendFail(int fd, const std::string& reason) {
+ return WriteFdExactly(fd, "FAIL", 4) && SendProtocolString(fd, reason);
+}
bool ReadFdExactly(int fd, void* buf, size_t len) {
char* p = reinterpret_cast<char*>(buf);
-#if ADB_TRACE
size_t len0 = len;
-#endif
D("readx: fd=%d wanted=%zu\n", fd, len);
while (len > 0) {
@@ -47,12 +64,10 @@ bool ReadFdExactly(int fd, void* buf, size_t len) {
}
}
-#if ADB_TRACE
D("readx: fd=%d wanted=%zu got=%zu\n", fd, len0, len0 - len);
if (ADB_TRACING) {
dump_hex(reinterpret_cast<const unsigned char*>(buf), len0);
}
-#endif
return true;
}
@@ -61,12 +76,10 @@ bool WriteFdExactly(int fd, const void* buf, size_t len) {
const char* p = reinterpret_cast<const char*>(buf);
int r;
-#if ADB_TRACE
D("writex: fd=%d len=%d: ", fd, (int)len);
if (ADB_TRACING) {
dump_hex(reinterpret_cast<const unsigned char*>(buf), len);
}
-#endif
while (len > 0) {
r = adb_write(fd, p, len);
@@ -90,6 +103,14 @@ bool WriteFdExactly(int fd, const void* buf, size_t len) {
return true;
}
+bool WriteFdExactly(int fd, const char* str) {
+ return WriteFdExactly(fd, str, strlen(str));
+}
+
+bool WriteFdExactly(int fd, const std::string& str) {
+ return WriteFdExactly(fd, str.c_str(), str.size());
+}
+
bool WriteStringFully(int fd, const char* str) {
return WriteFdExactly(fd, str, strlen(str));
}
diff --git a/adb/adb_io.h b/adb/adb_io.h
index 8d237ce..3b8b050 100644
--- a/adb/adb_io.h
+++ b/adb/adb_io.h
@@ -17,9 +17,19 @@
#ifndef ADB_IO_H
#define ADB_IO_H
-#include <stdbool.h>
#include <sys/types.h>
+#include <string>
+
+// Sends the protocol "OKAY" message.
+bool SendOkay(int fd);
+
+// Sends the protocol "FAIL" message, with the given failure reason.
+bool SendFail(int fd, const std::string& reason);
+
+// Writes a protocol-format string; a four hex digit length followed by the string data.
+bool SendProtocolString(int fd, const std::string& s);
+
/*
* Reads exactly len bytes from fd into buf.
*
@@ -37,9 +47,13 @@ bool ReadFdExactly(int fd, void *buf, size_t len);
* completed. If the other end of the fd (such as in a socket, pipe, or fifo),
* is closed, errno will be set to 0.
*/
-bool WriteFdExactly(int fd, const void *buf, size_t len);
+bool WriteFdExactly(int fd, const void* buf, size_t len);
+
+/* Same as above, but with an implicit len = strlen(buf). */
+bool WriteFdExactly(int fd, const char* s);
+bool WriteFdExactly(int fd, const std::string& s);
-/* Same as WriteFdExactly, but with an implicit len = strlen(buf). */
+// TODO: move minadb off this and remove it.
bool WriteStringFully(int fd, const char* str);
#endif /* ADB_IO_H */
diff --git a/adb/adb_io_test.cpp b/adb/adb_io_test.cpp
index da340b2..dd09919 100644
--- a/adb/adb_io_test.cpp
+++ b/adb/adb_io_test.cpp
@@ -139,13 +139,13 @@ TEST(io, WriteFdExactly_ENOSPC) {
ASSERT_EQ(ENOSPC, errno);
}
-TEST(io, WriteStringFully) {
+TEST(io, WriteFdExactly_string) {
const char str[] = "Foobar";
TemporaryFile tf;
ASSERT_NE(-1, tf.fd);
// Test writing a partial string to the file.
- ASSERT_TRUE(WriteStringFully(tf.fd, str)) << strerror(errno);
+ ASSERT_TRUE(WriteFdExactly(tf.fd, str)) << strerror(errno);
ASSERT_EQ(0, lseek(tf.fd, SEEK_SET, 0));
std::string s;
diff --git a/adb/adb_listeners.cpp b/adb/adb_listeners.cpp
index a1a5ddb..71a9321 100644
--- a/adb/adb_listeners.cpp
+++ b/adb/adb_listeners.cpp
@@ -19,6 +19,8 @@
#include <stdio.h>
#include <stdlib.h>
+#include <base/stringprintf.h>
+
#include "sysdeps.h"
#include "transport.h"
@@ -143,49 +145,17 @@ int local_name_to_fd(const char *name)
return -1;
}
-// Write a single line describing a listener to a user-provided buffer.
-// Appends a trailing zero, even in case of truncation, but the function
-// returns the full line length.
-// If |buffer| is NULL, does not write but returns required size.
-static int format_listener(alistener* l, char* buffer, size_t buffer_len) {
- // Format is simply:
- //
- // <device-serial> " " <local-name> " " <remote-name> "\n"
- //
- int local_len = strlen(l->local_name);
- int connect_len = strlen(l->connect_to);
- int serial_len = strlen(l->transport->serial);
-
- if (buffer != NULL) {
- snprintf(buffer, buffer_len, "%s %s %s\n",
- l->transport->serial, l->local_name, l->connect_to);
- }
- // NOTE: snprintf() on Windows returns -1 in case of truncation, so
- // return the computed line length instead.
- return local_len + connect_len + serial_len + 3;
-}
-
-// Write the list of current listeners (network redirections) into a
-// user-provided buffer. Appends a trailing zero, even in case of
-// trunctaion, but return the full size in bytes.
-// If |buffer| is NULL, does not write but returns required size.
-int format_listeners(char* buf, size_t buflen)
-{
- alistener* l;
- int result = 0;
- for (l = listener_list.next; l != &listener_list; l = l->next) {
+// Write the list of current listeners (network redirections) into a string.
+std::string format_listeners() {
+ std::string result;
+ for (alistener* l = listener_list.next; l != &listener_list; l = l->next) {
// Ignore special listeners like those for *smartsocket*
- if (l->connect_to[0] == '*')
- continue;
- int len = format_listener(l, buf, buflen);
- // Ensure there is space for the trailing zero.
- result += len;
- if (buf != NULL) {
- buf += len;
- buflen -= len;
- if (buflen <= 0)
- break;
+ if (l->connect_to[0] == '*') {
+ continue;
}
+ // <device-serial> " " <local-name> " " <remote-name> "\n"
+ android::base::StringAppendF(&result, "%s %s %s\n",
+ l->transport->serial, l->local_name, l->connect_to);
}
return result;
}
diff --git a/adb/adb_listeners.h b/adb/adb_listeners.h
index f55fdee..1d4f062 100644
--- a/adb/adb_listeners.h
+++ b/adb/adb_listeners.h
@@ -19,6 +19,8 @@
#include "adb.h"
+#include <string>
+
// error/status codes for install_listener.
enum install_status_t {
INSTALL_STATUS_OK = 0,
@@ -39,7 +41,7 @@ install_status_t install_listener(const char *local_name,
atransport* transport,
int no_rebind);
-int format_listeners(char* buf, size_t buflen);
+std::string format_listeners();
install_status_t remove_listener(const char* local_name, atransport* transport);
void remove_all_listeners(void);
diff --git a/adb/adb_trace.h b/adb/adb_trace.h
index 32b6ae4..63d4151 100644
--- a/adb/adb_trace.h
+++ b/adb/adb_trace.h
@@ -23,9 +23,6 @@
#include <stdio.h>
#endif
-/* define ADB_TRACE to 1 to enable tracing support, or 0 to disable it */
-#define ADB_TRACE 1
-
/* IMPORTANT: if you change the following list, don't
* forget to update the corresponding 'tags' table in
* the adb_trace_init() function implemented in adb.c
@@ -45,8 +42,6 @@ enum AdbTrace {
TRACE_FDEVENT,
} ;
-#if ADB_TRACE
-
#if !ADB_HOST
/*
* When running inside the emulator, guest's adbd can connect to 'adb-debug'
@@ -97,19 +92,6 @@ void adb_trace_init(void);
errno = save_errno; \
} \
} while (0)
-# define DD(...) \
- do { \
- int save_errno = errno; \
- adb_mutex_lock(&D_lock); \
- fprintf(stderr, "%16s: %5d:%5lu | ", \
- __FUNCTION__, \
- getpid(), adb_thread_id()); \
- errno = save_errno; \
- fprintf(stderr, __VA_ARGS__ ); \
- fflush(stderr); \
- adb_mutex_unlock(&D_lock); \
- errno = save_errno; \
- } while (0)
#else
# define D(...) \
do { \
@@ -129,19 +111,6 @@ void adb_trace_init(void);
__VA_ARGS__ ); \
} \
} while (0)
-# define DD(...) \
- do { \
- __android_log_print( \
- ANDROID_LOG_INFO, \
- __FUNCTION__, \
- __VA_ARGS__ ); \
- } while (0)
#endif /* ADB_HOST */
-#else
-# define D(...) ((void)0)
-# define DR(...) ((void)0)
-# define DD(...) ((void)0)
-# define ADB_TRACING 0
-#endif /* ADB_TRACE */
#endif /* __ADB_TRACE_H */
diff --git a/adb/adb_utils.cpp b/adb/adb_utils.cpp
index f10c143..0ce5ece 100644
--- a/adb/adb_utils.cpp
+++ b/adb/adb_utils.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define TRACE_TAG TRACE_ADB
+
#include "adb_utils.h"
#include <stdlib.h>
@@ -21,6 +23,11 @@
#include <sys/types.h>
#include <unistd.h>
+#include <algorithm>
+
+#include <base/stringprintf.h>
+
+#include "adb_trace.h"
#include "sysdeps.h"
bool getcwd(std::string* s) {
@@ -50,3 +57,25 @@ std::string escape_arg(const std::string& s) {
result.push_back('\'');
return result;
}
+
+void dump_hex(const void* data, size_t byte_count) {
+ byte_count = std::min(byte_count, size_t(16));
+
+ const uint8_t* p = reinterpret_cast<const uint8_t*>(data);
+
+ std::string line;
+ for (size_t i = 0; i < byte_count; ++i) {
+ android::base::StringAppendF(&line, "%02x", p[i]);
+ }
+ line.push_back(' ');
+
+ for (size_t i = 0; i < byte_count; ++i) {
+ int c = p[i];
+ if (c < 32 || c > 127) {
+ c = '.';
+ }
+ line.push_back(c);
+ }
+
+ DR("%s\n", line.c_str());
+}
diff --git a/adb/adb_utils.h b/adb/adb_utils.h
index 4b64afa..84f7d0c 100644
--- a/adb/adb_utils.h
+++ b/adb/adb_utils.h
@@ -24,4 +24,6 @@ bool directory_exists(const std::string& path);
std::string escape_arg(const std::string& s);
+void dump_hex(const void* ptr, size_t byte_count);
+
#endif
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 4941689..7964cd3 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -490,17 +490,8 @@ static int adb_download_buffer(const char *service, const char *fn, const void*
printf("\n");
}
- // TODO: should this be adb_status?
- char buf[5];
- if(!ReadFdExactly(fd, buf, 4)){
- fprintf(stderr,"* error reading response *\n");
- adb_close(fd);
- return -1;
- }
- if(memcmp(buf, "OKAY", 4)) {
- buf[4] = 0;
- fprintf(stderr,"* error response '%s' *\n", buf);
- adb_close(fd);
+ if (!adb_status(fd, &error)) {
+ fprintf(stderr,"* error response '%s' *\n", error.c_str());
return -1;
}
diff --git a/adb/remount_service.cpp b/adb/remount_service.cpp
index 1eaee73..3fb2fcb 100644
--- a/adb/remount_service.cpp
+++ b/adb/remount_service.cpp
@@ -92,7 +92,7 @@ static bool remount_partition(int fd, const char* partition, int* ro) {
if (remount(partition, ro)) {
char buf[200];
snprintf(buf, sizeof(buf), "remount of %s failed: %s\n", partition, strerror(errno));
- WriteStringFully(fd, buf);
+ WriteFdExactly(fd, buf);
return false;
}
return true;
@@ -102,7 +102,7 @@ void remount_service(int fd, void* cookie) {
char prop_buf[PROPERTY_VALUE_MAX];
if (getuid() != 0) {
- WriteStringFully(fd, "Not running as root. Try \"adb root\" first.\n");
+ WriteFdExactly(fd, "Not running as root. Try \"adb root\" first.\n");
adb_close(fd);
return;
}
@@ -128,12 +128,11 @@ void remount_service(int fd, void* cookie) {
both ? " and " : "",
vendor_verified ? "vendor" : "",
both ? "s" : "");
- WriteStringFully(fd, buffer);
- snprintf(buffer, sizeof(buffer),
- "Use \"adb disable-verity\" to disable verity.\n"
- "If you do not, remount may succeed, however, you will still "
- "not be able to write to these volumes.\n");
- WriteStringFully(fd, buffer);
+ WriteFdExactly(fd, buffer);
+ WriteFdExactly(fd,
+ "Use \"adb disable-verity\" to disable verity.\n"
+ "If you do not, remount may succeed, however, you will still "
+ "not be able to write to these volumes.\n");
}
bool success = true;
@@ -141,7 +140,7 @@ void remount_service(int fd, void* cookie) {
success &= remount_partition(fd, "/vendor", &vendor_ro);
success &= remount_partition(fd, "/oem", &oem_ro);
- WriteStringFully(fd, success ? "remount succeeded\n" : "remount failed\n");
+ WriteFdExactly(fd, success ? "remount succeeded\n" : "remount failed\n");
adb_close(fd);
}
diff --git a/adb/services.cpp b/adb/services.cpp
index e6c84a4..fa5a1a1 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -31,10 +31,11 @@
#include <unistd.h>
#endif
+#include <base/file.h>
#include <base/stringprintf.h>
+#include <base/strings.h>
#if !ADB_HOST
-#include "base/file.h"
#include "cutils/android_reboot.h"
#include "cutils/properties.h"
#endif
@@ -147,8 +148,7 @@ static bool reboot_service_impl(int fd, const char* arg) {
// in the command file.
if (strcmp(reboot_arg, "sideload") == 0) {
if (getuid() != 0) {
- snprintf(buf, sizeof(buf), "'adb root' is required for 'adb reboot sideload'.\n");
- WriteStringFully(fd, buf);
+ WriteFdExactly(fd, "'adb root' is required for 'adb reboot sideload'.\n");
return false;
}
@@ -175,14 +175,14 @@ static bool reboot_service_impl(int fd, const char* arg) {
int ret = snprintf(property_val, sizeof(property_val), "reboot,%s", reboot_arg);
if (ret >= static_cast<int>(sizeof(property_val))) {
snprintf(buf, sizeof(buf), "reboot string too long. length=%d\n", ret);
- WriteStringFully(fd, buf);
+ WriteFdExactly(fd, buf);
return false;
}
ret = property_set(ANDROID_RB_PROPERTY, property_val);
if (ret < 0) {
snprintf(buf, sizeof(buf), "reboot failed: %d\n", ret);
- WriteStringFully(fd, buf);
+ WriteFdExactly(fd, buf);
return false;
}
@@ -208,7 +208,7 @@ void reverse_service(int fd, void* arg)
const char* command = reinterpret_cast<const char*>(arg);
if (handle_forward_request(command, kTransportAny, NULL, fd) < 0) {
- sendfailmsg(fd, "not a reverse forwarding command");
+ SendFail(fd, "not a reverse forwarding command");
}
free(arg);
adb_close(fd);
@@ -551,9 +551,9 @@ static void wait_for_state(int fd, void* cookie)
std::string error_msg = "unknown error";
atransport* t = acquire_one_transport(sinfo->state, sinfo->transport, sinfo->serial, &error_msg);
if (t != 0) {
- WriteFdExactly(fd, "OKAY", 4);
+ SendOkay(fd);
} else {
- sendfailmsg(fd, error_msg.c_str());
+ SendFail(fd, error_msg);
}
if (sinfo->serial)
@@ -563,35 +563,31 @@ static void wait_for_state(int fd, void* cookie)
D("wait_for_state is done\n");
}
-static void connect_device(char* host, char* buffer, int buffer_size)
-{
- int port, fd;
- char* portstr = strchr(host, ':');
- char hostbuf[100];
- char serial[100];
- int ret;
-
- strncpy(hostbuf, host, sizeof(hostbuf) - 1);
- if (portstr) {
- if (portstr - host >= (ptrdiff_t)sizeof(hostbuf)) {
- snprintf(buffer, buffer_size, "bad host name %s", host);
- return;
- }
- // zero terminate the host at the point we found the colon
- hostbuf[portstr - host] = 0;
- if (sscanf(portstr + 1, "%d", &port) != 1) {
- snprintf(buffer, buffer_size, "bad port number %s", portstr);
+static void connect_device(const std::string& host, std::string* response) {
+ if (host.empty()) {
+ *response = "empty host name";
+ return;
+ }
+
+ std::vector<std::string> pieces = android::base::Split(host, ":");
+ const std::string& hostname = pieces[0];
+
+ int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
+ if (pieces.size() > 1) {
+ if (sscanf(pieces[1].c_str(), "%d", &port) != 1) {
+ *response = android::base::StringPrintf("bad port number %s", pieces[1].c_str());
return;
}
- } else {
- port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
}
- snprintf(serial, sizeof(serial), "%s:%d", hostbuf, port);
+ // This may look like we're putting 'host' back together,
+ // but we're actually inserting the default port if necessary.
+ std::string serial = android::base::StringPrintf("%s:%d", hostname.c_str(), port);
- fd = socket_network_client_timeout(hostbuf, port, SOCK_STREAM, 10);
+ int fd = socket_network_client_timeout(hostname.c_str(), port, SOCK_STREAM, 10);
if (fd < 0) {
- snprintf(buffer, buffer_size, "unable to connect to %s:%d", host, port);
+ *response = android::base::StringPrintf("unable to connect to %s:%d",
+ hostname.c_str(), port);
return;
}
@@ -599,85 +595,74 @@ static void connect_device(char* host, char* buffer, int buffer_size)
close_on_exec(fd);
disable_tcp_nagle(fd);
- ret = register_socket_transport(fd, serial, port, 0);
+ int ret = register_socket_transport(fd, serial.c_str(), port, 0);
if (ret < 0) {
adb_close(fd);
- snprintf(buffer, buffer_size, "already connected to %s", serial);
+ *response = android::base::StringPrintf("already connected to %s", serial.c_str());
} else {
- snprintf(buffer, buffer_size, "connected to %s", serial);
+ *response = android::base::StringPrintf("connected to %s", serial.c_str());
}
}
-void connect_emulator(char* port_spec, char* buffer, int buffer_size)
-{
- char* port_separator = strchr(port_spec, ',');
- if (!port_separator) {
- snprintf(buffer, buffer_size,
- "unable to parse '%s' as <console port>,<adb port>",
- port_spec);
+void connect_emulator(const std::string& port_spec, std::string* response) {
+ std::vector<std::string> pieces = android::base::Split(port_spec, ",");
+ if (pieces.size() != 2) {
+ *response = android::base::StringPrintf("unable to parse '%s' as <console port>,<adb port>",
+ port_spec.c_str());
return;
}
- // Zero-terminate console port and make port_separator point to 2nd port.
- *port_separator++ = 0;
- int console_port = strtol(port_spec, NULL, 0);
- int adb_port = strtol(port_separator, NULL, 0);
- if (!(console_port > 0 && adb_port > 0)) {
- *(port_separator - 1) = ',';
- snprintf(buffer, buffer_size,
- "Invalid port numbers: Expected positive numbers, got '%s'",
- port_spec);
+ int console_port = strtol(pieces[0].c_str(), NULL, 0);
+ int adb_port = strtol(pieces[1].c_str(), NULL, 0);
+ if (console_port <= 0 || adb_port <= 0) {
+ *response = android::base::StringPrintf("Invalid port numbers: %s", port_spec.c_str());
return;
}
- /* Check if the emulator is already known.
- * Note: There's a small but harmless race condition here: An emulator not
- * present just yet could be registered by another invocation right
- * after doing this check here. However, local_connect protects
- * against double-registration too. From here, a better error message
- * can be produced. In the case of the race condition, the very specific
- * error message won't be shown, but the data doesn't get corrupted. */
+ // Check if the emulator is already known.
+ // Note: There's a small but harmless race condition here: An emulator not
+ // present just yet could be registered by another invocation right
+ // after doing this check here. However, local_connect protects
+ // against double-registration too. From here, a better error message
+ // can be produced. In the case of the race condition, the very specific
+ // error message won't be shown, but the data doesn't get corrupted.
atransport* known_emulator = find_emulator_transport_by_adb_port(adb_port);
- if (known_emulator != NULL) {
- snprintf(buffer, buffer_size,
- "Emulator on port %d already registered.", adb_port);
+ if (known_emulator != nullptr) {
+ *response = android::base::StringPrintf("Emulator already registered on port %d", adb_port);
return;
}
- /* Check if more emulators can be registered. Similar unproblematic
- * race condition as above. */
+ // Check if more emulators can be registered. Similar unproblematic
+ // race condition as above.
int candidate_slot = get_available_local_transport_index();
if (candidate_slot < 0) {
- snprintf(buffer, buffer_size, "Cannot accept more emulators.");
+ *response = "Cannot accept more emulators";
return;
}
- /* Preconditions met, try to connect to the emulator. */
+ // Preconditions met, try to connect to the emulator.
if (!local_connect_arbitrary_ports(console_port, adb_port)) {
- snprintf(buffer, buffer_size,
- "Connected to emulator on ports %d,%d", console_port, adb_port);
+ *response = android::base::StringPrintf("Connected to emulator on ports %d,%d",
+ console_port, adb_port);
} else {
- snprintf(buffer, buffer_size,
- "Could not connect to emulator on ports %d,%d",
- console_port, adb_port);
+ *response = android::base::StringPrintf("Could not connect to emulator on ports %d,%d",
+ console_port, adb_port);
}
}
static void connect_service(int fd, void* cookie)
{
- char buf[4096];
- char resp[4096];
char *host = reinterpret_cast<char*>(cookie);
+ std::string response;
if (!strncmp(host, "emu:", 4)) {
- connect_emulator(host + 4, buf, sizeof(buf));
+ connect_emulator(host + 4, &response);
} else {
- connect_device(host, buf, sizeof(buf));
+ connect_device(host, &response);
}
// Send response for emulator and device
- snprintf(resp, sizeof(resp), "%04x%s",(unsigned)strlen(buf), buf);
- WriteFdExactly(fd, resp, strlen(resp));
+ SendProtocolString(fd, response);
adb_close(fd);
}
#endif
diff --git a/adb/set_verity_enable_state_service.cpp b/adb/set_verity_enable_state_service.cpp
index b75ed4c..d856d57 100644
--- a/adb/set_verity_enable_state_service.cpp
+++ b/adb/set_verity_enable_state_service.cpp
@@ -21,7 +21,6 @@
#include <fcntl.h>
#include <inttypes.h>
#include <stdarg.h>
-#include <stdbool.h>
#include <stdio.h>
#include <sys/stat.h>
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index f468029..32ca17d 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -37,23 +37,6 @@ ADB_MUTEX_DEFINE( socket_list_lock );
static void local_socket_close_locked(asocket *s);
-int sendfailmsg(int fd, const char *reason)
-{
- char buf[9];
- int len;
- len = strlen(reason);
- if (len > 0xffff) {
- len = 0xffff;
- }
-
- snprintf(buf, sizeof buf, "FAIL%04x", len);
- if (!WriteFdExactly(fd, buf, 8)) {
- return -1;
- }
-
- return WriteFdExactly(fd, reason, len) ? 0 : -1;
-}
-
static unsigned local_socket_next_id = 1;
static asocket local_socket_list = {
@@ -608,7 +591,7 @@ static void local_socket_ready_notify(asocket *s)
s->ready = local_socket_ready;
s->shutdown = NULL;
s->close = local_socket_close;
- adb_write(s->fd, "OKAY", 4);
+ SendOkay(s->fd);
s->ready(s);
}
@@ -620,11 +603,11 @@ static void local_socket_close_notify(asocket *s)
s->ready = local_socket_ready;
s->shutdown = NULL;
s->close = local_socket_close;
- sendfailmsg(s->fd, "closed");
+ SendFail(s->fd, "closed");
s->close(s);
}
-unsigned unhex(unsigned char *s, int len)
+static unsigned unhex(unsigned char *s, int len)
{
unsigned n = 0, c;
@@ -654,6 +637,8 @@ unsigned unhex(unsigned char *s, int len)
return n;
}
+#if ADB_HOST
+
#define PREFIX(str) { str, sizeof(str) - 1 }
static const struct prefix_struct {
const char *str;
@@ -670,7 +655,7 @@ static const int num_prefixes = (sizeof(prefixes) / sizeof(prefixes[0]));
skipping over the 'serial' parameter in the ADB protocol,
where parameter string may be a host:port string containing
the protocol delimiter (colon). */
-char *skip_host_serial(char *service) {
+static char *skip_host_serial(char *service) {
char *first_colon, *serial_end;
int i;
@@ -698,6 +683,8 @@ char *skip_host_serial(char *service) {
return serial_end;
}
+#endif // ADB_HOST
+
static int smart_socket_enqueue(asocket *s, apacket *p)
{
unsigned len;
@@ -799,7 +786,7 @@ static int smart_socket_enqueue(asocket *s, apacket *p)
s2 = create_host_service_socket(service, serial);
if(s2 == 0) {
D( "SS(%d): couldn't create host service '%s'\n", s->id, service );
- sendfailmsg(s->peer->fd, "unknown host service");
+ SendFail(s->peer->fd, "unknown host service");
goto fail;
}
@@ -810,7 +797,7 @@ static int smart_socket_enqueue(asocket *s, apacket *p)
** connection, and close this smart socket now
** that its work is done.
*/
- adb_write(s->peer->fd, "OKAY", 4);
+ SendOkay(s->peer->fd);
s->peer->ready = local_socket_ready;
s->peer->shutdown = NULL;
@@ -831,7 +818,7 @@ static int smart_socket_enqueue(asocket *s, apacket *p)
s->transport = acquire_one_transport(CS_ANY, kTransportAny, NULL, &error_msg);
if (s->transport == NULL) {
- sendfailmsg(s->peer->fd, error_msg.c_str());
+ SendFail(s->peer->fd, error_msg);
goto fail;
}
}
@@ -841,7 +828,7 @@ static int smart_socket_enqueue(asocket *s, apacket *p)
/* if there's no remote we fail the connection
** right here and terminate it
*/
- sendfailmsg(s->peer->fd, "device offline (x)");
+ SendFail(s->peer->fd, "device offline (x)");
goto fail;
}
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
index 633f6f5..a21272f 100644
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -22,7 +22,6 @@
#include <windows.h>
#include <errno.h>
-#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/adb/test_track_devices.cpp b/adb/test_track_devices.cpp
index 77b3ad9..3e823e9 100644
--- a/adb/test_track_devices.cpp
+++ b/adb/test_track_devices.cpp
@@ -1,3 +1,5 @@
+// TODO: replace this with a shell/python script.
+
/* a simple test program, connects to ADB server, and opens a track-devices session */
#include <netdb.h>
#include <sys/socket.h>
@@ -6,6 +8,8 @@
#include <errno.h>
#include <memory.h>
+#include <base/file.h>
+
static void
panic( const char* msg )
{
@@ -13,82 +17,49 @@ panic( const char* msg )
exit(1);
}
-static int
-unix_write( int fd, const char* buf, int len )
-{
- int result = 0;
- while (len > 0) {
- int len2 = write(fd, buf, len);
- if (len2 < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
- return -1;
- }
- result += len2;
- len -= len2;
- buf += len2;
- }
- return result;
-}
+int main(int argc, char* argv[]) {
+ const char* request = "host:track-devices";
-static int
-unix_read( int fd, char* buf, int len )
-{
- int result = 0;
- while (len > 0) {
- int len2 = read(fd, buf, len);
- if (len2 < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
- return -1;
- }
- result += len2;
- len -= len2;
- buf += len2;
+ if (argv[1] && strcmp(argv[1], "--jdwp") == 0) {
+ request = "track-jdwp";
}
- return result;
-}
-
-int main( void )
-{
- int ret, s;
+ int ret;
struct sockaddr_in server;
char buffer[1024];
- const char* request = "host:track-devices";
- int len;
memset( &server, 0, sizeof(server) );
server.sin_family = AF_INET;
server.sin_port = htons(5037);
server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- s = socket( PF_INET, SOCK_STREAM, 0 );
+ int s = socket( PF_INET, SOCK_STREAM, 0 );
ret = connect( s, (struct sockaddr*) &server, sizeof(server) );
if (ret < 0) panic( "could not connect to server" );
/* send the request */
- len = snprintf( buffer, sizeof buffer, "%04x%s", strlen(request), request );
- if (unix_write(s, buffer, len) < 0)
+ int len = snprintf(buffer, sizeof(buffer), "%04zx%s", strlen(request), request);
+ if (!android::base::WriteFully(s, buffer, len))
panic( "could not send request" );
/* read the OKAY answer */
- if (unix_read(s, buffer, 4) != 4)
+ if (!android::base::ReadFully(s, buffer, 4))
panic( "could not read request" );
printf( "server answer: %.*s\n", 4, buffer );
/* now loop */
- for (;;) {
+ while (true) {
char head[5] = "0000";
- if (unix_read(s, head, 4) < 0)
+ if (!android::base::ReadFully(s, head, 4))
panic("could not read length");
- if ( sscanf( head, "%04x", &len ) != 1 )
+ int len;
+ if (sscanf(head, "%04x", &len) != 1 )
panic("could not decode length");
- if (unix_read(s, buffer, len) != len)
+ if (!android::base::ReadFully(s, buffer, len))
panic("could not read data");
printf( "received header %.*s (%d bytes):\n%.*s", 4, head, len, len, buffer );
diff --git a/adb/test_track_jdwp.cpp b/adb/test_track_jdwp.cpp
deleted file mode 100644
index 8ecc6b8..0000000
--- a/adb/test_track_jdwp.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/* a simple test program, connects to ADB server, and opens a track-devices session */
-#include <netdb.h>
-#include <sys/socket.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <memory.h>
-
-static void
-panic( const char* msg )
-{
- fprintf(stderr, "PANIC: %s: %s\n", msg, strerror(errno));
- exit(1);
-}
-
-static int
-unix_write( int fd, const char* buf, int len )
-{
- int result = 0;
- while (len > 0) {
- int len2 = write(fd, buf, len);
- if (len2 < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
- return -1;
- }
- result += len2;
- len -= len2;
- buf += len2;
- }
- return result;
-}
-
-static int
-unix_read( int fd, char* buf, int len )
-{
- int result = 0;
- while (len > 0) {
- int len2 = read(fd, buf, len);
- if (len2 < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
- return -1;
- }
- result += len2;
- len -= len2;
- buf += len2;
- }
- return result;
-}
-
-
-int main( void )
-{
- int ret, s;
- struct sockaddr_in server;
- char buffer[1024];
- const char* request = "track-jdwp";
- int len;
-
- memset( &server, 0, sizeof(server) );
- server.sin_family = AF_INET;
- server.sin_port = htons(5037);
- server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
- s = socket( PF_INET, SOCK_STREAM, 0 );
- ret = connect( s, (struct sockaddr*) &server, sizeof(server) );
- if (ret < 0) panic( "could not connect to server" );
-
- /* send the request */
- len = snprintf( buffer, sizeof buffer, "%04x%s", strlen(request), request );
- if (unix_write(s, buffer, len) < 0)
- panic( "could not send request" );
-
- /* read the OKAY answer */
- if (unix_read(s, buffer, 4) != 4)
- panic( "could not read request" );
-
- printf( "server answer: %.*s\n", 4, buffer );
-
- /* now loop */
- for (;;) {
- char head[5] = "0000";
-
- if (unix_read(s, head, 4) < 0)
- panic("could not read length");
-
- if ( sscanf( head, "%04x", &len ) != 1 )
- panic("could not decode length");
-
- if (unix_read(s, buffer, len) != len)
- panic("could not read data");
-
- printf( "received header %.*s (%d bytes):\n%.*s", 4, head, len, len, buffer );
- }
- close(s);
-}
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 45740a8..b7f30ea 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -26,7 +26,10 @@
#include <string.h>
#include <unistd.h>
+#include <base/stringprintf.h>
+
#include "adb.h"
+#include "adb_utils.h"
static void transport_unref(atransport *t);
@@ -42,34 +45,6 @@ static atransport pending_list = {
ADB_MUTEX_DEFINE( transport_lock );
-#if ADB_TRACE
-#define MAX_DUMP_HEX_LEN 16
-void dump_hex(const unsigned char* ptr, size_t len)
-{
- int nn, len2 = len;
- // Build a string instead of logging each character.
- // MAX chars in 2 digit hex, one space, MAX chars, one '\0'.
- char buffer[MAX_DUMP_HEX_LEN *2 + 1 + MAX_DUMP_HEX_LEN + 1 ], *pb = buffer;
-
- if (len2 > MAX_DUMP_HEX_LEN) len2 = MAX_DUMP_HEX_LEN;
-
- for (nn = 0; nn < len2; nn++) {
- sprintf(pb, "%02x", ptr[nn]);
- pb += 2;
- }
- sprintf(pb++, " ");
-
- for (nn = 0; nn < len2; nn++) {
- int c = ptr[nn];
- if (c < 32 || c > 127)
- c = '.';
- *pb++ = c;
- }
- *pb++ = '\0';
- DR("%s\n", buffer);
-}
-#endif
-
void kick_transport(atransport* t)
{
if (t && !t->kicked)
@@ -117,10 +92,7 @@ void run_transport_disconnects(atransport* t)
}
}
-#if ADB_TRACE
-static void
-dump_packet(const char* name, const char* func, apacket* p)
-{
+static void dump_packet(const char* name, const char* func, apacket* p) {
unsigned command = p->msg.command;
int len = p->msg.data_length;
char cmd[9];
@@ -155,7 +127,6 @@ dump_packet(const char* name, const char* func, apacket* p)
name, func, cmd, arg0, arg1, len);
dump_hex(p->data, len);
}
-#endif /* ADB_TRACE */
static int
read_packet(int fd, const char* name, apacket** ppacket)
@@ -180,11 +151,9 @@ read_packet(int fd, const char* name, apacket** ppacket)
}
}
-#if ADB_TRACE
if (ADB_TRACING) {
dump_packet(name, "from remote", *ppacket);
}
-#endif
return 0;
}
@@ -199,11 +168,9 @@ write_packet(int fd, const char* name, apacket** ppacket)
name = buff;
}
-#if ADB_TRACE
if (ADB_TRACING) {
dump_packet(name, "to remote", *ppacket);
}
-#endif
len = sizeof(ppacket);
while(len > 0) {
r = adb_write(fd, p, len);
@@ -389,17 +356,6 @@ static fdevent transport_registration_fde;
#if ADB_HOST
-static int list_transports_msg(char* buffer, size_t bufferlen)
-{
- char head[5];
- int len;
-
- len = list_transports(buffer+4, bufferlen-4, 0);
- snprintf(head, sizeof(head), "%04x", len);
- memcpy(buffer, head, 4);
- len += 4;
- return len;
-}
/* this adds support required by the 'track-devices' service.
* this is used to send the content of "list_transport" to any
@@ -457,39 +413,29 @@ device_tracker_enqueue( asocket* socket, apacket* p )
return -1;
}
-static int
-device_tracker_send( device_tracker* tracker,
- const char* buffer,
- int len )
-{
- apacket* p = get_apacket();
- asocket* peer = tracker->socket.peer;
+static int device_tracker_send(device_tracker* tracker, const std::string& string) {
+ apacket* p = get_apacket();
+ asocket* peer = tracker->socket.peer;
- memcpy(p->data, buffer, len);
- p->len = len;
- return peer->enqueue( peer, p );
+ snprintf(reinterpret_cast<char*>(p->data), 5, "%04x", static_cast<int>(string.size()));
+ memcpy(&p->data[4], string.data(), string.size());
+ p->len = 4 + string.size();
+ return peer->enqueue(peer, p);
}
+static void device_tracker_ready(asocket* socket) {
+ device_tracker* tracker = reinterpret_cast<device_tracker*>(socket);
-static void
-device_tracker_ready( asocket* socket )
-{
- device_tracker* tracker = (device_tracker*) socket;
-
- /* we want to send the device list when the tracker connects
- * for the first time, even if no update occured */
+ // We want to send the device list when the tracker connects
+ // for the first time, even if no update occurred.
if (tracker->update_needed > 0) {
- char buffer[1024];
- int len;
-
tracker->update_needed = 0;
- len = list_transports_msg(buffer, sizeof(buffer));
- device_tracker_send(tracker, buffer, len);
+ std::string transports = list_transports(false);
+ device_tracker_send(tracker, transports);
}
}
-
asocket*
create_device_tracker(void)
{
@@ -510,27 +456,25 @@ create_device_tracker(void)
}
-/* call this function each time the transport list has changed */
-void update_transports(void) {
- char buffer[1024];
- int len;
- device_tracker* tracker;
-
- len = list_transports_msg(buffer, sizeof(buffer));
+// Call this function each time the transport list has changed.
+void update_transports() {
+ std::string transports = list_transports(false);
- tracker = device_tracker_list;
- while (tracker != NULL) {
- device_tracker* next = tracker->next;
- /* note: this may destroy the tracker if the connection is closed */
- device_tracker_send(tracker, buffer, len);
+ device_tracker* tracker = device_tracker_list;
+ while (tracker != nullptr) {
+ device_tracker* next = tracker->next;
+ // This may destroy the tracker if the connection is closed.
+ device_tracker_send(tracker, transports);
tracker = next;
}
}
+
#else
-void update_transports(void)
-{
- // nothing to do on the device side
+
+void update_transports() {
+ // Nothing to do on the device side.
}
+
#endif // ADB_HOST
struct tmsg
@@ -895,100 +839,71 @@ retry:
return result;
}
-#if ADB_HOST
-static const char *statename(atransport *t)
-{
- switch(t->connection_state){
+const char* atransport::connection_state_name() const {
+ switch (connection_state) {
case CS_OFFLINE: return "offline";
case CS_BOOTLOADER: return "bootloader";
case CS_DEVICE: return "device";
case CS_HOST: return "host";
case CS_RECOVERY: return "recovery";
- case CS_SIDELOAD: return "sideload";
case CS_NOPERM: return "no permissions";
+ case CS_SIDELOAD: return "sideload";
case CS_UNAUTHORIZED: return "unauthorized";
default: return "unknown";
}
}
-static void add_qual(char **buf, size_t *buf_size,
- const char *prefix, const char *qual, bool sanitize_qual)
-{
- if (!buf || !*buf || !buf_size || !*buf_size || !qual || !*qual)
+#if ADB_HOST
+
+static void append_transport_info(std::string* result, const char* key, const char* value, bool sanitize) {
+ if (value == nullptr || *value == '\0') {
return;
+ }
- int prefix_len;
- size_t len = snprintf(*buf, *buf_size, "%s%n%s", prefix, &prefix_len, qual);
+ *result += ' ';
+ *result += key;
- if (sanitize_qual) {
- for (char* cp = *buf + prefix_len; cp < *buf + len; cp++) {
- if (!isalnum(*cp))
- *cp = '_';
- }
+ for (const char* p = value; *p; ++p) {
+ result->push_back((!sanitize || isalnum(*p)) ? *p : '_');
}
-
- *buf_size -= len;
- *buf += len;
}
-static size_t format_transport(atransport *t, char *buf, size_t bufsize,
- int long_listing)
-{
+static void append_transport(atransport* t, std::string* result, bool long_listing) {
const char* serial = t->serial;
- if (!serial || !serial[0])
+ if (!serial || !serial[0]) {
serial = "????????????";
+ }
if (!long_listing) {
- return snprintf(buf, bufsize, "%s\t%s\n", serial, statename(t));
+ *result += serial;
+ *result += '\t';
+ *result += t->connection_state_name();
} else {
- size_t len, remaining = bufsize;
-
- len = snprintf(buf, remaining, "%-22s %s", serial, statename(t));
- remaining -= len;
- buf += len;
+ android::base::StringAppendF(result, "%-22s %s", serial, t->connection_state_name());
- add_qual(&buf, &remaining, " ", t->devpath, false);
- add_qual(&buf, &remaining, " product:", t->product, false);
- add_qual(&buf, &remaining, " model:", t->model, true);
- add_qual(&buf, &remaining, " device:", t->device, false);
-
- len = snprintf(buf, remaining, "\n");
- remaining -= len;
-
- return bufsize - remaining;
+ append_transport_info(result, "", t->devpath, false);
+ append_transport_info(result, "product:", t->product, false);
+ append_transport_info(result, "model:", t->model, true);
+ append_transport_info(result, "device:", t->device, false);
}
+ *result += '\n';
}
-int list_transports(char *buf, size_t bufsize, int long_listing)
-{
- char* p = buf;
- char* end = buf + bufsize;
- int len;
- atransport *t;
-
- /* XXX OVERRUN PROBLEMS XXX */
+std::string list_transports(bool long_listing) {
+ std::string result;
adb_mutex_lock(&transport_lock);
- for(t = transport_list.next; t != &transport_list; t = t->next) {
- len = format_transport(t, p, end - p, long_listing);
- if (p + len >= end) {
- /* discard last line if buffer is too short */
- break;
- }
- p += len;
+ for (atransport* t = transport_list.next; t != &transport_list; t = t->next) {
+ append_transport(t, &result, long_listing);
}
- p[0] = 0;
adb_mutex_unlock(&transport_lock);
- return p - buf;
+ return result;
}
-
/* hack for osx */
void close_usb_devices()
{
- atransport *t;
-
adb_mutex_lock(&transport_lock);
- for(t = transport_list.next; t != &transport_list; t = t->next) {
+ for (atransport* t = transport_list.next; t != &transport_list; t = t->next) {
if ( !t->kicked ) {
t->kicked = 1;
t->kick(t);
diff --git a/adb/transport.h b/adb/transport.h
index a2077e8..5b6fdac 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -23,10 +23,6 @@
#include "adb.h"
-#if ADB_TRACE
-void dump_hex(const unsigned char* ptr, size_t len);
-#endif
-
/*
* Obtain a transport from the available transports.
* If state is != CS_ANY, only transports in that state are considered.
@@ -45,7 +41,7 @@ void update_transports(void);
** 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 long_listing);
+std::string list_transports(bool long_listing);
atransport* find_transport(const char* serial);
void register_usb_transport(usb_handle* h, const char* serial,