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