Home | History | Annotate | Download | only in adb
      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 
     22 void adb_set_transport(transport_type type, const char* serial)
     23 {
     24     __adb_transport = type;
     25     __adb_serial = serial;
     26 }
     27 
     28 void adb_set_tcp_specifics(int server_port)
     29 {
     30     __adb_server_port = server_port;
     31 }
     32 
     33 void adb_set_tcp_name(const char* hostname)
     34 {
     35     __adb_server_name = hostname;
     36 }
     37 
     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 
     87 const char *adb_error(void)
     88 {
     89     return __adb_error;
     90 }
     91 
     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 
    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 
    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 
    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 
    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 
    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