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