blob: a485aa2eb64b0f716fe76273d944e931041ee549 [file] [log] [blame]
Dan Albert76649012015-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 Projectdd7bc332009-03-03 19:32:55 -080017#include <errno.h>
18#include <limits.h>
19#include <stdarg.h>
Dan Albert76649012015-02-24 15:51:19 -080020#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080023#include <sys/stat.h>
Dan Albert76649012015-02-24 15:51:19 -080024#include <sys/types.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080025
26#include "sysdeps.h"
27
28#define TRACE_TAG TRACE_ADB
29#include "adb_client.h"
Dan Albertcc731cc2015-02-24 21:26:58 -080030#include "adb_io.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080031
32static transport_type __adb_transport = kTransportAny;
33static const char* __adb_serial = NULL;
34
Stefan Hilzingerd0eacb82010-04-19 12:21:12 +010035static int __adb_server_port = DEFAULT_ADB_PORT;
Matt Gumbeld7b33082012-11-14 10:16:17 -080036static const char* __adb_server_name = NULL;
Stefan Hilzingerd0eacb82010-04-19 12:21:12 +010037
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080038void adb_set_transport(transport_type type, const char* serial)
39{
40 __adb_transport = type;
41 __adb_serial = serial;
42}
43
Stefan Hilzingerd0eacb82010-04-19 12:21:12 +010044void adb_set_tcp_specifics(int server_port)
45{
46 __adb_server_port = server_port;
47}
48
Matt Gumbeld7b33082012-11-14 10:16:17 -080049void adb_set_tcp_name(const char* hostname)
50{
51 __adb_server_name = hostname;
52}
53
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080054int adb_get_emulator_console_port(void)
55{
56 const char* serial = __adb_serial;
57 int port;
58
59 if (serial == NULL) {
60 /* if no specific device was specified, we need to look at */
61 /* the list of connected devices, and extract an emulator */
62 /* name from it. two emulators is an error */
63 char* tmp = adb_query("host:devices");
64 char* p = tmp;
65 if(!tmp) {
66 printf("no emulator connected\n");
67 return -1;
68 }
69 while (*p) {
70 char* q = strchr(p, '\n');
71 if (q != NULL)
72 *q++ = 0;
73 else
74 q = p + strlen(p);
75
76 if (!memcmp(p, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1)) {
77 if (serial != NULL) { /* more than one emulator listed */
78 free(tmp);
79 return -2;
80 }
81 serial = p;
82 }
83
84 p = q;
85 }
86 free(tmp);
87
88 if (serial == NULL)
89 return -1; /* no emulator found */
90 }
91 else {
92 if (memcmp(serial, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1) != 0)
93 return -1; /* not an emulator */
94 }
95
96 serial += sizeof(LOCAL_CLIENT_PREFIX)-1;
97 port = strtol(serial, NULL, 10);
98 return port;
99}
100
101static char __adb_error[256] = { 0 };
102
103const char *adb_error(void)
104{
105 return __adb_error;
106}
107
108static int switch_socket_transport(int fd)
109{
110 char service[64];
111 char tmp[5];
112 int len;
113
114 if (__adb_serial)
115 snprintf(service, sizeof service, "host:transport:%s", __adb_serial);
116 else {
Dan Albertbac34742015-02-25 17:51:28 -0800117 const char* transport_type = "???";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800118
119 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;
132 break;
133 }
134
135 snprintf(service, sizeof service, "host:%s", transport_type);
136 }
137 len = strlen(service);
138 snprintf(tmp, sizeof tmp, "%04x", len);
139
Dan Albertcc731cc2015-02-24 21:26:58 -0800140 if(!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, service, len)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800141 strcpy(__adb_error, "write failure during connection");
142 adb_close(fd);
143 return -1;
144 }
145 D("Switch transport in progress\n");
146
147 if(adb_status(fd)) {
148 adb_close(fd);
149 D("Switch transport failed\n");
150 return -1;
151 }
152 D("Switch transport success\n");
153 return 0;
154}
155
156int adb_status(int fd)
157{
158 unsigned char buf[5];
159 unsigned len;
160
Dan Albertcc731cc2015-02-24 21:26:58 -0800161 if(!ReadFdExactly(fd, buf, 4)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800162 strcpy(__adb_error, "protocol fault (no status)");
163 return -1;
164 }
165
166 if(!memcmp(buf, "OKAY", 4)) {
167 return 0;
168 }
169
170 if(memcmp(buf, "FAIL", 4)) {
171 sprintf(__adb_error,
172 "protocol fault (status %02x %02x %02x %02x?!)",
173 buf[0], buf[1], buf[2], buf[3]);
174 return -1;
175 }
176
Dan Albertcc731cc2015-02-24 21:26:58 -0800177 if(!ReadFdExactly(fd, buf, 4)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800178 strcpy(__adb_error, "protocol fault (status len)");
179 return -1;
180 }
181 buf[4] = 0;
182 len = strtoul((char*)buf, 0, 16);
183 if(len > 255) len = 255;
Dan Albertcc731cc2015-02-24 21:26:58 -0800184 if(!ReadFdExactly(fd, __adb_error, len)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800185 strcpy(__adb_error, "protocol fault (status read)");
186 return -1;
187 }
188 __adb_error[len] = 0;
189 return -1;
190}
191
192int _adb_connect(const char *service)
193{
194 char tmp[5];
195 int len;
196 int fd;
197
198 D("_adb_connect: %s\n", service);
199 len = strlen(service);
200 if((len < 1) || (len > 1024)) {
201 strcpy(__adb_error, "service name too long");
202 return -1;
203 }
204 snprintf(tmp, sizeof tmp, "%04x", len);
205
Matt Gumbeld7b33082012-11-14 10:16:17 -0800206 if (__adb_server_name)
207 fd = socket_network_client(__adb_server_name, __adb_server_port, SOCK_STREAM);
208 else
209 fd = socket_loopback_client(__adb_server_port, SOCK_STREAM);
210
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800211 if(fd < 0) {
212 strcpy(__adb_error, "cannot connect to daemon");
213 return -2;
214 }
215
216 if (memcmp(service,"host",4) != 0 && switch_socket_transport(fd)) {
217 return -1;
218 }
219
Dan Albertcc731cc2015-02-24 21:26:58 -0800220 if(!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, service, len)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800221 strcpy(__adb_error, "write failure during connection");
222 adb_close(fd);
223 return -1;
224 }
225
226 if(adb_status(fd)) {
227 adb_close(fd);
228 return -1;
229 }
230
JP Abgrall408fa572011-03-16 15:57:42 -0700231 D("_adb_connect: return fd %d\n", fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800232 return fd;
233}
234
235int adb_connect(const char *service)
236{
237 // first query the adb server's version
238 int fd = _adb_connect("host:version");
239
JP Abgrall408fa572011-03-16 15:57:42 -0700240 D("adb_connect: service %s\n", service);
Matt Gumbeld7b33082012-11-14 10:16:17 -0800241 if(fd == -2 && __adb_server_name) {
242 fprintf(stderr,"** Cannot start server on remote host\n");
243 return fd;
244 } else if(fd == -2) {
Stefan Hilzingerd0eacb82010-04-19 12:21:12 +0100245 fprintf(stdout,"* daemon not running. starting it now on port %d *\n",
246 __adb_server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800247 start_server:
Stefan Hilzingerd0eacb82010-04-19 12:21:12 +0100248 if(launch_server(__adb_server_port)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800249 fprintf(stderr,"* failed to start daemon *\n");
250 return -1;
251 } else {
252 fprintf(stdout,"* daemon started successfully *\n");
253 }
254 /* give the server some time to start properly and detect devices */
Xavier Ducroheta481d092009-05-21 17:47:43 -0700255 adb_sleep_ms(3000);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800256 // fall through to _adb_connect
257 } else {
258 // if server was running, check its version to make sure it is not out of date
259 char buf[100];
Nick Kralevich75e06452013-12-10 10:18:10 -0800260 size_t n;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800261 int version = ADB_SERVER_VERSION - 1;
262
263 // if we have a file descriptor, then parse version result
264 if(fd >= 0) {
Dan Albertcc731cc2015-02-24 21:26:58 -0800265 if(!ReadFdExactly(fd, buf, 4)) goto error;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800266
267 buf[4] = 0;
268 n = strtoul(buf, 0, 16);
Nick Kralevich75e06452013-12-10 10:18:10 -0800269 if(n > sizeof(buf)) goto error;
Dan Albertcc731cc2015-02-24 21:26:58 -0800270 if(!ReadFdExactly(fd, buf, n)) goto error;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800271 adb_close(fd);
272
273 if (sscanf(buf, "%04x", &version) != 1) goto error;
274 } else {
275 // if fd is -1, then check for "unknown host service",
276 // which would indicate a version of adb that does not support the version command
277 if (strcmp(__adb_error, "unknown host service") != 0)
278 return fd;
279 }
280
281 if(version != ADB_SERVER_VERSION) {
282 printf("adb server is out of date. killing...\n");
283 fd = _adb_connect("host:kill");
284 adb_close(fd);
285
286 /* XXX can we better detect its death? */
287 adb_sleep_ms(2000);
288 goto start_server;
289 }
290 }
291
292 // if the command is start-server, we are done.
293 if (!strcmp(service, "host:start-server"))
294 return 0;
295
296 fd = _adb_connect(service);
Brian Carlstrom93c91fa2013-10-18 13:58:48 -0700297 if(fd == -1) {
leozwangcbf02672014-08-15 09:51:27 -0700298 D("_adb_connect error: %s", __adb_error);
Brian Carlstrom93c91fa2013-10-18 13:58:48 -0700299 } else if(fd == -2) {
Matt Gumbeld7b33082012-11-14 10:16:17 -0800300 fprintf(stderr,"** daemon still not running\n");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800301 }
JP Abgrall408fa572011-03-16 15:57:42 -0700302 D("adb_connect: return fd %d\n", fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800303
304 return fd;
305error:
306 adb_close(fd);
307 return -1;
308}
309
310
311int adb_command(const char *service)
312{
313 int fd = adb_connect(service);
314 if(fd < 0) {
Doug Zongker8e49ae42014-06-26 15:35:36 -0700315 fprintf(stderr, "error: %s\n", adb_error());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800316 return -1;
317 }
318
319 if(adb_status(fd)) {
320 adb_close(fd);
321 return -1;
322 }
323
324 return 0;
325}
326
327char *adb_query(const char *service)
328{
329 char buf[5];
Dan Albertbac34742015-02-25 17:51:28 -0800330 unsigned long n;
331 char* tmp;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800332
333 D("adb_query: %s\n", service);
334 int fd = adb_connect(service);
335 if(fd < 0) {
336 fprintf(stderr,"error: %s\n", __adb_error);
337 return 0;
338 }
339
Dan Albertcc731cc2015-02-24 21:26:58 -0800340 if(!ReadFdExactly(fd, buf, 4)) goto oops;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800341
342 buf[4] = 0;
343 n = strtoul(buf, 0, 16);
Snild Dolkow2264e7c2014-01-30 10:08:38 +0100344 if(n >= 0xffff) {
345 strcpy(__adb_error, "reply is too long (>= 64kB)");
346 goto oops;
347 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800348
Dan Albertbac34742015-02-25 17:51:28 -0800349 tmp = reinterpret_cast<char*>(malloc(n + 1));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800350 if(tmp == 0) goto oops;
351
Dan Albertcc731cc2015-02-24 21:26:58 -0800352 if(!ReadFdExactly(fd, tmp, n) == 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800353 tmp[n] = 0;
354 adb_close(fd);
355 return tmp;
356 }
357 free(tmp);
358
359oops:
360 adb_close(fd);
361 return 0;
362}