blob: 0f64998cd7362127144efd3fdfd087678af427d5 [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>
32
Dan Albert66a91b02015-02-24 21:26:58 -080033#include "adb_io.h"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080034
35static transport_type __adb_transport = kTransportAny;
36static const char* __adb_serial = NULL;
37
Stefan Hilzingerfb798d92010-04-19 12:21:12 +010038static int __adb_server_port = DEFAULT_ADB_PORT;
Matt Gumbel411775c2012-11-14 10:16:17 -080039static const char* __adb_server_name = NULL;
Stefan Hilzingerfb798d92010-04-19 12:21:12 +010040
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080041void adb_set_transport(transport_type type, const char* serial)
42{
43 __adb_transport = type;
44 __adb_serial = serial;
45}
46
Stefan Hilzingerfb798d92010-04-19 12:21:12 +010047void adb_set_tcp_specifics(int server_port)
48{
49 __adb_server_port = server_port;
50}
51
Matt Gumbel411775c2012-11-14 10:16:17 -080052void adb_set_tcp_name(const char* hostname)
53{
54 __adb_server_name = hostname;
55}
56
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080057int adb_get_emulator_console_port(void)
58{
59 const char* serial = __adb_serial;
60 int port;
61
62 if (serial == NULL) {
63 /* if no specific device was specified, we need to look at */
64 /* the list of connected devices, and extract an emulator */
65 /* name from it. two emulators is an error */
66 char* tmp = adb_query("host:devices");
67 char* p = tmp;
68 if(!tmp) {
69 printf("no emulator connected\n");
70 return -1;
71 }
72 while (*p) {
73 char* q = strchr(p, '\n');
74 if (q != NULL)
75 *q++ = 0;
76 else
77 q = p + strlen(p);
78
79 if (!memcmp(p, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1)) {
80 if (serial != NULL) { /* more than one emulator listed */
81 free(tmp);
82 return -2;
83 }
84 serial = p;
85 }
86
87 p = q;
88 }
89 free(tmp);
90
91 if (serial == NULL)
92 return -1; /* no emulator found */
93 }
94 else {
95 if (memcmp(serial, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1) != 0)
96 return -1; /* not an emulator */
97 }
98
99 serial += sizeof(LOCAL_CLIENT_PREFIX)-1;
100 port = strtol(serial, NULL, 10);
101 return port;
102}
103
104static char __adb_error[256] = { 0 };
105
106const char *adb_error(void)
107{
108 return __adb_error;
109}
110
111static int switch_socket_transport(int fd)
112{
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())) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800140 strcpy(__adb_error, "write failure during connection");
141 adb_close(fd);
142 return -1;
143 }
144 D("Switch transport in progress\n");
145
Elliott Hughes949f2622015-04-27 14:20:17 -0700146 if (adb_status(fd)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800147 adb_close(fd);
148 D("Switch transport failed\n");
149 return -1;
150 }
151 D("Switch transport success\n");
152 return 0;
153}
154
155int adb_status(int fd)
156{
157 unsigned char buf[5];
158 unsigned len;
159
Dan Albert66a91b02015-02-24 21:26:58 -0800160 if(!ReadFdExactly(fd, buf, 4)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800161 strcpy(__adb_error, "protocol fault (no status)");
162 return -1;
163 }
164
165 if(!memcmp(buf, "OKAY", 4)) {
166 return 0;
167 }
168
169 if(memcmp(buf, "FAIL", 4)) {
170 sprintf(__adb_error,
171 "protocol fault (status %02x %02x %02x %02x?!)",
172 buf[0], buf[1], buf[2], buf[3]);
173 return -1;
174 }
175
Dan Albert66a91b02015-02-24 21:26:58 -0800176 if(!ReadFdExactly(fd, buf, 4)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800177 strcpy(__adb_error, "protocol fault (status len)");
178 return -1;
179 }
180 buf[4] = 0;
181 len = strtoul((char*)buf, 0, 16);
182 if(len > 255) len = 255;
Dan Albert66a91b02015-02-24 21:26:58 -0800183 if(!ReadFdExactly(fd, __adb_error, len)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800184 strcpy(__adb_error, "protocol fault (status read)");
185 return -1;
186 }
187 __adb_error[len] = 0;
188 return -1;
189}
190
191int _adb_connect(const char *service)
192{
193 char tmp[5];
194 int len;
195 int fd;
196
197 D("_adb_connect: %s\n", service);
198 len = strlen(service);
199 if((len < 1) || (len > 1024)) {
200 strcpy(__adb_error, "service name too long");
201 return -1;
202 }
203 snprintf(tmp, sizeof tmp, "%04x", len);
204
Matt Gumbel411775c2012-11-14 10:16:17 -0800205 if (__adb_server_name)
206 fd = socket_network_client(__adb_server_name, __adb_server_port, SOCK_STREAM);
207 else
208 fd = socket_loopback_client(__adb_server_port, SOCK_STREAM);
209
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800210 if(fd < 0) {
211 strcpy(__adb_error, "cannot connect to daemon");
212 return -2;
213 }
214
215 if (memcmp(service,"host",4) != 0 && switch_socket_transport(fd)) {
216 return -1;
217 }
218
Dan Albert66a91b02015-02-24 21:26:58 -0800219 if(!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, service, len)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800220 strcpy(__adb_error, "write failure during connection");
221 adb_close(fd);
222 return -1;
223 }
224
225 if(adb_status(fd)) {
226 adb_close(fd);
227 return -1;
228 }
229
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700230 D("_adb_connect: return fd %d\n", fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800231 return fd;
232}
233
234int adb_connect(const char *service)
235{
236 // first query the adb server's version
237 int fd = _adb_connect("host:version");
238
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700239 D("adb_connect: service %s\n", service);
Matt Gumbel411775c2012-11-14 10:16:17 -0800240 if(fd == -2 && __adb_server_name) {
241 fprintf(stderr,"** Cannot start server on remote host\n");
242 return fd;
243 } else if(fd == -2) {
Stefan Hilzingerfb798d92010-04-19 12:21:12 +0100244 fprintf(stdout,"* daemon not running. starting it now on port %d *\n",
245 __adb_server_port);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800246 start_server:
Stefan Hilzingerfb798d92010-04-19 12:21:12 +0100247 if(launch_server(__adb_server_port)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800248 fprintf(stderr,"* failed to start daemon *\n");
249 return -1;
250 } else {
251 fprintf(stdout,"* daemon started successfully *\n");
252 }
253 /* give the server some time to start properly and detect devices */
Xavier Ducrohet30a40332009-05-21 17:47:43 -0700254 adb_sleep_ms(3000);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800255 // fall through to _adb_connect
256 } else {
257 // if server was running, check its version to make sure it is not out of date
258 char buf[100];
Nick Kralevich1d448652013-12-10 10:18:10 -0800259 size_t n;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800260 int version = ADB_SERVER_VERSION - 1;
261
262 // if we have a file descriptor, then parse version result
263 if(fd >= 0) {
Dan Albert66a91b02015-02-24 21:26:58 -0800264 if(!ReadFdExactly(fd, buf, 4)) goto error;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800265
266 buf[4] = 0;
267 n = strtoul(buf, 0, 16);
Nick Kralevich1d448652013-12-10 10:18:10 -0800268 if(n > sizeof(buf)) goto error;
Dan Albert66a91b02015-02-24 21:26:58 -0800269 if(!ReadFdExactly(fd, buf, n)) goto error;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800270 adb_close(fd);
271
272 if (sscanf(buf, "%04x", &version) != 1) goto error;
273 } else {
274 // if fd is -1, then check for "unknown host service",
275 // which would indicate a version of adb that does not support the version command
276 if (strcmp(__adb_error, "unknown host service") != 0)
277 return fd;
278 }
279
280 if(version != ADB_SERVER_VERSION) {
281 printf("adb server is out of date. killing...\n");
282 fd = _adb_connect("host:kill");
283 adb_close(fd);
284
285 /* XXX can we better detect its death? */
286 adb_sleep_ms(2000);
287 goto start_server;
288 }
289 }
290
291 // if the command is start-server, we are done.
292 if (!strcmp(service, "host:start-server"))
293 return 0;
294
295 fd = _adb_connect(service);
Brian Carlstromcad81322013-10-18 13:58:48 -0700296 if(fd == -1) {
leozwang1be54622014-08-15 09:51:27 -0700297 D("_adb_connect error: %s", __adb_error);
Brian Carlstromcad81322013-10-18 13:58:48 -0700298 } else if(fd == -2) {
Matt Gumbel411775c2012-11-14 10:16:17 -0800299 fprintf(stderr,"** daemon still not running\n");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800300 }
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700301 D("adb_connect: return fd %d\n", fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800302
303 return fd;
304error:
305 adb_close(fd);
306 return -1;
307}
308
309
310int adb_command(const char *service)
311{
312 int fd = adb_connect(service);
313 if(fd < 0) {
Doug Zongkerbcad29f2014-06-26 15:35:36 -0700314 fprintf(stderr, "error: %s\n", adb_error());
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800315 return -1;
316 }
317
318 if(adb_status(fd)) {
319 adb_close(fd);
320 return -1;
321 }
322
323 return 0;
324}
325
326char *adb_query(const char *service)
327{
328 char buf[5];
Dan Albertf30d73c2015-02-25 17:51:28 -0800329 unsigned long n;
330 char* tmp;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800331
332 D("adb_query: %s\n", service);
333 int fd = adb_connect(service);
334 if(fd < 0) {
335 fprintf(stderr,"error: %s\n", __adb_error);
336 return 0;
337 }
338
Dan Albert66a91b02015-02-24 21:26:58 -0800339 if(!ReadFdExactly(fd, buf, 4)) goto oops;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800340
341 buf[4] = 0;
342 n = strtoul(buf, 0, 16);
Snild Dolkow4516a872014-01-30 10:08:38 +0100343 if(n >= 0xffff) {
344 strcpy(__adb_error, "reply is too long (>= 64kB)");
345 goto oops;
346 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800347
Dan Albertf30d73c2015-02-25 17:51:28 -0800348 tmp = reinterpret_cast<char*>(malloc(n + 1));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800349 if(tmp == 0) goto oops;
350
Dan Albert66a91b02015-02-24 21:26:58 -0800351 if(!ReadFdExactly(fd, tmp, n) == 0) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800352 tmp[n] = 0;
353 adb_close(fd);
354 return tmp;
355 }
356 free(tmp);
357
358oops:
359 adb_close(fd);
360 return 0;
361}