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