blob: e07c92c217b6d77fd146e3552ad05bb2e81dc5e7 [file] [log] [blame]
Dan Albertb302d122015-02-24 15:51:19 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dan Albertdb6fe642015-03-19 15:21:08 -070017#define TRACE_TAG TRACE_ADB
18
19#include "sysdeps.h"
20#include "adb_client.h"
21
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080022#include <errno.h>
23#include <limits.h>
24#include <stdarg.h>
Dan Albertb302d122015-02-24 15:51:19 -080025#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080028#include <sys/stat.h>
Dan Albertb302d122015-02-24 15:51:19 -080029#include <sys/types.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080030
Elliott Hughes949f2622015-04-27 14:20:17 -070031#include <string>
Elliott Hughes04a98c22015-04-29 08:35:59 -070032#include <vector>
33
34#include <base/stringprintf.h>
Elliott Hughes949f2622015-04-27 14:20:17 -070035
Dan Albert66a91b02015-02-24 21:26:58 -080036#include "adb_io.h"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080037
38static transport_type __adb_transport = kTransportAny;
39static const char* __adb_serial = NULL;
40
Stefan Hilzingerfb798d92010-04-19 12:21:12 +010041static int __adb_server_port = DEFAULT_ADB_PORT;
Matt Gumbel411775c2012-11-14 10:16:17 -080042static const char* __adb_server_name = NULL;
Stefan Hilzingerfb798d92010-04-19 12:21:12 +010043
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080044void adb_set_transport(transport_type type, const char* serial)
45{
46 __adb_transport = type;
47 __adb_serial = serial;
48}
49
Stefan Hilzingerfb798d92010-04-19 12:21:12 +010050void adb_set_tcp_specifics(int server_port)
51{
52 __adb_server_port = server_port;
53}
54
Matt Gumbel411775c2012-11-14 10:16:17 -080055void adb_set_tcp_name(const char* hostname)
56{
57 __adb_server_name = hostname;
58}
59
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080060int adb_get_emulator_console_port(void)
61{
62 const char* serial = __adb_serial;
63 int port;
64
65 if (serial == NULL) {
66 /* if no specific device was specified, we need to look at */
67 /* the list of connected devices, and extract an emulator */
68 /* name from it. two emulators is an error */
Elliott Hughes04a98c22015-04-29 08:35:59 -070069 std::string error;
70 char* tmp = adb_query("host:devices", &error);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080071 char* p = tmp;
Elliott Hughes04a98c22015-04-29 08:35:59 -070072 if (!tmp) {
73 printf("no emulator connected: %s\n", error.c_str());
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080074 return -1;
75 }
76 while (*p) {
77 char* q = strchr(p, '\n');
78 if (q != NULL)
79 *q++ = 0;
80 else
81 q = p + strlen(p);
82
83 if (!memcmp(p, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1)) {
84 if (serial != NULL) { /* more than one emulator listed */
85 free(tmp);
86 return -2;
87 }
88 serial = p;
89 }
90
91 p = q;
92 }
93 free(tmp);
94
95 if (serial == NULL)
96 return -1; /* no emulator found */
97 }
98 else {
99 if (memcmp(serial, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1) != 0)
100 return -1; /* not an emulator */
101 }
102
103 serial += sizeof(LOCAL_CLIENT_PREFIX)-1;
104 port = strtol(serial, NULL, 10);
105 return port;
106}
107
Elliott Hughes04a98c22015-04-29 08:35:59 -0700108std::string perror_str(const char* msg) {
109 return android::base::StringPrintf("%s: %s", msg, strerror(errno));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800110}
111
Elliott Hughes04a98c22015-04-29 08:35:59 -0700112static int switch_socket_transport(int fd, std::string* error) {
Elliott Hughes949f2622015-04-27 14:20:17 -0700113 std::string service;
114 if (__adb_serial) {
115 service += "host:transport:";
116 service += __adb_serial;
117 } else {
Dan Albertf30d73c2015-02-25 17:51:28 -0800118 const char* transport_type = "???";
Elliott Hughes949f2622015-04-27 14:20:17 -0700119 switch (__adb_transport) {
120 case kTransportUsb:
121 transport_type = "transport-usb";
122 break;
123 case kTransportLocal:
124 transport_type = "transport-local";
125 break;
126 case kTransportAny:
127 transport_type = "transport-any";
128 break;
129 case kTransportHost:
130 // no switch necessary
131 return 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800132 }
Elliott Hughes949f2622015-04-27 14:20:17 -0700133 service += "host:";
134 service += transport_type;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800135 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800136
Elliott Hughes949f2622015-04-27 14:20:17 -0700137 char tmp[5];
138 snprintf(tmp, sizeof(tmp), "%04zx", service.size());
139 if (!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, service.c_str(), service.size())) {
Elliott Hughes04a98c22015-04-29 08:35:59 -0700140 *error = perror_str("write failure during connection");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800141 adb_close(fd);
142 return -1;
143 }
144 D("Switch transport in progress\n");
145
Elliott Hughes04a98c22015-04-29 08:35:59 -0700146 if (!adb_status(fd, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800147 adb_close(fd);
Elliott Hughes04a98c22015-04-29 08:35:59 -0700148 D("Switch transport failed: %s\n", error->c_str());
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800149 return -1;
150 }
151 D("Switch transport success\n");
152 return 0;
153}
154
Elliott Hughes04a98c22015-04-29 08:35:59 -0700155bool adb_status(int fd, std::string* error) {
156 char buf[5];
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800157
Elliott Hughes04a98c22015-04-29 08:35:59 -0700158 if (!ReadFdExactly(fd, buf, 4)) {
159 *error = perror_str("protocol fault (couldn't read status)");
160 return false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800161 }
162
Elliott Hughes04a98c22015-04-29 08:35:59 -0700163 if (!memcmp(buf, "OKAY", 4)) {
164 return true;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800165 }
166
Elliott Hughes04a98c22015-04-29 08:35:59 -0700167 if (memcmp(buf, "FAIL", 4)) {
168 *error = android::base::StringPrintf("protocol fault (status %02x %02x %02x %02x?!)",
169 buf[0], buf[1], buf[2], buf[3]);
170 return false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800171 }
172
Elliott Hughes04a98c22015-04-29 08:35:59 -0700173 if (!ReadFdExactly(fd, buf, 4)) {
174 *error = perror_str("protocol fault (couldn't read status length)");
175 return false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800176 }
177 buf[4] = 0;
Elliott Hughes04a98c22015-04-29 08:35:59 -0700178
179 unsigned long len = strtoul(buf, 0, 16);
180 error->resize(len + 1, '\0'); // Ensure NUL-termination.
181 if (!ReadFdExactly(fd, &(*error)[0], len)) {
182 *error = perror_str("protocol fault (couldn't read status message)");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800183 }
Elliott Hughes04a98c22015-04-29 08:35:59 -0700184 return false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800185}
186
Elliott Hughes04a98c22015-04-29 08:35:59 -0700187int _adb_connect(const char *service, std::string* error) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800188 char tmp[5];
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800189 int fd;
190
191 D("_adb_connect: %s\n", service);
Elliott Hughes04a98c22015-04-29 08:35:59 -0700192 size_t len = strlen(service);
193 if ((len < 1) || (len > 1024)) {
194 *error = android::base::StringPrintf("service name too long (%zd)", len);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800195 return -1;
196 }
Elliott Hughes04a98c22015-04-29 08:35:59 -0700197 snprintf(tmp, sizeof tmp, "%04zx", len);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800198
Matt Gumbel411775c2012-11-14 10:16:17 -0800199 if (__adb_server_name)
200 fd = socket_network_client(__adb_server_name, __adb_server_port, SOCK_STREAM);
201 else
202 fd = socket_loopback_client(__adb_server_port, SOCK_STREAM);
203
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800204 if(fd < 0) {
Elliott Hughes04a98c22015-04-29 08:35:59 -0700205 *error = perror_str("cannot connect to daemon");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800206 return -2;
207 }
208
Elliott Hughes04a98c22015-04-29 08:35:59 -0700209 if (memcmp(service,"host",4) != 0 && switch_socket_transport(fd, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800210 return -1;
211 }
212
Dan Albert66a91b02015-02-24 21:26:58 -0800213 if(!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, service, len)) {
Elliott Hughes04a98c22015-04-29 08:35:59 -0700214 *error = perror_str("write failure during connection");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800215 adb_close(fd);
216 return -1;
217 }
218
Elliott Hughes04a98c22015-04-29 08:35:59 -0700219 if (!adb_status(fd, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800220 adb_close(fd);
221 return -1;
222 }
223
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700224 D("_adb_connect: return fd %d\n", fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800225 return fd;
226}
227
Elliott Hughes04a98c22015-04-29 08:35:59 -0700228int adb_connect(const char* service, std::string* error) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800229 // first query the adb server's version
Elliott Hughes04a98c22015-04-29 08:35:59 -0700230 int fd = _adb_connect("host:version", error);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800231
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700232 D("adb_connect: service %s\n", service);
Elliott Hughes04a98c22015-04-29 08:35:59 -0700233 if (fd == -2 && __adb_server_name) {
Matt Gumbel411775c2012-11-14 10:16:17 -0800234 fprintf(stderr,"** Cannot start server on remote host\n");
235 return fd;
Elliott Hughes04a98c22015-04-29 08:35:59 -0700236 } else if (fd == -2) {
Stefan Hilzingerfb798d92010-04-19 12:21:12 +0100237 fprintf(stdout,"* daemon not running. starting it now on port %d *\n",
238 __adb_server_port);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800239 start_server:
Elliott Hughes04a98c22015-04-29 08:35:59 -0700240 if (launch_server(__adb_server_port)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800241 fprintf(stderr,"* failed to start daemon *\n");
242 return -1;
243 } else {
244 fprintf(stdout,"* daemon started successfully *\n");
245 }
246 /* give the server some time to start properly and detect devices */
Xavier Ducrohet30a40332009-05-21 17:47:43 -0700247 adb_sleep_ms(3000);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800248 // fall through to _adb_connect
249 } else {
250 // if server was running, check its version to make sure it is not out of date
251 char buf[100];
Nick Kralevich1d448652013-12-10 10:18:10 -0800252 size_t n;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800253 int version = ADB_SERVER_VERSION - 1;
254
255 // if we have a file descriptor, then parse version result
Elliott Hughes04a98c22015-04-29 08:35:59 -0700256 if (fd >= 0) {
Dan Albert66a91b02015-02-24 21:26:58 -0800257 if(!ReadFdExactly(fd, buf, 4)) goto error;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800258
259 buf[4] = 0;
260 n = strtoul(buf, 0, 16);
Nick Kralevich1d448652013-12-10 10:18:10 -0800261 if(n > sizeof(buf)) goto error;
Dan Albert66a91b02015-02-24 21:26:58 -0800262 if(!ReadFdExactly(fd, buf, n)) goto error;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800263 adb_close(fd);
264
265 if (sscanf(buf, "%04x", &version) != 1) goto error;
266 } else {
267 // if fd is -1, then check for "unknown host service",
268 // which would indicate a version of adb that does not support the version command
Elliott Hughes04a98c22015-04-29 08:35:59 -0700269 if (*error == "unknown host service") {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800270 return fd;
Elliott Hughes04a98c22015-04-29 08:35:59 -0700271 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800272 }
273
274 if(version != ADB_SERVER_VERSION) {
275 printf("adb server is out of date. killing...\n");
Elliott Hughes04a98c22015-04-29 08:35:59 -0700276 fd = _adb_connect("host:kill", error);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800277 adb_close(fd);
278
279 /* XXX can we better detect its death? */
280 adb_sleep_ms(2000);
281 goto start_server;
282 }
283 }
284
285 // if the command is start-server, we are done.
Elliott Hughes04a98c22015-04-29 08:35:59 -0700286 if (!strcmp(service, "host:start-server")) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800287 return 0;
Elliott Hughes04a98c22015-04-29 08:35:59 -0700288 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800289
Elliott Hughes04a98c22015-04-29 08:35:59 -0700290 fd = _adb_connect(service, error);
291 if (fd == -1) {
292 D("_adb_connect error: %s", error->c_str());
Brian Carlstromcad81322013-10-18 13:58:48 -0700293 } else if(fd == -2) {
Matt Gumbel411775c2012-11-14 10:16:17 -0800294 fprintf(stderr,"** daemon still not running\n");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800295 }
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700296 D("adb_connect: return fd %d\n", fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800297
298 return fd;
299error:
300 adb_close(fd);
301 return -1;
302}
303
304
Elliott Hughes04a98c22015-04-29 08:35:59 -0700305int adb_command(const char* service, std::string* error) {
306 int fd = adb_connect(service, error);
307 if (fd < 0) {
308 fprintf(stderr, "error: %s\n", error->c_str());
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800309 return -1;
310 }
311
Elliott Hughes04a98c22015-04-29 08:35:59 -0700312 if (!adb_status(fd, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800313 adb_close(fd);
314 return -1;
315 }
316
317 return 0;
318}
319
Elliott Hughes04a98c22015-04-29 08:35:59 -0700320char* adb_query(const char* service, std::string* error) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800321 char buf[5];
Dan Albertf30d73c2015-02-25 17:51:28 -0800322 unsigned long n;
323 char* tmp;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800324
325 D("adb_query: %s\n", service);
Elliott Hughes04a98c22015-04-29 08:35:59 -0700326 int fd = adb_connect(service, error);
327 if (fd < 0) {
328 fprintf(stderr,"error: %s\n", error->c_str());
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800329 return 0;
330 }
331
Elliott Hughes04a98c22015-04-29 08:35:59 -0700332 if (!ReadFdExactly(fd, buf, 4)) goto oops;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800333
334 buf[4] = 0;
335 n = strtoul(buf, 0, 16);
Elliott Hughes04a98c22015-04-29 08:35:59 -0700336 // TODO: given that we just read a 4-byte hex length 0x????, why the test?
337 if (n >= 0xffff) {
338 *error = "reply is too long (>= 64KiB)";
Snild Dolkow4516a872014-01-30 10:08:38 +0100339 goto oops;
340 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800341
Dan Albertf30d73c2015-02-25 17:51:28 -0800342 tmp = reinterpret_cast<char*>(malloc(n + 1));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800343 if(tmp == 0) goto oops;
344
Dan Albert66a91b02015-02-24 21:26:58 -0800345 if(!ReadFdExactly(fd, tmp, n) == 0) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800346 tmp[n] = 0;
347 adb_close(fd);
348 return tmp;
349 }
350 free(tmp);
351
352oops:
353 adb_close(fd);
354 return 0;
355}