adb_client.c revision 4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <errno.h>
5#include <limits.h>
6#include <stdarg.h>
7#include <zipfile/zipfile.h>
8#include <sys/types.h>
9#include <sys/stat.h>
10
11#include "sysdeps.h"
12
13#define  TRACE_TAG  TRACE_ADB
14#include "adb_client.h"
15
16static transport_type __adb_transport = kTransportAny;
17static const char* __adb_serial = NULL;
18
19void adb_set_transport(transport_type type, const char* serial)
20{
21    __adb_transport = type;
22    __adb_serial = serial;
23}
24
25int  adb_get_emulator_console_port(void)
26{
27    const char*   serial = __adb_serial;
28    int           port;
29
30    if (serial == NULL) {
31        /* if no specific device was specified, we need to look at */
32        /* the list of connected devices, and extract an emulator  */
33        /* name from it. two emulators is an error                 */
34        char*  tmp = adb_query("host:devices");
35        char*  p   = tmp;
36        if(!tmp) {
37            printf("no emulator connected\n");
38            return -1;
39        }
40        while (*p) {
41            char*  q = strchr(p, '\n');
42            if (q != NULL)
43                *q++ = 0;
44            else
45                q = p + strlen(p);
46
47            if (!memcmp(p, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1)) {
48                if (serial != NULL) {  /* more than one emulator listed */
49                    free(tmp);
50                    return -2;
51                }
52                serial = p;
53            }
54
55            p = q;
56        }
57        free(tmp);
58
59        if (serial == NULL)
60            return -1;  /* no emulator found */
61    }
62    else {
63        if (memcmp(serial, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1) != 0)
64            return -1;  /* not an emulator */
65    }
66
67    serial += sizeof(LOCAL_CLIENT_PREFIX)-1;
68    port    = strtol(serial, NULL, 10);
69    return port;
70}
71
72static char __adb_error[256] = { 0 };
73
74const char *adb_error(void)
75{
76    return __adb_error;
77}
78
79static int switch_socket_transport(int fd)
80{
81    char service[64];
82    char tmp[5];
83    int len;
84
85    if (__adb_serial)
86        snprintf(service, sizeof service, "host:transport:%s", __adb_serial);
87    else {
88        char* transport_type = "???";
89
90         switch (__adb_transport) {
91            case kTransportUsb:
92                transport_type = "transport-usb";
93                break;
94            case kTransportLocal:
95                transport_type = "transport-local";
96                break;
97            case kTransportAny:
98                transport_type = "transport-any";
99                break;
100            case kTransportHost:
101                // no switch necessary
102                return 0;
103                break;
104        }
105
106        snprintf(service, sizeof service, "host:%s", transport_type);
107    }
108    len = strlen(service);
109    snprintf(tmp, sizeof tmp, "%04x", len);
110
111    if(writex(fd, tmp, 4) || writex(fd, service, len)) {
112        strcpy(__adb_error, "write failure during connection");
113        adb_close(fd);
114        return -1;
115    }
116    D("Switch transport in progress\n");
117
118    if(adb_status(fd)) {
119        adb_close(fd);
120        D("Switch transport failed\n");
121        return -1;
122    }
123    D("Switch transport success\n");
124    return 0;
125}
126
127int adb_status(int fd)
128{
129    unsigned char buf[5];
130    unsigned len;
131
132    if(readx(fd, buf, 4)) {
133        strcpy(__adb_error, "protocol fault (no status)");
134        return -1;
135    }
136
137    if(!memcmp(buf, "OKAY", 4)) {
138        return 0;
139    }
140
141    if(memcmp(buf, "FAIL", 4)) {
142        sprintf(__adb_error,
143                "protocol fault (status %02x %02x %02x %02x?!)",
144                buf[0], buf[1], buf[2], buf[3]);
145        return -1;
146    }
147
148    if(readx(fd, buf, 4)) {
149        strcpy(__adb_error, "protocol fault (status len)");
150        return -1;
151    }
152    buf[4] = 0;
153    len = strtoul((char*)buf, 0, 16);
154    if(len > 255) len = 255;
155    if(readx(fd, __adb_error, len)) {
156        strcpy(__adb_error, "protocol fault (status read)");
157        return -1;
158    }
159    __adb_error[len] = 0;
160    return -1;
161}
162
163int _adb_connect(const char *service)
164{
165    char tmp[5];
166    int len;
167    int fd;
168
169    D("_adb_connect: %s\n", service);
170    len = strlen(service);
171    if((len < 1) || (len > 1024)) {
172        strcpy(__adb_error, "service name too long");
173        return -1;
174    }
175    snprintf(tmp, sizeof tmp, "%04x", len);
176
177    fd = socket_loopback_client(ADB_PORT, SOCK_STREAM);
178    if(fd < 0) {
179        strcpy(__adb_error, "cannot connect to daemon");
180        return -2;
181    }
182
183    if (memcmp(service,"host",4) != 0 && switch_socket_transport(fd)) {
184        return -1;
185    }
186
187    if(writex(fd, tmp, 4) || writex(fd, service, len)) {
188        strcpy(__adb_error, "write failure during connection");
189        adb_close(fd);
190        return -1;
191    }
192
193    if(adb_status(fd)) {
194        adb_close(fd);
195        return -1;
196    }
197
198    return fd;
199}
200
201int adb_connect(const char *service)
202{
203    // first query the adb server's version
204    int fd = _adb_connect("host:version");
205
206    if(fd == -2) {
207        fprintf(stdout,"* daemon not running. starting it now *\n");
208    start_server:
209        if(launch_server(0)) {
210            fprintf(stderr,"* failed to start daemon *\n");
211            return -1;
212        } else {
213            fprintf(stdout,"* daemon started successfully *\n");
214		}
215        /* give the server some time to start properly and detect devices */
216        adb_sleep_ms(2000);
217        // fall through to _adb_connect
218    } else {
219        // if server was running, check its version to make sure it is not out of date
220        char buf[100];
221        int n;
222        int version = ADB_SERVER_VERSION - 1;
223
224        // if we have a file descriptor, then parse version result
225        if(fd >= 0) {
226	        if(readx(fd, buf, 4)) goto error;
227
228		    buf[4] = 0;
229		    n = strtoul(buf, 0, 16);
230		    if(n > (int)sizeof(buf)) goto error;
231		    if(readx(fd, buf, n)) goto error;
232		    adb_close(fd);
233
234            if (sscanf(buf, "%04x", &version) != 1) goto error;
235        } else {
236            // if fd is -1, then check for "unknown host service",
237            // which would indicate a version of adb that does not support the version command
238            if (strcmp(__adb_error, "unknown host service") != 0)
239                return fd;
240        }
241
242        if(version != ADB_SERVER_VERSION) {
243	        printf("adb server is out of date.  killing...\n");
244	        fd = _adb_connect("host:kill");
245	        adb_close(fd);
246
247                /* XXX can we better detect its death? */
248	        adb_sleep_ms(2000);
249            goto start_server;
250	    }
251    }
252
253    // if the command is start-server, we are done.
254    if (!strcmp(service, "host:start-server"))
255        return 0;
256
257    fd = _adb_connect(service);
258    if(fd == -2) {
259        fprintf(stderr,"** daemon still not running");
260    }
261
262    return fd;
263error:
264    adb_close(fd);
265    return -1;
266}
267
268
269int adb_command(const char *service)
270{
271    int fd = adb_connect(service);
272    if(fd < 0) {
273        return -1;
274    }
275
276    if(adb_status(fd)) {
277        adb_close(fd);
278        return -1;
279    }
280
281    return 0;
282}
283
284char *adb_query(const char *service)
285{
286    char buf[5];
287    unsigned n;
288    char *tmp;
289
290    D("adb_query: %s\n", service);
291    int fd = adb_connect(service);
292    if(fd < 0) {
293        fprintf(stderr,"error: %s\n", __adb_error);
294        return 0;
295    }
296
297    if(readx(fd, buf, 4)) goto oops;
298
299    buf[4] = 0;
300    n = strtoul(buf, 0, 16);
301    if(n > 1024) goto oops;
302
303    tmp = malloc(n + 1);
304    if(tmp == 0) goto oops;
305
306    if(readx(fd, tmp, n) == 0) {
307        tmp[n] = 0;
308        adb_close(fd);
309        return tmp;
310    }
311    free(tmp);
312
313oops:
314    adb_close(fd);
315    return 0;
316}
317
318
319