blob: d677db8202d21c8987c3b4e39f477502b3e94969 [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
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080017#include <errno.h>
18#include <limits.h>
19#include <stdarg.h>
Dan Albertb302d122015-02-24 15:51:19 -080020#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080023#include <sys/stat.h>
Dan Albertb302d122015-02-24 15:51:19 -080024#include <sys/types.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080025
26#include "sysdeps.h"
27
28#define TRACE_TAG TRACE_ADB
29#include "adb_client.h"
Dan Albert66a91b02015-02-24 21:26:58 -080030#include "adb_io.h"
Dan Albertb302d122015-02-24 15:51:19 -080031#include "zipfile/zipfile.h"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080032
33static transport_type __adb_transport = kTransportAny;
34static const char* __adb_serial = NULL;
35
Stefan Hilzingerfb798d92010-04-19 12:21:12 +010036static int __adb_server_port = DEFAULT_ADB_PORT;
Matt Gumbel411775c2012-11-14 10:16:17 -080037static const char* __adb_server_name = NULL;
Stefan Hilzingerfb798d92010-04-19 12:21:12 +010038
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080039void adb_set_transport(transport_type type, const char* serial)
40{
41 __adb_transport = type;
42 __adb_serial = serial;
43}
44
Stefan Hilzingerfb798d92010-04-19 12:21:12 +010045void adb_set_tcp_specifics(int server_port)
46{
47 __adb_server_port = server_port;
48}
49
Matt Gumbel411775c2012-11-14 10:16:17 -080050void adb_set_tcp_name(const char* hostname)
51{
52 __adb_server_name = hostname;
53}
54
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080055int adb_get_emulator_console_port(void)
56{
57 const char* serial = __adb_serial;
58 int port;
59
60 if (serial == NULL) {
61 /* if no specific device was specified, we need to look at */
62 /* the list of connected devices, and extract an emulator */
63 /* name from it. two emulators is an error */
64 char* tmp = adb_query("host:devices");
65 char* p = tmp;
66 if(!tmp) {
67 printf("no emulator connected\n");
68 return -1;
69 }
70 while (*p) {
71 char* q = strchr(p, '\n');
72 if (q != NULL)
73 *q++ = 0;
74 else
75 q = p + strlen(p);
76
77 if (!memcmp(p, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1)) {
78 if (serial != NULL) { /* more than one emulator listed */
79 free(tmp);
80 return -2;
81 }
82 serial = p;
83 }
84
85 p = q;
86 }
87 free(tmp);
88
89 if (serial == NULL)
90 return -1; /* no emulator found */
91 }
92 else {
93 if (memcmp(serial, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1) != 0)
94 return -1; /* not an emulator */
95 }
96
97 serial += sizeof(LOCAL_CLIENT_PREFIX)-1;
98 port = strtol(serial, NULL, 10);
99 return port;
100}
101
102static char __adb_error[256] = { 0 };
103
104const char *adb_error(void)
105{
106 return __adb_error;
107}
108
109static int switch_socket_transport(int fd)
110{
111 char service[64];
112 char tmp[5];
113 int len;
114
115 if (__adb_serial)
116 snprintf(service, sizeof service, "host:transport:%s", __adb_serial);
117 else {
Dan Albertf30d73c2015-02-25 17:51:28 -0800118 const char* transport_type = "???";
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800119
120 switch (__adb_transport) {
121 case kTransportUsb:
122 transport_type = "transport-usb";
123 break;
124 case kTransportLocal:
125 transport_type = "transport-local";
126 break;
127 case kTransportAny:
128 transport_type = "transport-any";
129 break;
130 case kTransportHost:
131 // no switch necessary
132 return 0;
133 break;
134 }
135
136 snprintf(service, sizeof service, "host:%s", transport_type);
137 }
138 len = strlen(service);
139 snprintf(tmp, sizeof tmp, "%04x", len);
140
Dan Albert66a91b02015-02-24 21:26:58 -0800141 if(!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, service, len)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800142 strcpy(__adb_error, "write failure during connection");
143 adb_close(fd);
144 return -1;
145 }
146 D("Switch transport in progress\n");
147
148 if(adb_status(fd)) {
149 adb_close(fd);
150 D("Switch transport failed\n");
151 return -1;
152 }
153 D("Switch transport success\n");
154 return 0;
155}
156
157int adb_status(int fd)
158{
159 unsigned char buf[5];
160 unsigned len;
161
Dan Albert66a91b02015-02-24 21:26:58 -0800162 if(!ReadFdExactly(fd, buf, 4)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800163 strcpy(__adb_error, "protocol fault (no status)");
164 return -1;
165 }
166
167 if(!memcmp(buf, "OKAY", 4)) {
168 return 0;
169 }
170
171 if(memcmp(buf, "FAIL", 4)) {
172 sprintf(__adb_error,
173 "protocol fault (status %02x %02x %02x %02x?!)",
174 buf[0], buf[1], buf[2], buf[3]);
175 return -1;
176 }
177
Dan Albert66a91b02015-02-24 21:26:58 -0800178 if(!ReadFdExactly(fd, buf, 4)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800179 strcpy(__adb_error, "protocol fault (status len)");
180 return -1;
181 }
182 buf[4] = 0;
183 len = strtoul((char*)buf, 0, 16);
184 if(len > 255) len = 255;
Dan Albert66a91b02015-02-24 21:26:58 -0800185 if(!ReadFdExactly(fd, __adb_error, len)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800186 strcpy(__adb_error, "protocol fault (status read)");
187 return -1;
188 }
189 __adb_error[len] = 0;
190 return -1;
191}
192
193int _adb_connect(const char *service)
194{
195 char tmp[5];
196 int len;
197 int fd;
198
199 D("_adb_connect: %s\n", service);
200 len = strlen(service);
201 if((len < 1) || (len > 1024)) {
202 strcpy(__adb_error, "service name too long");
203 return -1;
204 }
205 snprintf(tmp, sizeof tmp, "%04x", len);
206
Matt Gumbel411775c2012-11-14 10:16:17 -0800207 if (__adb_server_name)
208 fd = socket_network_client(__adb_server_name, __adb_server_port, SOCK_STREAM);
209 else
210 fd = socket_loopback_client(__adb_server_port, SOCK_STREAM);
211
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800212 if(fd < 0) {
213 strcpy(__adb_error, "cannot connect to daemon");
214 return -2;
215 }
216
217 if (memcmp(service,"host",4) != 0 && switch_socket_transport(fd)) {
218 return -1;
219 }
220
Dan Albert66a91b02015-02-24 21:26:58 -0800221 if(!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, service, len)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800222 strcpy(__adb_error, "write failure during connection");
223 adb_close(fd);
224 return -1;
225 }
226
227 if(adb_status(fd)) {
228 adb_close(fd);
229 return -1;
230 }
231
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700232 D("_adb_connect: return fd %d\n", fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800233 return fd;
234}
235
236int adb_connect(const char *service)
237{
238 // first query the adb server's version
239 int fd = _adb_connect("host:version");
240
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700241 D("adb_connect: service %s\n", service);
Matt Gumbel411775c2012-11-14 10:16:17 -0800242 if(fd == -2 && __adb_server_name) {
243 fprintf(stderr,"** Cannot start server on remote host\n");
244 return fd;
245 } else if(fd == -2) {
Stefan Hilzingerfb798d92010-04-19 12:21:12 +0100246 fprintf(stdout,"* daemon not running. starting it now on port %d *\n",
247 __adb_server_port);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800248 start_server:
Stefan Hilzingerfb798d92010-04-19 12:21:12 +0100249 if(launch_server(__adb_server_port)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800250 fprintf(stderr,"* failed to start daemon *\n");
251 return -1;
252 } else {
253 fprintf(stdout,"* daemon started successfully *\n");
254 }
255 /* give the server some time to start properly and detect devices */
Xavier Ducrohet30a40332009-05-21 17:47:43 -0700256 adb_sleep_ms(3000);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800257 // fall through to _adb_connect
258 } else {
259 // if server was running, check its version to make sure it is not out of date
260 char buf[100];
Nick Kralevich1d448652013-12-10 10:18:10 -0800261 size_t n;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800262 int version = ADB_SERVER_VERSION - 1;
263
264 // if we have a file descriptor, then parse version result
265 if(fd >= 0) {
Dan Albert66a91b02015-02-24 21:26:58 -0800266 if(!ReadFdExactly(fd, buf, 4)) goto error;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800267
268 buf[4] = 0;
269 n = strtoul(buf, 0, 16);
Nick Kralevich1d448652013-12-10 10:18:10 -0800270 if(n > sizeof(buf)) goto error;
Dan Albert66a91b02015-02-24 21:26:58 -0800271 if(!ReadFdExactly(fd, buf, n)) goto error;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800272 adb_close(fd);
273
274 if (sscanf(buf, "%04x", &version) != 1) goto error;
275 } else {
276 // if fd is -1, then check for "unknown host service",
277 // which would indicate a version of adb that does not support the version command
278 if (strcmp(__adb_error, "unknown host service") != 0)
279 return fd;
280 }
281
282 if(version != ADB_SERVER_VERSION) {
283 printf("adb server is out of date. killing...\n");
284 fd = _adb_connect("host:kill");
285 adb_close(fd);
286
287 /* XXX can we better detect its death? */
288 adb_sleep_ms(2000);
289 goto start_server;
290 }
291 }
292
293 // if the command is start-server, we are done.
294 if (!strcmp(service, "host:start-server"))
295 return 0;
296
297 fd = _adb_connect(service);
Brian Carlstromcad81322013-10-18 13:58:48 -0700298 if(fd == -1) {
leozwang1be54622014-08-15 09:51:27 -0700299 D("_adb_connect error: %s", __adb_error);
Brian Carlstromcad81322013-10-18 13:58:48 -0700300 } else if(fd == -2) {
Matt Gumbel411775c2012-11-14 10:16:17 -0800301 fprintf(stderr,"** daemon still not running\n");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800302 }
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700303 D("adb_connect: return fd %d\n", fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800304
305 return fd;
306error:
307 adb_close(fd);
308 return -1;
309}
310
311
312int adb_command(const char *service)
313{
314 int fd = adb_connect(service);
315 if(fd < 0) {
Doug Zongkerbcad29f2014-06-26 15:35:36 -0700316 fprintf(stderr, "error: %s\n", adb_error());
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800317 return -1;
318 }
319
320 if(adb_status(fd)) {
321 adb_close(fd);
322 return -1;
323 }
324
325 return 0;
326}
327
328char *adb_query(const char *service)
329{
330 char buf[5];
Dan Albertf30d73c2015-02-25 17:51:28 -0800331 unsigned long n;
332 char* tmp;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800333
334 D("adb_query: %s\n", service);
335 int fd = adb_connect(service);
336 if(fd < 0) {
337 fprintf(stderr,"error: %s\n", __adb_error);
338 return 0;
339 }
340
Dan Albert66a91b02015-02-24 21:26:58 -0800341 if(!ReadFdExactly(fd, buf, 4)) goto oops;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800342
343 buf[4] = 0;
344 n = strtoul(buf, 0, 16);
Snild Dolkow4516a872014-01-30 10:08:38 +0100345 if(n >= 0xffff) {
346 strcpy(__adb_error, "reply is too long (>= 64kB)");
347 goto oops;
348 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800349
Dan Albertf30d73c2015-02-25 17:51:28 -0800350 tmp = reinterpret_cast<char*>(malloc(n + 1));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800351 if(tmp == 0) goto oops;
352
Dan Albert66a91b02015-02-24 21:26:58 -0800353 if(!ReadFdExactly(fd, tmp, n) == 0) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800354 tmp[n] = 0;
355 adb_close(fd);
356 return tmp;
357 }
358 free(tmp);
359
360oops:
361 adb_close(fd);
362 return 0;
363}