• 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 
adb_set_transport(transport_type type,const char * serial)19 void adb_set_transport(transport_type type, const char* serial)
20 {
21     __adb_transport = type;
22     __adb_serial = serial;
23 }
24 
adb_get_emulator_console_port(void)25 int  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 
72 static char __adb_error[256] = { 0 };
73 
adb_error(void)74 const char *adb_error(void)
75 {
76     return __adb_error;
77 }
78 
switch_socket_transport(int fd)79 static 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 
adb_status(int fd)127 int 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 
_adb_connect(const char * service)163 int _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 
adb_connect(const char * service)201 int 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(3000);
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;
263 error:
264     adb_close(fd);
265     return -1;
266 }
267 
268 
adb_command(const char * service)269 int 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 
adb_query(const char * service)284 char *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 
313 oops:
314     adb_close(fd);
315     return 0;
316 }
317 
318 
319