adb_client.cpp revision bac3474a8256cb32a29e8d46f78cad95a5502692
1/*
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
17#include <errno.h>
18#include <limits.h>
19#include <stdarg.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <sys/stat.h>
24#include <sys/types.h>
25
26#include "sysdeps.h"
27
28#define  TRACE_TAG  TRACE_ADB
29#include "adb_client.h"
30#include "adb_io.h"
31#include "zipfile/zipfile.h"
32
33static transport_type __adb_transport = kTransportAny;
34static const char* __adb_serial = NULL;
35
36static int __adb_server_port = DEFAULT_ADB_PORT;
37static const char* __adb_server_name = NULL;
38
39void adb_set_transport(transport_type type, const char* serial)
40{
41    __adb_transport = type;
42    __adb_serial = serial;
43}
44
45void adb_set_tcp_specifics(int server_port)
46{
47    __adb_server_port = server_port;
48}
49
50void adb_set_tcp_name(const char* hostname)
51{
52    __adb_server_name = hostname;
53}
54
55int  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 {
118        const char* transport_type = "???";
119
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
141    if(!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, service, len)) {
142        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
162    if(!ReadFdExactly(fd, buf, 4)) {
163        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
178    if(!ReadFdExactly(fd, buf, 4)) {
179        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;
185    if(!ReadFdExactly(fd, __adb_error, len)) {
186        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
207    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
212    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
221    if(!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, service, len)) {
222        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
232    D("_adb_connect: return fd %d\n", fd);
233    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
241    D("adb_connect: service %s\n", service);
242    if(fd == -2 && __adb_server_name) {
243        fprintf(stderr,"** Cannot start server on remote host\n");
244        return fd;
245    } else if(fd == -2) {
246        fprintf(stdout,"* daemon not running. starting it now on port %d *\n",
247                __adb_server_port);
248    start_server:
249        if(launch_server(__adb_server_port)) {
250            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 */
256        adb_sleep_ms(3000);
257        // 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];
261        size_t n;
262        int version = ADB_SERVER_VERSION - 1;
263
264        // if we have a file descriptor, then parse version result
265        if(fd >= 0) {
266            if(!ReadFdExactly(fd, buf, 4)) goto error;
267
268            buf[4] = 0;
269            n = strtoul(buf, 0, 16);
270            if(n > sizeof(buf)) goto error;
271            if(!ReadFdExactly(fd, buf, n)) goto error;
272            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);
298    if(fd == -1) {
299        D("_adb_connect error: %s", __adb_error);
300    } else if(fd == -2) {
301        fprintf(stderr,"** daemon still not running\n");
302    }
303    D("adb_connect: return fd %d\n", fd);
304
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) {
316        fprintf(stderr, "error: %s\n", adb_error());
317        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];
331    unsigned long n;
332    char* tmp;
333
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
341    if(!ReadFdExactly(fd, buf, 4)) goto oops;
342
343    buf[4] = 0;
344    n = strtoul(buf, 0, 16);
345    if(n >= 0xffff) {
346        strcpy(__adb_error, "reply is too long (>= 64kB)");
347        goto oops;
348    }
349
350    tmp = reinterpret_cast<char*>(malloc(n + 1));
351    if(tmp == 0) goto oops;
352
353    if(!ReadFdExactly(fd, tmp, n) == 0) {
354        tmp[n] = 0;
355        adb_close(fd);
356        return tmp;
357    }
358    free(tmp);
359
360oops:
361    adb_close(fd);
362    return 0;
363}
364