adb.c revision d0eacb8aee77f01edadf525019f8dd1e43671ce7
102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project/*
202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project *
402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project * you may not use this file except in compliance with the License.
602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project * You may obtain a copy of the License at
702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project *
802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project *
1002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project * See the License for the specific language governing permissions and
1402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project * limitations under the License.
1502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project */
1602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
1702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#define  TRACE_TAG   TRACE_ADB
1802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
1902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include <stdio.h>
2002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include <stdlib.h>
2102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include <ctype.h>
2202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include <stdarg.h>
2302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include <errno.h>
2402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include <string.h>
2502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include <time.h>
2602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include <sys/time.h>
2702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
2802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include "sysdeps.h"
2902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include "adb.h"
3002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
3102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#if !ADB_HOST
3202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include <private/android_filesystem_config.h>
3302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include <linux/capability.h>
3402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include <linux/prctl.h>
3502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#else
3602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include "usb_vendors.h"
3702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#endif
3802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
3902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
4002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectint HOST = 0;
4102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
4202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectstatic const char *adb_device_banner = "device";
4302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
4402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectvoid fatal(const char *fmt, ...)
4502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
4602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    va_list ap;
4702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    va_start(ap, fmt);
4802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fprintf(stderr, "error: ");
4902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    vfprintf(stderr, fmt, ap);
5002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fprintf(stderr, "\n");
5102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    va_end(ap);
5202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    exit(-1);
5302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
5402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
5502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectvoid fatal_errno(const char *fmt, ...)
5602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
5702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    va_list ap;
5802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    va_start(ap, fmt);
5902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fprintf(stderr, "error: %s: ", strerror(errno));
6002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    vfprintf(stderr, fmt, ap);
6102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fprintf(stderr, "\n");
6202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    va_end(ap);
6302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    exit(-1);
6402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
6502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
6602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectint   adb_trace_mask;
6702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
6802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project/* read a comma/space/colum/semi-column separated list of tags
6902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project * from the ADB_TRACE environment variable and build the trace
7002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project * mask from it. note that '1' and 'all' are special cases to
7102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project * enable all tracing
7202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project */
7302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectvoid  adb_trace_init(void)
7402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
7502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    const char*  p = getenv("ADB_TRACE");
7602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    const char*  q;
7702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
7802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    static const struct {
7902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        const char*  tag;
8002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        int           flag;
8102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    } tags[] = {
8202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        { "1", 0 },
8302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        { "all", 0 },
8402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        { "adb", TRACE_ADB },
8502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        { "sockets", TRACE_SOCKETS },
8602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        { "packets", TRACE_PACKETS },
8702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        { "rwx", TRACE_RWX },
8802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        { "usb", TRACE_USB },
8902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        { "sync", TRACE_SYNC },
9002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        { "sysdeps", TRACE_SYSDEPS },
9102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        { "transport", TRACE_TRANSPORT },
9202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        { "jdwp", TRACE_JDWP },
9302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        { NULL, 0 }
9402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    };
9502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
9602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if (p == NULL)
9702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            return;
9802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
9902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    /* use a comma/column/semi-colum/space separated list */
10002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    while (*p) {
10102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        int  len, tagn;
10202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
10302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        q = strpbrk(p, " ,:;");
10402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        if (q == NULL) {
10502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            q = p + strlen(p);
10602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        }
10702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        len = q - p;
10802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
10902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        for (tagn = 0; tags[tagn].tag != NULL; tagn++)
11002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        {
11102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            int  taglen = strlen(tags[tagn].tag);
11202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
11302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            if (len == taglen && !memcmp(tags[tagn].tag, p, len) )
11402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            {
11502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                int  flag = tags[tagn].flag;
11602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                if (flag == 0) {
11702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                    adb_trace_mask = ~0;
11802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                    return;
11902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                }
12002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                adb_trace_mask |= (1 << flag);
12102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                break;
12202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            }
12302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        }
12402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        p = q;
12502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        if (*p)
12602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            p++;
12702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
12802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
12902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
13002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
13102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectapacket *get_apacket(void)
13202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
13302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    apacket *p = malloc(sizeof(apacket));
13402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if(p == 0) fatal("failed to allocate an apacket");
13502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    memset(p, 0, sizeof(apacket) - MAX_PAYLOAD);
13602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    return p;
13702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
13802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
13902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectvoid put_apacket(apacket *p)
14002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
14102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    free(p);
14202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
14302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
14402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectvoid handle_online(void)
14502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
14602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    D("adb: online\n");
14702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
14802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
14902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectvoid handle_offline(atransport *t)
15002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
15102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    D("adb: offline\n");
15202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    //Close the associated usb
15302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    run_transport_disconnects(t);
15402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
15502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
15602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#if TRACE_PACKETS
15702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#define DUMPMAX 32
15802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectvoid print_packet(const char *label, apacket *p)
15902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
16002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    char *tag;
16102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    char *x;
16202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    unsigned count;
16302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
16402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    switch(p->msg.command){
16502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    case A_SYNC: tag = "SYNC"; break;
16602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    case A_CNXN: tag = "CNXN" ; break;
16702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    case A_OPEN: tag = "OPEN"; break;
16802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    case A_OKAY: tag = "OKAY"; break;
16902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    case A_CLSE: tag = "CLSE"; break;
17002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    case A_WRTE: tag = "WRTE"; break;
17102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    default: tag = "????"; break;
17202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
17302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
17402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fprintf(stderr, "%s: %s %08x %08x %04x \"",
17502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length);
17602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    count = p->msg.data_length;
17702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    x = (char*) p->data;
17802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if(count > DUMPMAX) {
17902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        count = DUMPMAX;
18002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        tag = "\n";
18102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    } else {
18202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        tag = "\"\n";
18302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
18402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    while(count-- > 0){
18502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        if((*x >= ' ') && (*x < 127)) {
18602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            fputc(*x, stderr);
18702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        } else {
18802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            fputc('.', stderr);
18902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        }
19002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        x++;
19102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
19202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fprintf(stderr, tag);
19302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
19402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#endif
19502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
19602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectstatic void send_ready(unsigned local, unsigned remote, atransport *t)
19702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
19802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    D("Calling send_ready \n");
19902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    apacket *p = get_apacket();
20002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    p->msg.command = A_OKAY;
20102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    p->msg.arg0 = local;
20202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    p->msg.arg1 = remote;
20302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    send_packet(p, t);
20402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
20502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
20602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectstatic void send_close(unsigned local, unsigned remote, atransport *t)
20702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
20802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    D("Calling send_close \n");
20902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    apacket *p = get_apacket();
21002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    p->msg.command = A_CLSE;
21102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    p->msg.arg0 = local;
21202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    p->msg.arg1 = remote;
21302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    send_packet(p, t);
21402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
21502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
21602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectstatic void send_connect(atransport *t)
21702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
21802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    D("Calling send_connect \n");
21902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    apacket *cp = get_apacket();
22002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    cp->msg.command = A_CNXN;
22102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    cp->msg.arg0 = A_VERSION;
22202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    cp->msg.arg1 = MAX_PAYLOAD;
22302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    snprintf((char*) cp->data, sizeof cp->data, "%s::",
22402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            HOST ? "host" : adb_device_banner);
22502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    cp->msg.data_length = strlen((char*) cp->data) + 1;
22602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    send_packet(cp, t);
22702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#if ADB_HOST
22802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        /* XXX why sleep here? */
22902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    // allow the device some time to respond to the connect message
23002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    adb_sleep_ms(1000);
23102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#endif
23202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
23302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
23402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectstatic char *connection_state_name(atransport *t)
23502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
23602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if (t == NULL) {
23702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        return "unknown";
23802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
23902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
24002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    switch(t->connection_state) {
24102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    case CS_BOOTLOADER:
24202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        return "bootloader";
24302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    case CS_DEVICE:
24402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        return "device";
24502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    case CS_OFFLINE:
24602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        return "offline";
24702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    default:
24802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        return "unknown";
24902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
25002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
25102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
25202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectvoid parse_banner(char *banner, atransport *t)
25302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
25402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    char *type, *product, *end;
25502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
25602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    D("parse_banner: %s\n", banner);
25702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    type = banner;
25802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    product = strchr(type, ':');
25902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if(product) {
26002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        *product++ = 0;
26102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    } else {
26202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        product = "";
26302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
26402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
26502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        /* remove trailing ':' */
26602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    end = strchr(product, ':');
26702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if(end) *end = 0;
26802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
26902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        /* save product name in device structure */
27002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if (t->product == NULL) {
27102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        t->product = strdup(product);
27202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    } else if (strcmp(product, t->product) != 0) {
27302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        free(t->product);
27402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        t->product = strdup(product);
27502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
27602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
27702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if(!strcmp(type, "bootloader")){
27802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        D("setting connection_state to CS_BOOTLOADER\n");
27902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        t->connection_state = CS_BOOTLOADER;
28002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        update_transports();
28102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        return;
28202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
28302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
28402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if(!strcmp(type, "device")) {
28502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        D("setting connection_state to CS_DEVICE\n");
28602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        t->connection_state = CS_DEVICE;
28702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        update_transports();
28802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        return;
28902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
29002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
29102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if(!strcmp(type, "recovery")) {
29202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        D("setting connection_state to CS_RECOVERY\n");
29302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        t->connection_state = CS_RECOVERY;
29402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        update_transports();
29502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        return;
29602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
29702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
29802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    t->connection_state = CS_HOST;
29902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
30002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
30102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectvoid handle_packet(apacket *p, atransport *t)
30202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
30302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    asocket *s;
30402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
30502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    D("handle_packet() %d\n", p->msg.command);
30602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
30702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    print_packet("recv", p);
30802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
30902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    switch(p->msg.command){
31002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    case A_SYNC:
31102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        if(p->msg.arg0){
31202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            send_packet(p, t);
31302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            if(HOST) send_connect(t);
31402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        } else {
31502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            t->connection_state = CS_OFFLINE;
31602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            handle_offline(t);
31702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            send_packet(p, t);
31802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        }
31902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        return;
32002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
32102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
32202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            /* XXX verify version, etc */
32302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        if(t->connection_state != CS_OFFLINE) {
32402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            t->connection_state = CS_OFFLINE;
32502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            handle_offline(t);
32602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        }
32702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        parse_banner((char*) p->data, t);
32802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        handle_online();
32902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        if(!HOST) send_connect(t);
33002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        break;
33102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
33202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    case A_OPEN: /* OPEN(local-id, 0, "destination") */
33302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        if(t->connection_state != CS_OFFLINE) {
33402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            char *name = (char*) p->data;
33502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
33602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            s = create_local_service_socket(name);
33702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            if(s == 0) {
33802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                send_close(0, p->msg.arg0, t);
33902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            } else {
34002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                s->peer = create_remote_socket(p->msg.arg0, t);
34102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                s->peer->peer = s;
34202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                send_ready(s->id, s->peer->id, t);
34302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                s->ready(s);
34402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            }
34502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        }
34602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        break;
34702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
34802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    case A_OKAY: /* READY(local-id, remote-id, "") */
34902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        if(t->connection_state != CS_OFFLINE) {
35002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            if((s = find_local_socket(p->msg.arg1))) {
35102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                if(s->peer == 0) {
35202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                    s->peer = create_remote_socket(p->msg.arg0, t);
35302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                    s->peer->peer = s;
35402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                }
35502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                s->ready(s);
35602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            }
35702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        }
35802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        break;
35902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
36002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    case A_CLSE: /* CLOSE(local-id, remote-id, "") */
36102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        if(t->connection_state != CS_OFFLINE) {
36202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            if((s = find_local_socket(p->msg.arg1))) {
36302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                s->close(s);
36402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            }
36502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        }
36602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        break;
36702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
36802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    case A_WRTE:
36902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        if(t->connection_state != CS_OFFLINE) {
37002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            if((s = find_local_socket(p->msg.arg1))) {
37102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                unsigned rid = p->msg.arg0;
37202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                p->len = p->msg.data_length;
37302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
37402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                if(s->enqueue(s, p) == 0) {
37502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                    D("Enqueue the socket\n");
37602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                    send_ready(s->id, rid, t);
37702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                }
37802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                return;
37902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            }
38002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        }
38102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        break;
38202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
38302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    default:
38402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        printf("handle_packet: what is %08x?!\n", p->msg.command);
38502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
38602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
38702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    put_apacket(p);
38802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
38902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
39002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectalistener listener_list = {
39102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    .next = &listener_list,
39202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    .prev = &listener_list,
39302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project};
39402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
39502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectstatic void ss_listener_event_func(int _fd, unsigned ev, void *_l)
39602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
39702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    asocket *s;
39802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
39902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if(ev & FDE_READ) {
40002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        struct sockaddr addr;
40102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        socklen_t alen;
40202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        int fd;
40302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
40402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        alen = sizeof(addr);
40502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        fd = adb_socket_accept(_fd, &addr, &alen);
40602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        if(fd < 0) return;
40702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
40802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        adb_socket_setbufsize(fd, CHUNK_SIZE);
40902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
41002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        s = create_local_socket(fd);
41102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        if(s) {
41202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            connect_to_smartsocket(s);
41302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            return;
41402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        }
41502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
41602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        adb_close(fd);
41702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
41802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
41902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
42002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectstatic void listener_event_func(int _fd, unsigned ev, void *_l)
42102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
42202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    alistener *l = _l;
42302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    asocket *s;
42402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
42502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if(ev & FDE_READ) {
42602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        struct sockaddr addr;
42702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        socklen_t alen;
42802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        int fd;
42902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
43002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        alen = sizeof(addr);
43102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        fd = adb_socket_accept(_fd, &addr, &alen);
43202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        if(fd < 0) return;
43302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
43402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        s = create_local_socket(fd);
43502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        if(s) {
43602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            s->transport = l->transport;
43702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            connect_to_remote(s, l->connect_to);
43802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            return;
43902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        }
44002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
44102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        adb_close(fd);
44202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
44302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
44402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
44502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectstatic void  free_listener(alistener*  l)
44602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
44702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if (l->next) {
44802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        l->next->prev = l->prev;
44902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        l->prev->next = l->next;
45002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        l->next = l->prev = l;
45102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
45202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
45302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    // closes the corresponding fd
45402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fdevent_remove(&l->fde);
45502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
45602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if (l->local_name)
45702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        free((char*)l->local_name);
45802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
45902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if (l->connect_to)
46002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        free((char*)l->connect_to);
46102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
46202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if (l->transport) {
46302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        remove_transport_disconnect(l->transport, &l->disconnect);
46402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
46502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    free(l);
46602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
46702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
46802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectstatic void listener_disconnect(void*  _l, atransport*  t)
46902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
47002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    alistener*  l = _l;
47102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
47202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    free_listener(l);
47302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
47402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
47502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectint local_name_to_fd(const char *name)
47602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
47702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    int port;
47802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
47902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if(!strncmp("tcp:", name, 4)){
48002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        int  ret;
48102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        port = atoi(name + 4);
48202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        ret = socket_loopback_server(port, SOCK_STREAM);
48302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        return ret;
48402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
48502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#ifndef HAVE_WIN32_IPC  /* no Unix-domain sockets on Win32 */
48602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    // It's non-sensical to support the "reserved" space on the adb host side
48702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if(!strncmp(name, "local:", 6)) {
48802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        return socket_local_server(name + 6,
48902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
49002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    } else if(!strncmp(name, "localabstract:", 14)) {
49102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        return socket_local_server(name + 14,
49202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
49302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    } else if(!strncmp(name, "localfilesystem:", 16)) {
49402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        return socket_local_server(name + 16,
49502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
49602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
49702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
49802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#endif
49902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    printf("unknown local portname '%s'\n", name);
50002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    return -1;
50102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
50202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
50302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectstatic int remove_listener(const char *local_name, const char *connect_to, atransport* transport)
50402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
50502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    alistener *l;
50602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
50702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    for (l = listener_list.next; l != &listener_list; l = l->next) {
50802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        if (!strcmp(local_name, l->local_name) &&
50902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            !strcmp(connect_to, l->connect_to) &&
51002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            l->transport && l->transport == transport) {
51102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
51202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            listener_disconnect(l, transport);
51302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            return 0;
51402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        }
51502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
51602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
51702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    return -1;
51802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
51902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
52002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectstatic int install_listener(const char *local_name, const char *connect_to, atransport* transport)
52102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
52202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    alistener *l;
52302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
52402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    //printf("install_listener('%s','%s')\n", local_name, connect_to);
52502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
52602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    for(l = listener_list.next; l != &listener_list; l = l->next){
52702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        if(strcmp(local_name, l->local_name) == 0) {
52802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            char *cto;
52902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
53002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                /* can't repurpose a smartsocket */
53102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            if(l->connect_to[0] == '*') {
53202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                return -1;
53302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            }
53402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
53502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            cto = strdup(connect_to);
53602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            if(cto == 0) {
53702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                return -1;
53802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            }
53902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
54002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            //printf("rebinding '%s' to '%s'\n", local_name, connect_to);
54102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            free((void*) l->connect_to);
54202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            l->connect_to = cto;
54302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            if (l->transport != transport) {
54402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                remove_transport_disconnect(l->transport, &l->disconnect);
54502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                l->transport = transport;
54602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                add_transport_disconnect(l->transport, &l->disconnect);
54702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            }
54802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            return 0;
54902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        }
55002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
55102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
55202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if((l = calloc(1, sizeof(alistener))) == 0) goto nomem;
55302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if((l->local_name = strdup(local_name)) == 0) goto nomem;
55402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if((l->connect_to = strdup(connect_to)) == 0) goto nomem;
55502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
55602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
55702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    l->fd = local_name_to_fd(local_name);
55802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if(l->fd < 0) {
55902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        free((void*) l->local_name);
560        free((void*) l->connect_to);
561        free(l);
562        printf("cannot bind '%s'\n", local_name);
563        return -2;
564    }
565
566    close_on_exec(l->fd);
567    if(!strcmp(l->connect_to, "*smartsocket*")) {
568        fdevent_install(&l->fde, l->fd, ss_listener_event_func, l);
569    } else {
570        fdevent_install(&l->fde, l->fd, listener_event_func, l);
571    }
572    fdevent_set(&l->fde, FDE_READ);
573
574    l->next = &listener_list;
575    l->prev = listener_list.prev;
576    l->next->prev = l;
577    l->prev->next = l;
578    l->transport = transport;
579
580    if (transport) {
581        l->disconnect.opaque = l;
582        l->disconnect.func   = listener_disconnect;
583        add_transport_disconnect(transport, &l->disconnect);
584    }
585    return 0;
586
587nomem:
588    fatal("cannot allocate listener");
589    return 0;
590}
591
592#ifdef HAVE_FORKEXEC
593static void sigchld_handler(int n)
594{
595    int status;
596    while(waitpid(-1, &status, WNOHANG) > 0) ;
597}
598#endif
599
600#ifdef HAVE_WIN32_PROC
601static BOOL WINAPI ctrlc_handler(DWORD type)
602{
603    exit(STATUS_CONTROL_C_EXIT);
604    return TRUE;
605}
606#endif
607
608static void adb_cleanup(void)
609{
610    usb_cleanup();
611}
612
613void start_logging(void)
614{
615#ifdef HAVE_WIN32_PROC
616    char    temp[ MAX_PATH ];
617    FILE*   fnul;
618    FILE*   flog;
619
620    GetTempPath( sizeof(temp) - 8, temp );
621    strcat( temp, "adb.log" );
622
623    /* Win32 specific redirections */
624    fnul = fopen( "NUL", "rt" );
625    if (fnul != NULL)
626        stdin[0] = fnul[0];
627
628    flog = fopen( temp, "at" );
629    if (flog == NULL)
630        flog = fnul;
631
632    setvbuf( flog, NULL, _IONBF, 0 );
633
634    stdout[0] = flog[0];
635    stderr[0] = flog[0];
636    fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
637#else
638    int fd;
639
640    fd = unix_open("/dev/null", O_RDONLY);
641    dup2(fd, 0);
642
643    fd = unix_open("/tmp/adb.log", O_WRONLY | O_CREAT | O_APPEND, 0640);
644    if(fd < 0) {
645        fd = unix_open("/dev/null", O_WRONLY);
646    }
647    dup2(fd, 1);
648    dup2(fd, 2);
649    fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
650#endif
651}
652
653#if !ADB_HOST
654void start_device_log(void)
655{
656    int fd;
657    char    path[PATH_MAX];
658    struct tm now;
659    time_t t;
660    char value[PROPERTY_VALUE_MAX];
661
662    // read the trace mask from persistent property persist.adb.trace_mask
663    // give up if the property is not set or cannot be parsed
664    property_get("persist.adb.trace_mask", value, "");
665    if (sscanf(value, "%x", &adb_trace_mask) != 1)
666        return;
667
668    adb_mkdir("/data/adb", 0775);
669    tzset();
670    time(&t);
671    localtime_r(&t, &now);
672    strftime(path, sizeof(path),
673                "/data/adb/adb-%Y-%m-%d-%H-%M-%S.txt",
674                &now);
675    fd = unix_open(path, O_WRONLY | O_CREAT | O_TRUNC, 0640);
676    if (fd < 0)
677        return;
678
679    // redirect stdout and stderr to the log file
680    dup2(fd, 1);
681    dup2(fd, 2);
682    fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
683
684    fd = unix_open("/dev/null", O_RDONLY);
685    dup2(fd, 0);
686}
687#endif
688
689#if ADB_HOST
690int launch_server(int server_port)
691{
692#ifdef HAVE_WIN32_PROC
693    /* we need to start the server in the background                    */
694    /* we create a PIPE that will be used to wait for the server's "OK" */
695    /* message since the pipe handles must be inheritable, we use a     */
696    /* security attribute                                               */
697    HANDLE                pipe_read, pipe_write;
698    SECURITY_ATTRIBUTES   sa;
699    STARTUPINFO           startup;
700    PROCESS_INFORMATION   pinfo;
701    char                  program_path[ MAX_PATH ];
702    int                   ret;
703
704    sa.nLength = sizeof(sa);
705    sa.lpSecurityDescriptor = NULL;
706    sa.bInheritHandle = TRUE;
707
708    /* create pipe, and ensure its read handle isn't inheritable */
709    ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
710    if (!ret) {
711        fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );
712        return -1;
713    }
714
715    SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );
716
717    ZeroMemory( &startup, sizeof(startup) );
718    startup.cb = sizeof(startup);
719    startup.hStdInput  = GetStdHandle( STD_INPUT_HANDLE );
720    startup.hStdOutput = pipe_write;
721    startup.hStdError  = GetStdHandle( STD_ERROR_HANDLE );
722    startup.dwFlags    = STARTF_USESTDHANDLES;
723
724    ZeroMemory( &pinfo, sizeof(pinfo) );
725
726    /* get path of current program */
727    GetModuleFileName( NULL, program_path, sizeof(program_path) );
728
729    ret = CreateProcess(
730            program_path,                              /* program path  */
731            "adb fork-server server",
732                                    /* the fork-server argument will set the
733                                       debug = 2 in the child           */
734            NULL,                   /* process handle is not inheritable */
735            NULL,                    /* thread handle is not inheritable */
736            TRUE,                          /* yes, inherit some handles */
737            DETACHED_PROCESS, /* the new process doesn't have a console */
738            NULL,                     /* use parent's environment block */
739            NULL,                    /* use parent's starting directory */
740            &startup,                 /* startup info, i.e. std handles */
741            &pinfo );
742
743    CloseHandle( pipe_write );
744
745    if (!ret) {
746        fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );
747        CloseHandle( pipe_read );
748        return -1;
749    }
750
751    CloseHandle( pinfo.hProcess );
752    CloseHandle( pinfo.hThread );
753
754    /* wait for the "OK\n" message */
755    {
756        char  temp[3];
757        DWORD  count;
758
759        ret = ReadFile( pipe_read, temp, 3, &count, NULL );
760        CloseHandle( pipe_read );
761        if ( !ret ) {
762            fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() );
763            return -1;
764        }
765        if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
766            fprintf(stderr, "ADB server didn't ACK\n" );
767            return -1;
768        }
769    }
770#elif defined(HAVE_FORKEXEC)
771    char    path[PATH_MAX];
772    int     fd[2];
773
774    // set up a pipe so the child can tell us when it is ready.
775    // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child.
776    if (pipe(fd)) {
777        fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
778        return -1;
779    }
780    get_my_path(path, PATH_MAX);
781    pid_t pid = fork();
782    if(pid < 0) return -1;
783
784    if (pid == 0) {
785        // child side of the fork
786
787        // redirect stderr to the pipe
788        // we use stderr instead of stdout due to stdout's buffering behavior.
789        adb_close(fd[0]);
790        dup2(fd[1], STDERR_FILENO);
791        adb_close(fd[1]);
792
793        // child process
794        int result = execl(path, "adb", "fork-server", "server", NULL);
795        // this should not return
796        fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
797    } else  {
798        // parent side of the fork
799
800        char  temp[3];
801
802        temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
803        // wait for the "OK\n" message
804        adb_close(fd[1]);
805        int ret = adb_read(fd[0], temp, 3);
806        adb_close(fd[0]);
807        if (ret < 0) {
808            fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", errno);
809            return -1;
810        }
811        if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
812            fprintf(stderr, "ADB server didn't ACK\n" );
813            return -1;
814        }
815
816        setsid();
817    }
818#else
819#error "cannot implement background server start on this platform"
820#endif
821    return 0;
822}
823#endif
824
825/* Constructs a local name of form tcp:port.
826 * target_str points to the target string, it's content will be overwritten.
827 * target_size is the capacity of the target string.
828 * server_port is the port number to use for the local name.
829 */
830void build_local_name(char* target_str, size_t target_size, int server_port)
831{
832  snprintf(target_str, target_size, "tcp:%d", server_port);
833}
834
835int adb_main(int is_daemon, int server_port)
836{
837#if !ADB_HOST
838    int secure = 0;
839    int port;
840    char value[PROPERTY_VALUE_MAX];
841#endif
842
843    atexit(adb_cleanup);
844#ifdef HAVE_WIN32_PROC
845    SetConsoleCtrlHandler( ctrlc_handler, TRUE );
846#elif defined(HAVE_FORKEXEC)
847    signal(SIGCHLD, sigchld_handler);
848    signal(SIGPIPE, SIG_IGN);
849#endif
850
851    init_transport_registration();
852
853
854#if ADB_HOST
855    HOST = 1;
856    usb_vendors_init();
857    usb_init();
858    local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
859
860    char local_name[30];
861    build_local_name(local_name, sizeof(local_name), server_port);
862    if(install_listener(local_name, "*smartsocket*", NULL)) {
863        exit(1);
864    }
865#else
866    /* run adbd in secure mode if ro.secure is set and
867    ** we are not in the emulator
868    */
869    property_get("ro.kernel.qemu", value, "");
870    if (strcmp(value, "1") != 0) {
871        property_get("ro.secure", value, "");
872        if (strcmp(value, "1") == 0) {
873            // don't run as root if ro.secure is set...
874            secure = 1;
875
876            // ... except we allow running as root in userdebug builds if the
877            // service.adb.root property has been set by the "adb root" command
878            property_get("ro.debuggable", value, "");
879            if (strcmp(value, "1") == 0) {
880                property_get("service.adb.root", value, "");
881                if (strcmp(value, "1") == 0) {
882                    secure = 0;
883                }
884            }
885        }
886    }
887
888    /* don't listen on a port (default 5037) if running in secure mode */
889    /* don't run as root if we are running in secure mode */
890    if (secure) {
891        struct __user_cap_header_struct header;
892        struct __user_cap_data_struct cap;
893
894        prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
895
896        /* add extra groups:
897        ** AID_ADB to access the USB driver
898        ** AID_LOG to read system logs (adb logcat)
899        ** AID_INPUT to diagnose input issues (getevent)
900        ** AID_INET to diagnose network issues (netcfg, ping)
901        ** AID_GRAPHICS to access the frame buffer
902        ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
903        ** AID_SDCARD_RW to allow writing to the SD card
904        ** AID_MOUNT to allow unmounting the SD card before rebooting
905        */
906        gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS,
907                           AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_RW, AID_MOUNT };
908        setgroups(sizeof(groups)/sizeof(groups[0]), groups);
909
910        /* then switch user and group to "shell" */
911        setgid(AID_SHELL);
912        setuid(AID_SHELL);
913
914        /* set CAP_SYS_BOOT capability, so "adb reboot" will succeed */
915        header.version = _LINUX_CAPABILITY_VERSION;
916        header.pid = 0;
917        cap.effective = cap.permitted = (1 << CAP_SYS_BOOT);
918        cap.inheritable = 0;
919        capset(&header, &cap);
920
921        D("Local port disabled\n");
922    } else {
923        char local_name[30];
924        build_local_name(local_name, sizeof(local_name), server_port);
925        if(install_listener(local_name, "*smartsocket*", NULL)) {
926            exit(1);
927        }
928    }
929
930        /* for the device, start the usb transport if the
931        ** android usb device exists and the "service.adb.tcp.port" and
932        ** "persist.adb.tcp.port" properties are not set.
933        ** Otherwise start the network transport.
934        */
935    property_get("service.adb.tcp.port", value, "");
936    if (!value[0])
937        property_get("persist.adb.tcp.port", value, "");
938    if (sscanf(value, "%d", &port) == 1 && port > 0) {
939        // listen on TCP port specified by service.adb.tcp.port property
940        local_init(port);
941    } else if (access("/dev/android_adb", F_OK) == 0) {
942        // listen on USB
943        usb_init();
944    } else {
945        // listen on default port
946        local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
947    }
948    init_jdwp();
949#endif
950
951    if (is_daemon)
952    {
953        // inform our parent that we are up and running.
954#ifdef HAVE_WIN32_PROC
955        DWORD  count;
956        WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), "OK\n", 3, &count, NULL );
957#elif defined(HAVE_FORKEXEC)
958        fprintf(stderr, "OK\n");
959#endif
960        start_logging();
961    }
962
963    fdevent_loop();
964
965    usb_cleanup();
966
967    return 0;
968}
969
970int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
971{
972    atransport *transport = NULL;
973    char buf[4096];
974
975    if(!strcmp(service, "kill")) {
976        fprintf(stderr,"adb server killed by remote request\n");
977        fflush(stdout);
978        adb_write(reply_fd, "OKAY", 4);
979        usb_cleanup();
980        exit(0);
981    }
982
983#if ADB_HOST
984    // "transport:" is used for switching transport with a specified serial number
985    // "transport-usb:" is used for switching transport to the only USB transport
986    // "transport-local:" is used for switching transport to the only local transport
987    // "transport-any:" is used for switching transport to the only transport
988    if (!strncmp(service, "transport", strlen("transport"))) {
989        char* error_string = "unknown failure";
990        transport_type type = kTransportAny;
991
992        if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
993            type = kTransportUsb;
994        } else if (!strncmp(service, "transport-local", strlen("transport-local"))) {
995            type = kTransportLocal;
996        } else if (!strncmp(service, "transport-any", strlen("transport-any"))) {
997            type = kTransportAny;
998        } else if (!strncmp(service, "transport:", strlen("transport:"))) {
999            service += strlen("transport:");
1000            serial = strdup(service);
1001        }
1002
1003        transport = acquire_one_transport(CS_ANY, type, serial, &error_string);
1004
1005        if (transport) {
1006            s->transport = transport;
1007            adb_write(reply_fd, "OKAY", 4);
1008        } else {
1009            sendfailmsg(reply_fd, error_string);
1010        }
1011        return 1;
1012    }
1013
1014    // return a list of all connected devices
1015    if (!strcmp(service, "devices")) {
1016        char buffer[4096];
1017        memset(buf, 0, sizeof(buf));
1018        memset(buffer, 0, sizeof(buffer));
1019        D("Getting device list \n");
1020        list_transports(buffer, sizeof(buffer));
1021        snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer);
1022        D("Wrote device list \n");
1023        writex(reply_fd, buf, strlen(buf));
1024        return 0;
1025    }
1026
1027    // add a new TCP transport
1028    if (!strncmp(service, "connect:", 8)) {
1029        char buffer[4096];
1030        int port, fd;
1031        char* host = service + 8;
1032        char* portstr = strchr(host, ':');
1033
1034        if (!portstr) {
1035            snprintf(buffer, sizeof(buffer), "unable to parse %s as <host>:<port>", host);
1036            goto done;
1037        }
1038        if (find_transport(host)) {
1039            snprintf(buffer, sizeof(buffer), "Already connected to %s", host);
1040            goto done;
1041        }
1042
1043        // zero terminate host by overwriting the ':'
1044        *portstr++ = 0;
1045        if (sscanf(portstr, "%d", &port) == 0) {
1046            snprintf(buffer, sizeof(buffer), "bad port number %s", portstr);
1047            goto done;
1048        }
1049
1050        fd = socket_network_client(host, port, SOCK_STREAM);
1051        if (fd < 0) {
1052            snprintf(buffer, sizeof(buffer), "unable to connect to %s:%d", host, port);
1053            goto done;
1054        }
1055
1056        D("client: connected on remote on fd %d\n", fd);
1057        close_on_exec(fd);
1058        disable_tcp_nagle(fd);
1059        snprintf(buf, sizeof buf, "%s:%d", host, port);
1060        register_socket_transport(fd, buf, port, 0);
1061        snprintf(buffer, sizeof(buffer), "connected to %s:%d", host, port);
1062
1063done:
1064        snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer);
1065        writex(reply_fd, buf, strlen(buf));
1066        return 0;
1067    }
1068
1069    // remove TCP transport
1070    if (!strncmp(service, "disconnect:", 11)) {
1071        char buffer[4096];
1072        memset(buffer, 0, sizeof(buffer));
1073        char* serial = service + 11;
1074        atransport *t = find_transport(serial);
1075
1076        if (t) {
1077            unregister_transport(t);
1078        } else {
1079            snprintf(buffer, sizeof(buffer), "No such device %s", serial);
1080        }
1081
1082        snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer);
1083        writex(reply_fd, buf, strlen(buf));
1084        return 0;
1085    }
1086
1087    // returns our value for ADB_SERVER_VERSION
1088    if (!strcmp(service, "version")) {
1089        char version[12];
1090        snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION);
1091        snprintf(buf, sizeof buf, "OKAY%04x%s", (unsigned)strlen(version), version);
1092        writex(reply_fd, buf, strlen(buf));
1093        return 0;
1094    }
1095
1096    if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {
1097        char *out = "unknown";
1098         transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
1099       if (transport && transport->serial) {
1100            out = transport->serial;
1101        }
1102        snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out);
1103        writex(reply_fd, buf, strlen(buf));
1104        return 0;
1105    }
1106    // indicates a new emulator instance has started
1107    if (!strncmp(service,"emulator:",9)) {
1108        int  port = atoi(service+9);
1109        local_connect(port);
1110        /* we don't even need to send a reply */
1111        return 0;
1112    }
1113#endif // ADB_HOST
1114
1115    if(!strncmp(service,"forward:",8) || !strncmp(service,"killforward:",12)) {
1116        char *local, *remote, *err;
1117        int r;
1118        atransport *transport;
1119
1120        int createForward = strncmp(service,"kill",4);
1121
1122        local = service + (createForward ? 8 : 12);
1123        remote = strchr(local,';');
1124        if(remote == 0) {
1125            sendfailmsg(reply_fd, "malformed forward spec");
1126            return 0;
1127        }
1128
1129        *remote++ = 0;
1130        if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')){
1131            sendfailmsg(reply_fd, "malformed forward spec");
1132            return 0;
1133        }
1134
1135        transport = acquire_one_transport(CS_ANY, ttype, serial, &err);
1136        if (!transport) {
1137            sendfailmsg(reply_fd, err);
1138            return 0;
1139        }
1140
1141        if (createForward) {
1142            r = install_listener(local, remote, transport);
1143        } else {
1144            r = remove_listener(local, remote, transport);
1145        }
1146        if(r == 0) {
1147                /* 1st OKAY is connect, 2nd OKAY is status */
1148            writex(reply_fd, "OKAYOKAY", 8);
1149            return 0;
1150        }
1151
1152        if (createForward) {
1153            sendfailmsg(reply_fd, (r == -1) ? "cannot rebind smartsocket" : "cannot bind socket");
1154        } else {
1155            sendfailmsg(reply_fd, "cannot remove listener");
1156        }
1157        return 0;
1158    }
1159
1160    if(!strncmp(service,"get-state",strlen("get-state"))) {
1161        transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
1162        char *state = connection_state_name(transport);
1163        snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(state),state);
1164        writex(reply_fd, buf, strlen(buf));
1165        return 0;
1166    }
1167    return -1;
1168}
1169
1170#if !ADB_HOST
1171int recovery_mode = 0;
1172#endif
1173
1174int main(int argc, char **argv)
1175{
1176    adb_trace_init();
1177#if ADB_HOST
1178    adb_sysdeps_init();
1179    return adb_commandline(argc - 1, argv + 1);
1180#else
1181    if((argc > 1) && (!strcmp(argv[1],"recovery"))) {
1182        adb_device_banner = "recovery";
1183        recovery_mode = 1;
1184    }
1185
1186    start_device_log();
1187    return adb_main(0, DEFAULT_ADB_PORT);
1188#endif
1189}
1190