adb.c revision 9270a20a801403c9f60d6a701b39eae70d380403
19270a20a801403c9f60d6a701b39eae70d380403Doug Zongker/*
29270a20a801403c9f60d6a701b39eae70d380403Doug Zongker * Copyright (C) 2007 The Android Open Source Project
39270a20a801403c9f60d6a701b39eae70d380403Doug Zongker *
49270a20a801403c9f60d6a701b39eae70d380403Doug Zongker * Licensed under the Apache License, Version 2.0 (the "License");
59270a20a801403c9f60d6a701b39eae70d380403Doug Zongker * you may not use this file except in compliance with the License.
69270a20a801403c9f60d6a701b39eae70d380403Doug Zongker * You may obtain a copy of the License at
79270a20a801403c9f60d6a701b39eae70d380403Doug Zongker *
89270a20a801403c9f60d6a701b39eae70d380403Doug Zongker *      http://www.apache.org/licenses/LICENSE-2.0
99270a20a801403c9f60d6a701b39eae70d380403Doug Zongker *
109270a20a801403c9f60d6a701b39eae70d380403Doug Zongker * Unless required by applicable law or agreed to in writing, software
119270a20a801403c9f60d6a701b39eae70d380403Doug Zongker * distributed under the License is distributed on an "AS IS" BASIS,
129270a20a801403c9f60d6a701b39eae70d380403Doug Zongker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139270a20a801403c9f60d6a701b39eae70d380403Doug Zongker * See the License for the specific language governing permissions and
149270a20a801403c9f60d6a701b39eae70d380403Doug Zongker * limitations under the License.
159270a20a801403c9f60d6a701b39eae70d380403Doug Zongker */
169270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
179270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#define  TRACE_TAG   TRACE_ADB
189270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
199270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#include <stdio.h>
209270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#include <stdlib.h>
219270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#include <ctype.h>
229270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#include <stdarg.h>
239270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#include <errno.h>
249270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#include <string.h>
259270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#include <time.h>
269270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#include <sys/time.h>
279270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
289270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#include "sysdeps.h"
299270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#include "adb.h"
309270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
319270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#if !ADB_HOST
329270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#include <private/android_filesystem_config.h>
339270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#include <linux/capability.h>
349270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#include <linux/prctl.h>
359270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#else
369270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#include "usb_vendors.h"
379270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#endif
389270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
399270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#if ADB_TRACE
409270a20a801403c9f60d6a701b39eae70d380403Doug ZongkerADB_MUTEX_DEFINE( D_lock );
419270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#endif
429270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
439270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerint HOST = 0;
449270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
459270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerstatic const char *adb_device_banner = "sideload";
469270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
479270a20a801403c9f60d6a701b39eae70d380403Doug Zongkervoid fatal(const char *fmt, ...)
489270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
499270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    va_list ap;
509270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    va_start(ap, fmt);
519270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fprintf(stderr, "error: ");
529270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    vfprintf(stderr, fmt, ap);
539270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fprintf(stderr, "\n");
549270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    va_end(ap);
559270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    exit(-1);
569270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
579270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
589270a20a801403c9f60d6a701b39eae70d380403Doug Zongkervoid fatal_errno(const char *fmt, ...)
599270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
609270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    va_list ap;
619270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    va_start(ap, fmt);
629270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fprintf(stderr, "error: %s: ", strerror(errno));
639270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    vfprintf(stderr, fmt, ap);
649270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fprintf(stderr, "\n");
659270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    va_end(ap);
669270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    exit(-1);
679270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
689270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
699270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerint   adb_trace_mask;
709270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
719270a20a801403c9f60d6a701b39eae70d380403Doug Zongker/* read a comma/space/colum/semi-column separated list of tags
729270a20a801403c9f60d6a701b39eae70d380403Doug Zongker * from the ADB_TRACE environment variable and build the trace
739270a20a801403c9f60d6a701b39eae70d380403Doug Zongker * mask from it. note that '1' and 'all' are special cases to
749270a20a801403c9f60d6a701b39eae70d380403Doug Zongker * enable all tracing
759270a20a801403c9f60d6a701b39eae70d380403Doug Zongker */
769270a20a801403c9f60d6a701b39eae70d380403Doug Zongkervoid  adb_trace_init(void)
779270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
789270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    const char*  p = getenv("ADB_TRACE");
799270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    const char*  q;
809270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
819270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    static const struct {
829270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        const char*  tag;
839270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        int           flag;
849270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    } tags[] = {
859270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        { "1", 0 },
869270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        { "all", 0 },
879270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        { "adb", TRACE_ADB },
889270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        { "sockets", TRACE_SOCKETS },
899270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        { "packets", TRACE_PACKETS },
909270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        { "rwx", TRACE_RWX },
919270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        { "usb", TRACE_USB },
929270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        { "sync", TRACE_SYNC },
939270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        { "sysdeps", TRACE_SYSDEPS },
949270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        { "transport", TRACE_TRANSPORT },
959270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        { "jdwp", TRACE_JDWP },
969270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        { "services", TRACE_SERVICES },
979270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        { NULL, 0 }
989270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    };
999270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
1009270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (p == NULL)
1019270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            return;
1029270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
1039270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    /* use a comma/column/semi-colum/space separated list */
1049270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    while (*p) {
1059270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        int  len, tagn;
1069270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
1079270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        q = strpbrk(p, " ,:;");
1089270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if (q == NULL) {
1099270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            q = p + strlen(p);
1109270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
1119270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        len = q - p;
1129270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
1139270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        for (tagn = 0; tags[tagn].tag != NULL; tagn++)
1149270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        {
1159270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            int  taglen = strlen(tags[tagn].tag);
1169270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
1179270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            if (len == taglen && !memcmp(tags[tagn].tag, p, len) )
1189270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            {
1199270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                int  flag = tags[tagn].flag;
1209270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                if (flag == 0) {
1219270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                    adb_trace_mask = ~0;
1229270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                    return;
1239270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                }
1249270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                adb_trace_mask |= (1 << flag);
1259270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                break;
1269270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            }
1279270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
1289270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        p = q;
1299270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if (*p)
1309270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            p++;
1319270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
1329270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
1339270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
1349270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
1359270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerapacket *get_apacket(void)
1369270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
1379270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    apacket *p = malloc(sizeof(apacket));
1389270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(p == 0) fatal("failed to allocate an apacket");
1399270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    memset(p, 0, sizeof(apacket) - MAX_PAYLOAD);
1409270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    return p;
1419270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
1429270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
1439270a20a801403c9f60d6a701b39eae70d380403Doug Zongkervoid put_apacket(apacket *p)
1449270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
1459270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    free(p);
1469270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
1479270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
1489270a20a801403c9f60d6a701b39eae70d380403Doug Zongkervoid handle_online(void)
1499270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
1509270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    D("adb: online\n");
1519270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
1529270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
1539270a20a801403c9f60d6a701b39eae70d380403Doug Zongkervoid handle_offline(atransport *t)
1549270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
1559270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    D("adb: offline\n");
1569270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    //Close the associated usb
1579270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    run_transport_disconnects(t);
1589270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
1599270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
1609270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#if TRACE_PACKETS
1619270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#define DUMPMAX 32
1629270a20a801403c9f60d6a701b39eae70d380403Doug Zongkervoid print_packet(const char *label, apacket *p)
1639270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
1649270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    char *tag;
1659270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    char *x;
1669270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    unsigned count;
1679270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
1689270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    switch(p->msg.command){
1699270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    case A_SYNC: tag = "SYNC"; break;
1709270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    case A_CNXN: tag = "CNXN" ; break;
1719270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    case A_OPEN: tag = "OPEN"; break;
1729270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    case A_OKAY: tag = "OKAY"; break;
1739270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    case A_CLSE: tag = "CLSE"; break;
1749270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    case A_WRTE: tag = "WRTE"; break;
1759270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    default: tag = "????"; break;
1769270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
1779270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
1789270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fprintf(stderr, "%s: %s %08x %08x %04x \"",
1799270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length);
1809270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    count = p->msg.data_length;
1819270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    x = (char*) p->data;
1829270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(count > DUMPMAX) {
1839270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        count = DUMPMAX;
1849270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        tag = "\n";
1859270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    } else {
1869270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        tag = "\"\n";
1879270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
1889270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    while(count-- > 0){
1899270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if((*x >= ' ') && (*x < 127)) {
1909270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            fputc(*x, stderr);
1919270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        } else {
1929270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            fputc('.', stderr);
1939270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
1949270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        x++;
1959270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
1969270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fprintf(stderr, tag);
1979270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
1989270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#endif
1999270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
2009270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerstatic void send_ready(unsigned local, unsigned remote, atransport *t)
2019270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
2029270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    D("Calling send_ready \n");
2039270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    apacket *p = get_apacket();
2049270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    p->msg.command = A_OKAY;
2059270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    p->msg.arg0 = local;
2069270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    p->msg.arg1 = remote;
2079270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    send_packet(p, t);
2089270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
2099270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
2109270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerstatic void send_close(unsigned local, unsigned remote, atransport *t)
2119270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
2129270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    D("Calling send_close \n");
2139270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    apacket *p = get_apacket();
2149270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    p->msg.command = A_CLSE;
2159270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    p->msg.arg0 = local;
2169270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    p->msg.arg1 = remote;
2179270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    send_packet(p, t);
2189270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
2199270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
2209270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerstatic void send_connect(atransport *t)
2219270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
2229270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    D("Calling send_connect \n");
2239270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    apacket *cp = get_apacket();
2249270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    cp->msg.command = A_CNXN;
2259270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    cp->msg.arg0 = A_VERSION;
2269270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    cp->msg.arg1 = MAX_PAYLOAD;
2279270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    snprintf((char*) cp->data, sizeof cp->data, "%s::",
2289270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            HOST ? "host" : adb_device_banner);
2299270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    cp->msg.data_length = strlen((char*) cp->data) + 1;
2309270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    send_packet(cp, t);
2319270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#if ADB_HOST
2329270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        /* XXX why sleep here? */
2339270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // allow the device some time to respond to the connect message
2349270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    adb_sleep_ms(1000);
2359270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#endif
2369270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
2379270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
2389270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerstatic char *connection_state_name(atransport *t)
2399270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
2409270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (t == NULL) {
2419270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return "unknown";
2429270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
2439270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
2449270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    switch(t->connection_state) {
2459270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    case CS_BOOTLOADER:
2469270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return "bootloader";
2479270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    case CS_DEVICE:
2489270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return "device";
2499270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    case CS_OFFLINE:
2509270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return "offline";
2519270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    default:
2529270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return "unknown";
2539270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
2549270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
2559270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
2569270a20a801403c9f60d6a701b39eae70d380403Doug Zongkervoid parse_banner(char *banner, atransport *t)
2579270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
2589270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    char *type, *product, *end;
2599270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
2609270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    D("parse_banner: %s\n", banner);
2619270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    type = banner;
2629270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    product = strchr(type, ':');
2639270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(product) {
2649270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        *product++ = 0;
2659270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    } else {
2669270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        product = "";
2679270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
2689270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
2699270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        /* remove trailing ':' */
2709270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    end = strchr(product, ':');
2719270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(end) *end = 0;
2729270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
2739270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        /* save product name in device structure */
2749270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (t->product == NULL) {
2759270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        t->product = strdup(product);
2769270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    } else if (strcmp(product, t->product) != 0) {
2779270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        free(t->product);
2789270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        t->product = strdup(product);
2799270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
2809270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
2819270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(!strcmp(type, "bootloader")){
2829270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        D("setting connection_state to CS_BOOTLOADER\n");
2839270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        t->connection_state = CS_BOOTLOADER;
2849270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        update_transports();
2859270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return;
2869270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
2879270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
2889270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(!strcmp(type, "device")) {
2899270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        D("setting connection_state to CS_DEVICE\n");
2909270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        t->connection_state = CS_DEVICE;
2919270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        update_transports();
2929270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return;
2939270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
2949270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
2959270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(!strcmp(type, "recovery")) {
2969270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        D("setting connection_state to CS_RECOVERY\n");
2979270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        t->connection_state = CS_RECOVERY;
2989270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        update_transports();
2999270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return;
3009270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
3019270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
3029270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(!strcmp(type, "sideload")) {
3039270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        D("setting connection_state to CS_SIDELOAD\n");
3049270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        t->connection_state = CS_SIDELOAD;
3059270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        update_transports();
3069270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return;
3079270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
3089270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
3099270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    t->connection_state = CS_HOST;
3109270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
3119270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
3129270a20a801403c9f60d6a701b39eae70d380403Doug Zongkervoid handle_packet(apacket *p, atransport *t)
3139270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
3149270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    asocket *s;
3159270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
3169270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    D("handle_packet() %c%c%c%c\n", ((char*) (&(p->msg.command)))[0],
3179270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            ((char*) (&(p->msg.command)))[1],
3189270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            ((char*) (&(p->msg.command)))[2],
3199270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            ((char*) (&(p->msg.command)))[3]);
3209270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    print_packet("recv", p);
3219270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
3229270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    switch(p->msg.command){
3239270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    case A_SYNC:
3249270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if(p->msg.arg0){
3259270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            send_packet(p, t);
3269270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            if(HOST) send_connect(t);
3279270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        } else {
3289270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            t->connection_state = CS_OFFLINE;
3299270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            handle_offline(t);
3309270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            send_packet(p, t);
3319270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
3329270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return;
3339270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
3349270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
3359270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            /* XXX verify version, etc */
3369270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if(t->connection_state != CS_OFFLINE) {
3379270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            t->connection_state = CS_OFFLINE;
3389270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            handle_offline(t);
3399270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
3409270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        parse_banner((char*) p->data, t);
3419270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        handle_online();
3429270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if(!HOST) send_connect(t);
3439270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        break;
3449270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
3459270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    case A_OPEN: /* OPEN(local-id, 0, "destination") */
3469270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if(t->connection_state != CS_OFFLINE) {
3479270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            char *name = (char*) p->data;
3489270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
3499270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            s = create_local_service_socket(name);
3509270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            if(s == 0) {
3519270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                send_close(0, p->msg.arg0, t);
3529270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            } else {
3539270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                s->peer = create_remote_socket(p->msg.arg0, t);
3549270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                s->peer->peer = s;
3559270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                send_ready(s->id, s->peer->id, t);
3569270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                s->ready(s);
3579270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            }
3589270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
3599270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        break;
3609270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
3619270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    case A_OKAY: /* READY(local-id, remote-id, "") */
3629270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if(t->connection_state != CS_OFFLINE) {
3639270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            if((s = find_local_socket(p->msg.arg1))) {
3649270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                if(s->peer == 0) {
3659270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                    s->peer = create_remote_socket(p->msg.arg0, t);
3669270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                    s->peer->peer = s;
3679270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                }
3689270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                s->ready(s);
3699270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            }
3709270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
3719270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        break;
3729270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
3739270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    case A_CLSE: /* CLOSE(local-id, remote-id, "") */
3749270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if(t->connection_state != CS_OFFLINE) {
3759270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            if((s = find_local_socket(p->msg.arg1))) {
3769270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                s->close(s);
3779270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            }
3789270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
3799270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        break;
3809270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
3819270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    case A_WRTE:
3829270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if(t->connection_state != CS_OFFLINE) {
3839270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            if((s = find_local_socket(p->msg.arg1))) {
3849270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                unsigned rid = p->msg.arg0;
3859270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                p->len = p->msg.data_length;
3869270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
3879270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                if(s->enqueue(s, p) == 0) {
3889270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                    D("Enqueue the socket\n");
3899270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                    send_ready(s->id, rid, t);
3909270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                }
3919270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                return;
3929270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            }
3939270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
3949270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        break;
3959270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
3969270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    default:
3979270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        printf("handle_packet: what is %08x?!\n", p->msg.command);
3989270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
3999270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4009270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    put_apacket(p);
4019270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
4029270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4039270a20a801403c9f60d6a701b39eae70d380403Doug Zongkeralistener listener_list = {
4049270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    .next = &listener_list,
4059270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    .prev = &listener_list,
4069270a20a801403c9f60d6a701b39eae70d380403Doug Zongker};
4079270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4089270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerstatic void ss_listener_event_func(int _fd, unsigned ev, void *_l)
4099270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
4109270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    asocket *s;
4119270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4129270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(ev & FDE_READ) {
4139270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        struct sockaddr addr;
4149270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        socklen_t alen;
4159270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        int fd;
4169270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4179270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        alen = sizeof(addr);
4189270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        fd = adb_socket_accept(_fd, &addr, &alen);
4199270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if(fd < 0) return;
4209270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4219270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        adb_socket_setbufsize(fd, CHUNK_SIZE);
4229270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4239270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        s = create_local_socket(fd);
4249270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if(s) {
4259270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            connect_to_smartsocket(s);
4269270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            return;
4279270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
4289270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4299270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        adb_close(fd);
4309270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
4319270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
4329270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4339270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerstatic void listener_event_func(int _fd, unsigned ev, void *_l)
4349270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
4359270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    alistener *l = _l;
4369270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    asocket *s;
4379270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4389270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(ev & FDE_READ) {
4399270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        struct sockaddr addr;
4409270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        socklen_t alen;
4419270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        int fd;
4429270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4439270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        alen = sizeof(addr);
4449270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        fd = adb_socket_accept(_fd, &addr, &alen);
4459270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if(fd < 0) return;
4469270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4479270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        s = create_local_socket(fd);
4489270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if(s) {
4499270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            s->transport = l->transport;
4509270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            connect_to_remote(s, l->connect_to);
4519270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            return;
4529270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
4539270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4549270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        adb_close(fd);
4559270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
4569270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
4579270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4589270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerstatic void  free_listener(alistener*  l)
4599270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
4609270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (l->next) {
4619270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        l->next->prev = l->prev;
4629270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        l->prev->next = l->next;
4639270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        l->next = l->prev = l;
4649270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
4659270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4669270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // closes the corresponding fd
4679270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fdevent_remove(&l->fde);
4689270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4699270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (l->local_name)
4709270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        free((char*)l->local_name);
4719270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4729270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (l->connect_to)
4739270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        free((char*)l->connect_to);
4749270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4759270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (l->transport) {
4769270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        remove_transport_disconnect(l->transport, &l->disconnect);
4779270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
4789270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    free(l);
4799270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
4809270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4819270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerstatic void listener_disconnect(void*  _l, atransport*  t)
4829270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
4839270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    alistener*  l = _l;
4849270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4859270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    free_listener(l);
4869270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
4879270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4889270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerint local_name_to_fd(const char *name)
4899270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
4909270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    int port;
4919270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
4929270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(!strncmp("tcp:", name, 4)){
4939270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        int  ret;
4949270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        port = atoi(name + 4);
4959270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        ret = socket_loopback_server(port, SOCK_STREAM);
4969270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return ret;
4979270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
4989270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#ifndef HAVE_WIN32_IPC  /* no Unix-domain sockets on Win32 */
4999270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // It's non-sensical to support the "reserved" space on the adb host side
5009270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(!strncmp(name, "local:", 6)) {
5019270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return socket_local_server(name + 6,
5029270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
5039270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    } else if(!strncmp(name, "localabstract:", 14)) {
5049270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return socket_local_server(name + 14,
5059270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
5069270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    } else if(!strncmp(name, "localfilesystem:", 16)) {
5079270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return socket_local_server(name + 16,
5089270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
5099270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
5109270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
5119270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#endif
5129270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    printf("unknown local portname '%s'\n", name);
5139270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    return -1;
5149270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
5159270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
5169270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerstatic int remove_listener(const char *local_name, const char *connect_to, atransport* transport)
5179270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
5189270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    alistener *l;
5199270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
5209270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    for (l = listener_list.next; l != &listener_list; l = l->next) {
5219270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if (!strcmp(local_name, l->local_name) &&
5229270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            !strcmp(connect_to, l->connect_to) &&
5239270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            l->transport && l->transport == transport) {
5249270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
5259270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            listener_disconnect(l, transport);
5269270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            return 0;
5279270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
5289270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
5299270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
5309270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    return -1;
5319270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
5329270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
5339270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerstatic int install_listener(const char *local_name, const char *connect_to, atransport* transport)
5349270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
5359270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    alistener *l;
5369270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
5379270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    //printf("install_listener('%s','%s')\n", local_name, connect_to);
5389270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
5399270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    for(l = listener_list.next; l != &listener_list; l = l->next){
5409270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if(strcmp(local_name, l->local_name) == 0) {
5419270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            char *cto;
5429270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
5439270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                /* can't repurpose a smartsocket */
5449270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            if(l->connect_to[0] == '*') {
5459270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                return -1;
5469270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            }
5479270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
5489270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            cto = strdup(connect_to);
5499270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            if(cto == 0) {
5509270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                return -1;
5519270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            }
5529270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
5539270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            //printf("rebinding '%s' to '%s'\n", local_name, connect_to);
5549270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            free((void*) l->connect_to);
5559270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            l->connect_to = cto;
5569270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            if (l->transport != transport) {
5579270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                remove_transport_disconnect(l->transport, &l->disconnect);
5589270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                l->transport = transport;
5599270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                add_transport_disconnect(l->transport, &l->disconnect);
5609270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            }
5619270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            return 0;
5629270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
5639270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
5649270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
5659270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if((l = calloc(1, sizeof(alistener))) == 0) goto nomem;
5669270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if((l->local_name = strdup(local_name)) == 0) goto nomem;
5679270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if((l->connect_to = strdup(connect_to)) == 0) goto nomem;
5689270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
5699270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
5709270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    l->fd = local_name_to_fd(local_name);
5719270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(l->fd < 0) {
5729270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        free((void*) l->local_name);
5739270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        free((void*) l->connect_to);
5749270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        free(l);
5759270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        printf("cannot bind '%s'\n", local_name);
5769270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return -2;
5779270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
5789270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
5799270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    close_on_exec(l->fd);
5809270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(!strcmp(l->connect_to, "*smartsocket*")) {
5819270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        fdevent_install(&l->fde, l->fd, ss_listener_event_func, l);
5829270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    } else {
5839270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        fdevent_install(&l->fde, l->fd, listener_event_func, l);
5849270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
5859270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fdevent_set(&l->fde, FDE_READ);
5869270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
5879270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    l->next = &listener_list;
5889270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    l->prev = listener_list.prev;
5899270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    l->next->prev = l;
5909270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    l->prev->next = l;
5919270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    l->transport = transport;
5929270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
5939270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (transport) {
5949270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        l->disconnect.opaque = l;
5959270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        l->disconnect.func   = listener_disconnect;
5969270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        add_transport_disconnect(transport, &l->disconnect);
5979270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
5989270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    return 0;
5999270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
6009270a20a801403c9f60d6a701b39eae70d380403Doug Zongkernomem:
6019270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fatal("cannot allocate listener");
6029270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    return 0;
6039270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
6049270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
6059270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#ifdef HAVE_WIN32_PROC
6069270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerstatic BOOL WINAPI ctrlc_handler(DWORD type)
6079270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
6089270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    exit(STATUS_CONTROL_C_EXIT);
6099270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    return TRUE;
6109270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
6119270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#endif
6129270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
6139270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerstatic void adb_cleanup(void)
6149270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
6159270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    usb_cleanup();
6169270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
6179270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
6189270a20a801403c9f60d6a701b39eae70d380403Doug Zongkervoid start_logging(void)
6199270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
6209270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#ifdef HAVE_WIN32_PROC
6219270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    char    temp[ MAX_PATH ];
6229270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    FILE*   fnul;
6239270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    FILE*   flog;
6249270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
6259270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    GetTempPath( sizeof(temp) - 8, temp );
6269270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    strcat( temp, "adb.log" );
6279270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
6289270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    /* Win32 specific redirections */
6299270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fnul = fopen( "NUL", "rt" );
6309270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (fnul != NULL)
6319270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        stdin[0] = fnul[0];
6329270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
6339270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    flog = fopen( temp, "at" );
6349270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (flog == NULL)
6359270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        flog = fnul;
6369270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
6379270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    setvbuf( flog, NULL, _IONBF, 0 );
6389270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
6399270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    stdout[0] = flog[0];
6409270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    stderr[0] = flog[0];
6419270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
6429270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#else
6439270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    int fd;
6449270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
6459270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fd = unix_open("/dev/null", O_RDONLY);
6469270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    dup2(fd, 0);
6479270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    adb_close(fd);
6489270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
6499270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fd = unix_open("/tmp/adb.log", O_WRONLY | O_CREAT | O_APPEND, 0640);
6509270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(fd < 0) {
6519270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        fd = unix_open("/dev/null", O_WRONLY);
6529270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
6539270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    dup2(fd, 1);
6549270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    dup2(fd, 2);
6559270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    adb_close(fd);
6569270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
6579270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#endif
6589270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
6599270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
6609270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#if !ADB_HOST
6619270a20a801403c9f60d6a701b39eae70d380403Doug Zongkervoid start_device_log(void)
6629270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
6639270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    int fd;
6649270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    char    path[PATH_MAX];
6659270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    struct tm now;
6669270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    time_t t;
6679270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    char value[PROPERTY_VALUE_MAX];
6689270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
6699270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // read the trace mask from persistent property persist.adb.trace_mask
6709270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // give up if the property is not set or cannot be parsed
6719270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    property_get("persist.adb.trace_mask", value, "");
6729270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (sscanf(value, "%x", &adb_trace_mask) != 1)
6739270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return;
6749270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
6759270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    adb_mkdir("/data/adb", 0775);
6769270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    tzset();
6779270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    time(&t);
6789270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    localtime_r(&t, &now);
6799270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    strftime(path, sizeof(path),
6809270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                "/data/adb/adb-%Y-%m-%d-%H-%M-%S.txt",
6819270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                &now);
6829270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fd = unix_open(path, O_WRONLY | O_CREAT | O_TRUNC, 0640);
6839270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (fd < 0)
6849270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return;
6859270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
6869270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // redirect stdout and stderr to the log file
6879270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    dup2(fd, 1);
6889270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    dup2(fd, 2);
6899270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
6909270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    adb_close(fd);
6919270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
6929270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fd = unix_open("/dev/null", O_RDONLY);
6939270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    dup2(fd, 0);
6949270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    adb_close(fd);
6959270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
6969270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#endif
6979270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
6989270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#if ADB_HOST
6999270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerint launch_server(int server_port)
7009270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
7019270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#ifdef HAVE_WIN32_PROC
7029270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    /* we need to start the server in the background                    */
7039270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    /* we create a PIPE that will be used to wait for the server's "OK" */
7049270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    /* message since the pipe handles must be inheritable, we use a     */
7059270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    /* security attribute                                               */
7069270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    HANDLE                pipe_read, pipe_write;
7079270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    SECURITY_ATTRIBUTES   sa;
7089270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    STARTUPINFO           startup;
7099270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    PROCESS_INFORMATION   pinfo;
7109270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    char                  program_path[ MAX_PATH ];
7119270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    int                   ret;
7129270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
7139270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    sa.nLength = sizeof(sa);
7149270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    sa.lpSecurityDescriptor = NULL;
7159270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    sa.bInheritHandle = TRUE;
7169270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
7179270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    /* create pipe, and ensure its read handle isn't inheritable */
7189270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
7199270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (!ret) {
7209270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );
7219270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return -1;
7229270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
7239270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
7249270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );
7259270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
7269270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    ZeroMemory( &startup, sizeof(startup) );
7279270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    startup.cb = sizeof(startup);
7289270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    startup.hStdInput  = GetStdHandle( STD_INPUT_HANDLE );
7299270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    startup.hStdOutput = pipe_write;
7309270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    startup.hStdError  = GetStdHandle( STD_ERROR_HANDLE );
7319270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    startup.dwFlags    = STARTF_USESTDHANDLES;
7329270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
7339270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    ZeroMemory( &pinfo, sizeof(pinfo) );
7349270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
7359270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    /* get path of current program */
7369270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    GetModuleFileName( NULL, program_path, sizeof(program_path) );
7379270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
7389270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    ret = CreateProcess(
7399270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            program_path,                              /* program path  */
7409270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            "adb fork-server server",
7419270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                                    /* the fork-server argument will set the
7429270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                                       debug = 2 in the child           */
7439270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            NULL,                   /* process handle is not inheritable */
7449270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            NULL,                    /* thread handle is not inheritable */
7459270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            TRUE,                          /* yes, inherit some handles */
7469270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            DETACHED_PROCESS, /* the new process doesn't have a console */
7479270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            NULL,                     /* use parent's environment block */
7489270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            NULL,                    /* use parent's starting directory */
7499270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            &startup,                 /* startup info, i.e. std handles */
7509270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            &pinfo );
7519270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
7529270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    CloseHandle( pipe_write );
7539270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
7549270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (!ret) {
7559270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );
7569270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        CloseHandle( pipe_read );
7579270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return -1;
7589270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
7599270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
7609270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    CloseHandle( pinfo.hProcess );
7619270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    CloseHandle( pinfo.hThread );
7629270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
7639270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    /* wait for the "OK\n" message */
7649270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    {
7659270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        char  temp[3];
7669270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        DWORD  count;
7679270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
7689270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        ret = ReadFile( pipe_read, temp, 3, &count, NULL );
7699270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        CloseHandle( pipe_read );
7709270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if ( !ret ) {
7719270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() );
7729270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            return -1;
7739270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
7749270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
7759270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            fprintf(stderr, "ADB server didn't ACK\n" );
7769270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            return -1;
7779270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
7789270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
7799270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#elif defined(HAVE_FORKEXEC)
7809270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    char    path[PATH_MAX];
7819270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    int     fd[2];
7829270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
7839270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // set up a pipe so the child can tell us when it is ready.
7849270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child.
7859270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (pipe(fd)) {
7869270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
7879270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return -1;
7889270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
7899270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    get_my_path(path, PATH_MAX);
7909270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    pid_t pid = fork();
7919270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(pid < 0) return -1;
7929270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
7939270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (pid == 0) {
7949270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        // child side of the fork
7959270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
7969270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        // redirect stderr to the pipe
7979270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        // we use stderr instead of stdout due to stdout's buffering behavior.
7989270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        adb_close(fd[0]);
7999270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        dup2(fd[1], STDERR_FILENO);
8009270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        adb_close(fd[1]);
8019270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
8029270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        // child process
8039270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        int result = execl(path, "adb", "fork-server", "server", NULL);
8049270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        // this should not return
8059270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
8069270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    } else  {
8079270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        // parent side of the fork
8089270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
8099270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        char  temp[3];
8109270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
8119270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
8129270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        // wait for the "OK\n" message
8139270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        adb_close(fd[1]);
8149270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        int ret = adb_read(fd[0], temp, 3);
8159270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        int saved_errno = errno;
8169270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        adb_close(fd[0]);
8179270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if (ret < 0) {
8189270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
8199270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            return -1;
8209270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
8219270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
8229270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            fprintf(stderr, "ADB server didn't ACK\n" );
8239270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            return -1;
8249270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
8259270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
8269270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        setsid();
8279270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
8289270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#else
8299270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#error "cannot implement background server start on this platform"
8309270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#endif
8319270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    return 0;
8329270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
8339270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#endif
8349270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
8359270a20a801403c9f60d6a701b39eae70d380403Doug Zongker/* Constructs a local name of form tcp:port.
8369270a20a801403c9f60d6a701b39eae70d380403Doug Zongker * target_str points to the target string, it's content will be overwritten.
8379270a20a801403c9f60d6a701b39eae70d380403Doug Zongker * target_size is the capacity of the target string.
8389270a20a801403c9f60d6a701b39eae70d380403Doug Zongker * server_port is the port number to use for the local name.
8399270a20a801403c9f60d6a701b39eae70d380403Doug Zongker */
8409270a20a801403c9f60d6a701b39eae70d380403Doug Zongkervoid build_local_name(char* target_str, size_t target_size, int server_port)
8419270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
8429270a20a801403c9f60d6a701b39eae70d380403Doug Zongker  snprintf(target_str, target_size, "tcp:%d", server_port);
8439270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
8449270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
8459270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerint adb_main()
8469270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
8479270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    atexit(adb_cleanup);
8489270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#if defined(HAVE_FORKEXEC)
8499270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // No SIGCHLD. Let the service subproc handle its children.
8509270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    signal(SIGPIPE, SIG_IGN);
8519270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#endif
8529270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
8539270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    init_transport_registration();
8549270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
8559270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // The minimal version of adbd only uses USB.
8569270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (access("/dev/android_adb", F_OK) == 0) {
8579270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        // listen on USB
8589270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        usb_init();
8599270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
8609270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
8619270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    D("Event loop starting\n");
8629270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
8639270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fdevent_loop();
8649270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
8659270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    usb_cleanup();
8669270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
8679270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    return 0;
8689270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
8699270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
8709270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#if ADB_HOST
8719270a20a801403c9f60d6a701b39eae70d380403Doug Zongkervoid connect_device(char* host, char* buffer, int buffer_size)
8729270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
8739270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    int port, fd;
8749270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    char* portstr = strchr(host, ':');
8759270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    char hostbuf[100];
8769270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    char serial[100];
8779270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
8789270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    strncpy(hostbuf, host, sizeof(hostbuf) - 1);
8799270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (portstr) {
8809270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if (portstr - host >= sizeof(hostbuf)) {
8819270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            snprintf(buffer, buffer_size, "bad host name %s", host);
8829270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            return;
8839270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
8849270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        // zero terminate the host at the point we found the colon
8859270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        hostbuf[portstr - host] = 0;
8869270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if (sscanf(portstr + 1, "%d", &port) == 0) {
8879270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            snprintf(buffer, buffer_size, "bad port number %s", portstr);
8889270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            return;
8899270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
8909270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    } else {
8919270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
8929270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
8939270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
8949270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    snprintf(serial, sizeof(serial), "%s:%d", hostbuf, port);
8959270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (find_transport(serial)) {
8969270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        snprintf(buffer, buffer_size, "already connected to %s", serial);
8979270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return;
8989270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
8999270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
9009270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    fd = socket_network_client(hostbuf, port, SOCK_STREAM);
9019270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (fd < 0) {
9029270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        snprintf(buffer, buffer_size, "unable to connect to %s:%d", host, port);
9039270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return;
9049270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
9059270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
9069270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    D("client: connected on remote on fd %d\n", fd);
9079270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    close_on_exec(fd);
9089270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    disable_tcp_nagle(fd);
9099270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    register_socket_transport(fd, serial, port, 0);
9109270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    snprintf(buffer, buffer_size, "connected to %s", serial);
9119270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
9129270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
9139270a20a801403c9f60d6a701b39eae70d380403Doug Zongkervoid connect_emulator(char* port_spec, char* buffer, int buffer_size)
9149270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
9159270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    char* port_separator = strchr(port_spec, ',');
9169270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (!port_separator) {
9179270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        snprintf(buffer, buffer_size,
9189270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                "unable to parse '%s' as <console port>,<adb port>",
9199270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                port_spec);
9209270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return;
9219270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
9229270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
9239270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // Zero-terminate console port and make port_separator point to 2nd port.
9249270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    *port_separator++ = 0;
9259270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    int console_port = strtol(port_spec, NULL, 0);
9269270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    int adb_port = strtol(port_separator, NULL, 0);
9279270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (!(console_port > 0 && adb_port > 0)) {
9289270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        *(port_separator - 1) = ',';
9299270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        snprintf(buffer, buffer_size,
9309270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                "Invalid port numbers: Expected positive numbers, got '%s'",
9319270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                port_spec);
9329270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return;
9339270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
9349270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
9359270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    /* Check if the emulator is already known.
9369270a20a801403c9f60d6a701b39eae70d380403Doug Zongker     * Note: There's a small but harmless race condition here: An emulator not
9379270a20a801403c9f60d6a701b39eae70d380403Doug Zongker     * present just yet could be registered by another invocation right
9389270a20a801403c9f60d6a701b39eae70d380403Doug Zongker     * after doing this check here. However, local_connect protects
9399270a20a801403c9f60d6a701b39eae70d380403Doug Zongker     * against double-registration too. From here, a better error message
9409270a20a801403c9f60d6a701b39eae70d380403Doug Zongker     * can be produced. In the case of the race condition, the very specific
9419270a20a801403c9f60d6a701b39eae70d380403Doug Zongker     * error message won't be shown, but the data doesn't get corrupted. */
9429270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    atransport* known_emulator = find_emulator_transport_by_adb_port(adb_port);
9439270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (known_emulator != NULL) {
9449270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        snprintf(buffer, buffer_size,
9459270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                "Emulator on port %d already registered.", adb_port);
9469270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return;
9479270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
9489270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
9499270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    /* Check if more emulators can be registered. Similar unproblematic
9509270a20a801403c9f60d6a701b39eae70d380403Doug Zongker     * race condition as above. */
9519270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    int candidate_slot = get_available_local_transport_index();
9529270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (candidate_slot < 0) {
9539270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        snprintf(buffer, buffer_size, "Cannot accept more emulators.");
9549270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return;
9559270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
9569270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
9579270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    /* Preconditions met, try to connect to the emulator. */
9589270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (!local_connect_arbitrary_ports(console_port, adb_port)) {
9599270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        snprintf(buffer, buffer_size,
9609270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                "Connected to emulator on ports %d,%d", console_port, adb_port);
9619270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    } else {
9629270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        snprintf(buffer, buffer_size,
9639270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                "Could not connect to emulator on ports %d,%d",
9649270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                console_port, adb_port);
9659270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
9669270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
9679270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#endif
9689270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
9699270a20a801403c9f60d6a701b39eae70d380403Doug Zongkerint handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
9709270a20a801403c9f60d6a701b39eae70d380403Doug Zongker{
9719270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    atransport *transport = NULL;
9729270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    char buf[4096];
9739270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
9749270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(!strcmp(service, "kill")) {
9759270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        fprintf(stderr,"adb server killed by remote request\n");
9769270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        fflush(stdout);
9779270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        adb_write(reply_fd, "OKAY", 4);
9789270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        usb_cleanup();
9799270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        exit(0);
9809270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
9819270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
9829270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#if ADB_HOST
9839270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // "transport:" is used for switching transport with a specified serial number
9849270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // "transport-usb:" is used for switching transport to the only USB transport
9859270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // "transport-local:" is used for switching transport to the only local transport
9869270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // "transport-any:" is used for switching transport to the only transport
9879270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (!strncmp(service, "transport", strlen("transport"))) {
9889270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        char* error_string = "unknown failure";
9899270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        transport_type type = kTransportAny;
9909270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
9919270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
9929270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            type = kTransportUsb;
9939270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        } else if (!strncmp(service, "transport-local", strlen("transport-local"))) {
9949270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            type = kTransportLocal;
9959270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        } else if (!strncmp(service, "transport-any", strlen("transport-any"))) {
9969270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            type = kTransportAny;
9979270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        } else if (!strncmp(service, "transport:", strlen("transport:"))) {
9989270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            service += strlen("transport:");
9999270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            serial = service;
10009270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
10019270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
10029270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        transport = acquire_one_transport(CS_ANY, type, serial, &error_string);
10039270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
10049270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if (transport) {
10059270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            s->transport = transport;
10069270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            adb_write(reply_fd, "OKAY", 4);
10079270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        } else {
10089270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            sendfailmsg(reply_fd, error_string);
10099270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
10109270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return 1;
10119270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
10129270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
10139270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // return a list of all connected devices
10149270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (!strcmp(service, "devices")) {
10159270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        char buffer[4096];
10169270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        memset(buf, 0, sizeof(buf));
10179270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        memset(buffer, 0, sizeof(buffer));
10189270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        D("Getting device list \n");
10199270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        list_transports(buffer, sizeof(buffer));
10209270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer);
10219270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        D("Wrote device list \n");
10229270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        writex(reply_fd, buf, strlen(buf));
10239270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return 0;
10249270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
10259270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
10269270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // add a new TCP transport, device or emulator
10279270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (!strncmp(service, "connect:", 8)) {
10289270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        char buffer[4096];
10299270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        char* host = service + 8;
10309270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if (!strncmp(host, "emu:", 4)) {
10319270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            connect_emulator(host + 4, buffer, sizeof(buffer));
10329270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        } else {
10339270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            connect_device(host, buffer, sizeof(buffer));
10349270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
10359270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        // Send response for emulator and device
10369270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer);
10379270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        writex(reply_fd, buf, strlen(buf));
10389270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return 0;
10399270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
10409270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
10419270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // remove TCP transport
10429270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (!strncmp(service, "disconnect:", 11)) {
10439270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        char buffer[4096];
10449270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        memset(buffer, 0, sizeof(buffer));
10459270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        char* serial = service + 11;
10469270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if (serial[0] == 0) {
10479270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            // disconnect from all TCP devices
10489270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            unregister_all_tcp_transports();
10499270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        } else {
10509270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            char hostbuf[100];
10519270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            // assume port 5555 if no port is specified
10529270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            if (!strchr(serial, ':')) {
10539270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial);
10549270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                serial = hostbuf;
10559270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            }
10569270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            atransport *t = find_transport(serial);
10579270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
10589270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            if (t) {
10599270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                unregister_transport(t);
10609270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            } else {
10619270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                snprintf(buffer, sizeof(buffer), "No such device %s", serial);
10629270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            }
10639270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
10649270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
10659270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer);
10669270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        writex(reply_fd, buf, strlen(buf));
10679270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return 0;
10689270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
10699270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
10709270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // returns our value for ADB_SERVER_VERSION
10719270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (!strcmp(service, "version")) {
10729270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        char version[12];
10739270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION);
10749270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        snprintf(buf, sizeof buf, "OKAY%04x%s", (unsigned)strlen(version), version);
10759270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        writex(reply_fd, buf, strlen(buf));
10769270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return 0;
10779270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
10789270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
10799270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {
10809270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        char *out = "unknown";
10819270a20a801403c9f60d6a701b39eae70d380403Doug Zongker         transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
10829270a20a801403c9f60d6a701b39eae70d380403Doug Zongker       if (transport && transport->serial) {
10839270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            out = transport->serial;
10849270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
10859270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out);
10869270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        writex(reply_fd, buf, strlen(buf));
10879270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return 0;
10889270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
10899270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    // indicates a new emulator instance has started
10909270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if (!strncmp(service,"emulator:",9)) {
10919270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        int  port = atoi(service+9);
10929270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        local_connect(port);
10939270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        /* we don't even need to send a reply */
10949270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return 0;
10959270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
10969270a20a801403c9f60d6a701b39eae70d380403Doug Zongker#endif // ADB_HOST
10979270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
10989270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(!strncmp(service,"forward:",8) || !strncmp(service,"killforward:",12)) {
10999270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        char *local, *remote, *err;
11009270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        int r;
11019270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        atransport *transport;
11029270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
11039270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        int createForward = strncmp(service,"kill",4);
11049270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
11059270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        local = service + (createForward ? 8 : 12);
11069270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        remote = strchr(local,';');
11079270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if(remote == 0) {
11089270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            sendfailmsg(reply_fd, "malformed forward spec");
11099270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            return 0;
11109270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
11119270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
11129270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        *remote++ = 0;
11139270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')){
11149270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            sendfailmsg(reply_fd, "malformed forward spec");
11159270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            return 0;
11169270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
11179270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
11189270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        transport = acquire_one_transport(CS_ANY, ttype, serial, &err);
11199270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if (!transport) {
11209270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            sendfailmsg(reply_fd, err);
11219270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            return 0;
11229270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
11239270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
11249270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if (createForward) {
11259270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            r = install_listener(local, remote, transport);
11269270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        } else {
11279270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            r = remove_listener(local, remote, transport);
11289270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
11299270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if(r == 0) {
11309270a20a801403c9f60d6a701b39eae70d380403Doug Zongker                /* 1st OKAY is connect, 2nd OKAY is status */
11319270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            writex(reply_fd, "OKAYOKAY", 8);
11329270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            return 0;
11339270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
11349270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
11359270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        if (createForward) {
11369270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            sendfailmsg(reply_fd, (r == -1) ? "cannot rebind smartsocket" : "cannot bind socket");
11379270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        } else {
11389270a20a801403c9f60d6a701b39eae70d380403Doug Zongker            sendfailmsg(reply_fd, "cannot remove listener");
11399270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        }
11409270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return 0;
11419270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
11429270a20a801403c9f60d6a701b39eae70d380403Doug Zongker
11439270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    if(!strncmp(service,"get-state",strlen("get-state"))) {
11449270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
11459270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        char *state = connection_state_name(transport);
11469270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(state),state);
11479270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        writex(reply_fd, buf, strlen(buf));
11489270a20a801403c9f60d6a701b39eae70d380403Doug Zongker        return 0;
11499270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    }
11509270a20a801403c9f60d6a701b39eae70d380403Doug Zongker    return -1;
11519270a20a801403c9f60d6a701b39eae70d380403Doug Zongker}
1152