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 21 void adb_set_transport(transport_type type, const char* serial) 22 { 23 __adb_transport = type; 24 __adb_serial = serial; 25 } 26 27 void adb_set_tcp_specifics(int server_port) 28 { 29 __adb_server_port = server_port; 30 } 31 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 81 const char *adb_error(void) 82 { 83 return __adb_error; 84 } 85 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 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 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 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 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 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