1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License.
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License.
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
17aed3c61c4437ebb05eadfb3bf85d6962c30b9935Yabin Cui#define TRACE_TAG ADB
183313426fad9eaaf53017cdbde889ebcec91358ecDan Albert
193313426fad9eaaf53017cdbde889ebcec91358ecDan Albert#include "sysdeps.h"
203313426fad9eaaf53017cdbde889ebcec91358ecDan Albert#include "adb.h"
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <ctype.h>
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h>
24ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#include <stdarg.h>
25c7993af64baec271a238646bc20aaa846866c4a9Scott Anderson#include <stddef.h>
26ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#include <stdint.h>
27ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#include <stdio.h>
28ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#include <stdlib.h>
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
301f546e6d1f6ccd1964336ddf0d8e8b3b11b1e945Mike Lockwood#include <sys/time.h>
31ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#include <time.h>
32ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert
33dbe91eee26300be10d6f1a0b42451dd46ea68538Elliott Hughes#include <chrono>
34fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao#include <condition_variable>
35fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao#include <mutex>
36ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#include <string>
37dbe91eee26300be10d6f1a0b42451dd46ea68538Elliott Hughes#include <thread>
38e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert#include <vector>
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
405f787ed2b3b9f6cc02aa5923b95d77e2a5865438David Pursell#include <android-base/errors.h>
4182ff315bb0fecb9127970e01b399be53c92ca14fElliott Hughes#include <android-base/file.h>
424f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/logging.h>
434f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/macros.h>
44706955ff0d159d28bb6eb06dc10178624c505f4eDavid Pursell#include <android-base/parsenetaddress.h>
451c70e1bcbcced190b351d4fb418f32b4e428f496Josh Gao#include <android-base/quick_exit.h>
464f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/stringprintf.h>
474f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/strings.h>
487b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes
49d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#include "adb_auth.h"
50cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert#include "adb_io.h"
51e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert#include "adb_listeners.h"
526eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes#include "adb_unique_fd.h"
533d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes#include "adb_utils.h"
54fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao#include "sysdeps/chrono.h"
557664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include "transport.h"
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if !ADB_HOST
58e2864bf727d6a404bd871f063c03e36cc8eedeecNick Kralevich#include <sys/capability.h>
59885342a0f2c834a6b680284047c47c9d04b32565Jeff Sharkey#include <sys/mount.h>
60ffdec180176094dac0fb902263370dea1deb138fElliott Hughes#include <android-base/properties.h>
61dbe91eee26300be10d6f1a0b42451dd46ea68538Elliott Hughesusing namespace std::chrono_literals;
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
6442ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughesstd::string adb_version() {
6542ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes    // Don't change the format of this --- it's parsed by ddmlib.
661fd46dfa7266337324ca4429676a278a904192baElliott Hughes    return android::base::StringPrintf(
671fd46dfa7266337324ca4429676a278a904192baElliott Hughes        "Android Debug Bridge version %d.%d.%d\n"
684d4f64ff94e8c03d0c2e7b7ccfa7c48ca2345087Elliott Hughes        "Version %s\n"
691fd46dfa7266337324ca4429676a278a904192baElliott Hughes        "Installed as %s\n",
704d4f64ff94e8c03d0c2e7b7ccfa7c48ca2345087Elliott Hughes        ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION, ADB_VERSION,
711fd46dfa7266337324ca4429676a278a904192baElliott Hughes        android::base::GetExecutablePath().c_str());
7242ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes}
7342ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes
749313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertvoid fatal(const char *fmt, ...) {
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_list ap;
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_start(ap, fmt);
774abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao    char buf[1024];
784abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao    vsnprintf(buf, sizeof(buf), fmt, ap);
794abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao
804abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao#if ADB_HOST
814abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao    fprintf(stderr, "error: %s\n", buf);
824abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao#else
834abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao    LOG(ERROR) << "error: " << buf;
844abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao#endif
854abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_end(ap);
874abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao    abort();
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
909313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertvoid fatal_errno(const char* fmt, ...) {
914abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao    int err = errno;
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_list ap;
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_start(ap, fmt);
944abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao    char buf[1024];
954abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao    vsnprintf(buf, sizeof(buf), fmt, ap);
964abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao
974abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao#if ADB_HOST
984abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao    fprintf(stderr, "error: %s: %s\n", buf, strerror(err));
994abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao#else
1004abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao    LOG(ERROR) << "error: " << buf << ": " << strerror(err);
1014abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao#endif
1024abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_end(ap);
1044abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao    abort();
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
10706d61d4d96d28777f76578fb5d3c823168853166Josh Gaouint32_t calculate_apacket_checksum(const apacket* p) {
10806d61d4d96d28777f76578fb5d3c823168853166Josh Gao    const unsigned char* x = reinterpret_cast<const unsigned char*>(p->data);
10906d61d4d96d28777f76578fb5d3c823168853166Josh Gao    uint32_t sum = 0;
11006d61d4d96d28777f76578fb5d3c823168853166Josh Gao    size_t count = p->msg.data_length;
11106d61d4d96d28777f76578fb5d3c823168853166Josh Gao
11206d61d4d96d28777f76578fb5d3c823168853166Josh Gao    while (count-- > 0) {
11306d61d4d96d28777f76578fb5d3c823168853166Josh Gao        sum += *x++;
11406d61d4d96d28777f76578fb5d3c823168853166Josh Gao    }
11506d61d4d96d28777f76578fb5d3c823168853166Josh Gao
11606d61d4d96d28777f76578fb5d3c823168853166Josh Gao    return sum;
11706d61d4d96d28777f76578fb5d3c823168853166Josh Gao}
11806d61d4d96d28777f76578fb5d3c823168853166Josh Gao
119bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albertapacket* get_apacket(void)
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
121bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert    apacket* p = reinterpret_cast<apacket*>(malloc(sizeof(apacket)));
122bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert    if (p == nullptr) {
123bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert      fatal("failed to allocate an apacket");
124bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert    }
125bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memset(p, 0, sizeof(apacket) - MAX_PAYLOAD);
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return p;
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid put_apacket(apacket *p)
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    free(p);
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
135d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobyvoid handle_online(atransport *t)
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1377a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui    D("adb: online");
138d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    t->online = 1;
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid handle_offline(atransport *t)
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1437a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui    D("adb: offline");
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //Close the associated usb
145d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    t->online = 0;
14634f45c566365c966c78264e8a4dc0cf69957b6faYabin Cui
147b329824e6c5373ae303269dca285d835ce57e514Yabin Cui    // This is necessary to avoid a race condition that occurred when a transport closes
14834f45c566365c966c78264e8a4dc0cf69957b6faYabin Cui    // while a client socket is still active.
14934f45c566365c966c78264e8a4dc0cf69957b6faYabin Cui    close_all_sockets(t);
15034f45c566365c966c78264e8a4dc0cf69957b6faYabin Cui
151b329824e6c5373ae303269dca285d835ce57e514Yabin Cui    t->RunDisconnects();
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
154d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#if DEBUG_PACKETS
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define DUMPMAX 32
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid print_packet(const char *label, apacket *p)
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *tag;
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *x;
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned count;
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch(p->msg.command){
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_SYNC: tag = "SYNC"; break;
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_CNXN: tag = "CNXN" ; break;
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_OPEN: tag = "OPEN"; break;
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_OKAY: tag = "OKAY"; break;
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_CLSE: tag = "CLSE"; break;
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_WRTE: tag = "WRTE"; break;
169d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    case A_AUTH: tag = "AUTH"; break;
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    default: tag = "????"; break;
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr, "%s: %s %08x %08x %04x \"",
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length);
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    count = p->msg.data_length;
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    x = (char*) p->data;
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(count > DUMPMAX) {
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        count = DUMPMAX;
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        tag = "\n";
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        tag = "\"\n";
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while(count-- > 0){
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if((*x >= ' ') && (*x < 127)) {
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fputc(*x, stderr);
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fputc('.', stderr);
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        x++;
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
191d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    fputs(tag, stderr);
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void send_ready(unsigned local, unsigned remote, atransport *t)
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1977a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui    D("Calling send_ready");
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    apacket *p = get_apacket();
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p->msg.command = A_OKAY;
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p->msg.arg0 = local;
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p->msg.arg1 = remote;
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    send_packet(p, t);
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void send_close(unsigned local, unsigned remote, atransport *t)
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
2077a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui    D("Calling send_close");
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    apacket *p = get_apacket();
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p->msg.command = A_CLSE;
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p->msg.arg0 = local;
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p->msg.arg1 = remote;
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    send_packet(p, t);
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
2151792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albertstd::string get_connection_string() {
2161792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    std::vector<std::string> connection_properties;
2171792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert
2181792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert#if !ADB_HOST
2191792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    static const char* cnxn_props[] = {
220e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson        "ro.product.name",
221e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson        "ro.product.model",
222e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson        "ro.product.device",
223e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson    };
2241792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert
225ffdec180176094dac0fb902263370dea1deb138fElliott Hughes    for (const auto& prop : cnxn_props) {
226ffdec180176094dac0fb902263370dea1deb138fElliott Hughes        std::string value = std::string(prop) + "=" + android::base::GetProperty(prop, "");
227ffdec180176094dac0fb902263370dea1deb138fElliott Hughes        connection_properties.push_back(value);
228e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson    }
229e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson#endif
2301792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert
2311792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    connection_properties.push_back(android::base::StringPrintf(
2324e2fd36bc8c16147cab323b0418a7666812d3bc7David Pursell        "features=%s", FeatureSetToString(supported_features()).c_str()));
2331792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert
2341792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    return android::base::StringPrintf(
2351792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert        "%s::%s", adb_device_banner,
2361792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert        android::base::Join(connection_properties, ';').c_str());
237e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson}
238e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson
2391792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albertvoid send_connect(atransport* t) {
2407a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui    D("Calling send_connect");
2411792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    apacket* cp = get_apacket();
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    cp->msg.command = A_CNXN;
2433d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer    cp->msg.arg0 = t->get_protocol_version();
2443d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer    cp->msg.arg1 = t->get_max_payload();
2451792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert
2461792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    std::string connection_str = get_connection_string();
2471792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    // Connect and auth packets are limited to MAX_PAYLOAD_V1 because we don't
2481792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    // yet know how much data the other size is willing to accept.
2491792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    if (connection_str.length() > MAX_PAYLOAD_V1) {
2501792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert        LOG(FATAL) << "Connection banner is too long (length = "
2511792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert                   << connection_str.length() << ")";
2521792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    }
2531792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert
2541792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    memcpy(cp->data, connection_str.c_str(), connection_str.length());
2551792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    cp->msg.data_length = connection_str.length();
2561792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    send_packet(cp, t);
258d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby}
259d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
2608d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes// qual_overwrite is used to overwrite a qualifier string.  dst is a
2618d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes// pointer to a char pointer.  It is assumed that if *dst is non-NULL, it
2628d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes// was malloc'ed and needs to freed.  *dst will be set to a dup of src.
2638d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes// TODO: switch to std::string for these atransport fields instead.
2648d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughesstatic void qual_overwrite(char** dst, const std::string& src) {
265e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson    free(*dst);
2668d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    *dst = strdup(src.c_str());
267e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson}
268e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson
2691792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albertvoid parse_banner(const std::string& banner, atransport* t) {
2707a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui    D("parse_banner: %s", banner.c_str());
2718d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes
2728d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    // The format is something like:
2738d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    // "device::ro.product.name=x;ro.product.model=y;ro.product.device=z;".
2748d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    std::vector<std::string> pieces = android::base::Split(banner, ":");
2758d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes
276d2b588e23901538f4b459a71fefdac6fc2748f7eDavid Pursell    // Reset the features list or else if the server sends no features we may
277d2b588e23901538f4b459a71fefdac6fc2748f7eDavid Pursell    // keep the existing feature set (http://b/24405971).
278d2b588e23901538f4b459a71fefdac6fc2748f7eDavid Pursell    t->SetFeatures("");
279d2b588e23901538f4b459a71fefdac6fc2748f7eDavid Pursell
2808d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    if (pieces.size() > 2) {
2818d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes        const std::string& props = pieces[2];
28265fe2516b402ed8903f2ce39a86fa0bdc2b263a6Elliott Hughes        for (const auto& prop : android::base::Split(props, ";")) {
2838d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes            // The list of properties was traditionally ;-terminated rather than ;-separated.
2848d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes            if (prop.empty()) continue;
2858d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes
2868d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes            std::vector<std::string> key_value = android::base::Split(prop, "=");
2878d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes            if (key_value.size() != 2) continue;
2888d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes
2898d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes            const std::string& key = key_value[0];
2908d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes            const std::string& value = key_value[1];
2918d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes            if (key == "ro.product.name") {
2928d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes                qual_overwrite(&t->product, value);
2938d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes            } else if (key == "ro.product.model") {
2948d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes                qual_overwrite(&t->model, value);
2958d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes            } else if (key == "ro.product.device") {
2968d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes                qual_overwrite(&t->device, value);
2971792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert            } else if (key == "features") {
2984e2fd36bc8c16147cab323b0418a7666812d3bc7David Pursell                t->SetFeatures(value);
299e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson            }
300e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson        }
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
3038d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    const std::string& type = pieces[0];
3048d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    if (type == "bootloader") {
3057a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui        D("setting connection_state to kCsBootloader");
306b5e11415d9fdb929321c66889063dac50fb737afYabin Cui        t->SetConnectionState(kCsBootloader);
3078d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    } else if (type == "device") {
3087a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui        D("setting connection_state to kCsDevice");
309b5e11415d9fdb929321c66889063dac50fb737afYabin Cui        t->SetConnectionState(kCsDevice);
3108d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    } else if (type == "recovery") {
3117a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui        D("setting connection_state to kCsRecovery");
312b5e11415d9fdb929321c66889063dac50fb737afYabin Cui        t->SetConnectionState(kCsRecovery);
3138d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    } else if (type == "sideload") {
3147a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui        D("setting connection_state to kCsSideload");
315b5e11415d9fdb929321c66889063dac50fb737afYabin Cui        t->SetConnectionState(kCsSideload);
3163ce9575af76fa6dc110506080434303b9459abf4Elliott Hughes    } else {
3177a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui        D("setting connection_state to kCsHost");
318b5e11415d9fdb929321c66889063dac50fb737afYabin Cui        t->SetConnectionState(kCsHost);
319447f061da19fe46bae35f1cdd93eeb16bc225463Doug Zongker    }
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
3221792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albertstatic void handle_new_connection(atransport* t, apacket* p) {
323b5e11415d9fdb929321c66889063dac50fb737afYabin Cui    if (t->GetConnectionState() != kCsOffline) {
324b5e11415d9fdb929321c66889063dac50fb737afYabin Cui        t->SetConnectionState(kCsOffline);
3251792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert        handle_offline(t);
3261792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    }
3271792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert
3281792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    t->update_version(p->msg.arg0, p->msg.arg1);
3291792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    std::string banner(reinterpret_cast<const char*>(p->data),
3301792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert                       p->msg.data_length);
3311792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    parse_banner(banner, t);
3321792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert
3331792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert#if ADB_HOST
3341792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    handle_online(t);
3351792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert#else
3361792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    if (!auth_required) {
3371792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert        handle_online(t);
3381792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert        send_connect(t);
3391792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    } else {
3401792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert        send_auth_request(t);
3411792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    }
3421792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert#endif
343fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao
344fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao    update_transports();
3451792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert}
3461792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert
347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid handle_packet(apacket *p, atransport *t)
348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
3497a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui    D("handle_packet() %c%c%c%c", ((char*) (&(p->msg.command)))[0],
350899913f8168b54e00971c0e8d4ae16d06a4651feViral Mehta            ((char*) (&(p->msg.command)))[1],
351899913f8168b54e00971c0e8d4ae16d06a4651feViral Mehta            ((char*) (&(p->msg.command)))[2],
352899913f8168b54e00971c0e8d4ae16d06a4651feViral Mehta            ((char*) (&(p->msg.command)))[3]);
353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    print_packet("recv", p);
354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch(p->msg.command){
356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_SYNC:
357ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes        if (p->msg.arg0){
358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            send_packet(p, t);
359661327e8e40f95076e0e8abe86193da16b061bd8Yabin Cui#if ADB_HOST
36085366c15d4e45f453835f2261020acedf6b51babJosh Gao            send_connect(t);
361661327e8e40f95076e0e8abe86193da16b061bd8Yabin Cui#endif
362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
363b5e11415d9fdb929321c66889063dac50fb737afYabin Cui            t->SetConnectionState(kCsOffline);
364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            handle_offline(t);
365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            send_packet(p, t);
366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
3691792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert    case A_CNXN:  // CONNECT(version, maxdata, "system-id-string")
3701792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert        handle_new_connection(t, p);
371d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        break;
372d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
373d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    case A_AUTH:
3743bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao        switch (p->msg.arg0) {
3753bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao#if ADB_HOST
3763bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao            case ADB_AUTH_TOKEN:
377b5e11415d9fdb929321c66889063dac50fb737afYabin Cui                if (t->GetConnectionState() == kCsOffline) {
378b5e11415d9fdb929321c66889063dac50fb737afYabin Cui                    t->SetConnectionState(kCsUnauthorized);
379b5e11415d9fdb929321c66889063dac50fb737afYabin Cui                }
3803bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao                send_auth_response(p->data, p->msg.data_length, t);
3813bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao                break;
3823bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao#else
3833bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao            case ADB_AUTH_SIGNATURE:
3843bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao                if (adbd_auth_verify(t->token, sizeof(t->token), p->data, p->msg.data_length)) {
3853bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao                    adbd_auth_verified(t);
3863bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao                    t->failed_auth_attempts = 0;
3873bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao                } else {
388dbe91eee26300be10d6f1a0b42451dd46ea68538Elliott Hughes                    if (t->failed_auth_attempts++ > 256) std::this_thread::sleep_for(1s);
3893bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao                    send_auth_request(t);
3903bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao                }
3913bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao                break;
3923bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao
3933bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao            case ADB_AUTH_RSAPUBLICKEY:
3943bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao                adbd_auth_confirm_key(p->data, p->msg.data_length, t);
3953bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao                break;
3963bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao#endif
3973bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao            default:
398b5e11415d9fdb929321c66889063dac50fb737afYabin Cui                t->SetConnectionState(kCsOffline);
3993bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao                handle_offline(t);
4003bd2879d8e9bb0c0a1b8045e09f9cf87c2daeef3Josh Gao                break;
401d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        }
402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_OPEN: /* OPEN(local-id, 0, "destination") */
405818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner        if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) {
406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            char *name = (char*) p->data;
407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
408ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes            asocket* s = create_local_service_socket(name, t);
409ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes            if (s == nullptr) {
410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                send_close(0, p->msg.arg0, t);
411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                s->peer = create_remote_socket(p->msg.arg0, t);
413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                s->peer->peer = s;
414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                send_ready(s->id, s->peer->id, t);
415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                s->ready(s);
416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_OKAY: /* READY(local-id, remote-id, "") */
421818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner        if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
422ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes            asocket* s = find_local_socket(p->msg.arg1, 0);
423ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes            if (s) {
424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if(s->peer == 0) {
425818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                    /* On first READY message, create the connection. */
426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    s->peer = create_remote_socket(p->msg.arg0, t);
427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    s->peer->peer = s;
428818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                    s->ready(s);
429818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                } else if (s->peer->id == p->msg.arg0) {
430818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                    /* Other READY messages must use the same local-id */
431818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                    s->ready(s);
432818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                } else {
4337a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui                    D("Invalid A_OKAY(%d,%d), expected A_OKAY(%d,%d) on transport %s",
434818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                      p->msg.arg0, p->msg.arg1, s->peer->id, p->msg.arg1, t->serial);
435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
436aa77e22d7384a97757e2d2194f4e265f7ad3b71aYabin Cui            } else {
437aa77e22d7384a97757e2d2194f4e265f7ad3b71aYabin Cui                // When receiving A_OKAY from device for A_OPEN request, the host server may
438aa77e22d7384a97757e2d2194f4e265f7ad3b71aYabin Cui                // have closed the local socket because of client disconnection. Then we need
439aa77e22d7384a97757e2d2194f4e265f7ad3b71aYabin Cui                // to send A_CLSE back to device to close the service on device.
440aa77e22d7384a97757e2d2194f4e265f7ad3b71aYabin Cui                send_close(p->msg.arg1, p->msg.arg0, t);
441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
445818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner    case A_CLSE: /* CLOSE(local-id, remote-id, "") or CLOSE(0, remote-id, "") */
446818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner        if (t->online && p->msg.arg1 != 0) {
447ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes            asocket* s = find_local_socket(p->msg.arg1, p->msg.arg0);
448ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes            if (s) {
449818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                /* According to protocol.txt, p->msg.arg0 might be 0 to indicate
450818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                 * a failed OPEN only. However, due to a bug in previous ADB
451818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                 * versions, CLOSE(0, remote-id, "") was also used for normal
452818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                 * CLOSE() operations.
453818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                 *
454818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                 * This is bad because it means a compromised adbd could
455818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                 * send packets to close connections between the host and
456818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                 * other devices. To avoid this, only allow this if the local
457818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                 * socket has a peer on the same transport.
458818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                 */
459818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                if (p->msg.arg0 == 0 && s->peer && s->peer->transport != t) {
4607a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui                    D("Invalid A_CLSE(0, %u) from transport %s, expected transport %s",
461818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                      p->msg.arg1, t->serial, s->peer->transport->serial);
462818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                } else {
463818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                    s->close(s);
464818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                }
465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
469818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner    case A_WRTE: /* WRITE(local-id, remote-id, <data>) */
470818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner        if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
471ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes            asocket* s = find_local_socket(p->msg.arg1, p->msg.arg0);
472ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes            if (s) {
473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                unsigned rid = p->msg.arg0;
474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                p->len = p->msg.data_length;
475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
476ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes                if (s->enqueue(s, p) == 0) {
4777a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui                    D("Enqueue the socket");
478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    send_ready(s->id, rid, t);
479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return;
481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    default:
486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("handle_packet: what is %08x?!\n", p->msg.command);
487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    put_apacket(p);
490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST
493571c1367682c83cb23481cc9c1028c8588a1fed0JP Abgrall
4942122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low#ifdef _WIN32
4952122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
496bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low// Try to make a handle non-inheritable and if there is an error, don't output
497bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low// any error info, but leave GetLastError() for the caller to read. This is
498bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low// convenient if the caller is expecting that this may fail and they'd like to
499bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low// ignore such a failure.
500bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Lowstatic bool _try_make_handle_noninheritable(HANDLE h) {
5012122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    if (h != INVALID_HANDLE_VALUE && h != NULL) {
502bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low        return SetHandleInformation(h, HANDLE_FLAG_INHERIT, 0) ? true : false;
503bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low    }
504bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low
505bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low    return true;
506bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low}
507bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low
508bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low// Try to make a handle non-inheritable with the expectation that this should
509bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low// succeed, so if this fails, output error info.
510bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Lowstatic bool _make_handle_noninheritable(HANDLE h) {
511bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low    if (!_try_make_handle_noninheritable(h)) {
512bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low        // Show the handle value to give us a clue in case we have problems
513bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low        // with pseudo-handle values.
5141fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes        fprintf(stderr, "adb: cannot make handle 0x%p non-inheritable: %s\n", h,
5151fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes                android::base::SystemErrorCodeToString(GetLastError()).c_str());
516bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low        return false;
5172122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    }
5182122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
5192122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    return true;
5202122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low}
5212122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
5222122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low// Create anonymous pipe, preventing inheritance of the read pipe and setting
5232122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low// security of the write pipe to sa.
5242122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Lowstatic bool _create_anonymous_pipe(unique_handle* pipe_read_out,
5252122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low                                   unique_handle* pipe_write_out,
5262122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low                                   SECURITY_ATTRIBUTES* sa) {
5272122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    HANDLE pipe_read_raw = NULL;
5282122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    HANDLE pipe_write_raw = NULL;
5292122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    if (!CreatePipe(&pipe_read_raw, &pipe_write_raw, sa, 0)) {
5301fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes        fprintf(stderr, "adb: CreatePipe failed: %s\n",
5315f787ed2b3b9f6cc02aa5923b95d77e2a5865438David Pursell                android::base::SystemErrorCodeToString(GetLastError()).c_str());
5322122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        return false;
5332122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    }
5342122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
5352122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    unique_handle pipe_read(pipe_read_raw);
5362122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    pipe_read_raw = NULL;
5372122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    unique_handle pipe_write(pipe_write_raw);
5382122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    pipe_write_raw = NULL;
5392122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
5402122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    if (!_make_handle_noninheritable(pipe_read.get())) {
5412122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        return false;
5422122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    }
5432122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
5442122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    *pipe_read_out = std::move(pipe_read);
5452122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    *pipe_write_out = std::move(pipe_write);
5462122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
5472122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    return true;
5482122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low}
5492122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
55053a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low// Read from a pipe (that we take ownership of) and write the result to stdout/stderr. Return on
55153a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low// error or when the pipe is closed. Internally makes inheritable handles, so this should not be
55253a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low// called if subprocesses may be started concurrently.
5532122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Lowstatic unsigned _redirect_pipe_thread(HANDLE h, DWORD nStdHandle) {
5542122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // Take ownership of the HANDLE and close when we're done.
5552122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    unique_handle   read_pipe(h);
55653a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low    const char*     output_name = nStdHandle == STD_OUTPUT_HANDLE ? "stdout" : "stderr";
55753a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low    const int       original_fd = fileno(nStdHandle == STD_OUTPUT_HANDLE ? stdout : stderr);
55853a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low    std::unique_ptr<FILE, decltype(&fclose)> stream(nullptr, fclose);
55953a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low
56053a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low    if (original_fd == -1) {
5611fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes        fprintf(stderr, "adb: failed to get file descriptor for %s: %s\n", output_name,
5621fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes                strerror(errno));
56353a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        return EXIT_FAILURE;
56453a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low    }
56553a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low
56653a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low    // If fileno() is -2, stdout/stderr is not associated with an output stream, so we should read,
56753a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low    // but don't write. Otherwise, make a FILE* identical to stdout/stderr except that it is in
56853a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low    // binary mode with no CR/LR translation since we're reading raw.
56953a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low    if (original_fd >= 0) {
57053a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        // This internally makes a duplicate file handle that is inheritable, so callers should not
57153a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        // call this function if subprocesses may be started concurrently.
57253a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        const int fd = dup(original_fd);
57353a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        if (fd == -1) {
5741fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes            fprintf(stderr, "adb: failed to duplicate file descriptor for %s: %s\n", output_name,
57553a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low                    strerror(errno));
57653a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low            return EXIT_FAILURE;
57753a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        }
57853a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low
57953a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        // Note that although we call fdopen() below with a binary flag, it may not adhere to that
58053a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        // flag, so we have to set the mode manually.
58153a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        if (_setmode(fd, _O_BINARY) == -1) {
5821fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes            fprintf(stderr, "adb: failed to set binary mode for duplicate of %s: %s\n", output_name,
58353a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low                    strerror(errno));
58453a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low            unix_close(fd);
58553a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low            return EXIT_FAILURE;
58653a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        }
58753a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low
58853a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        stream.reset(fdopen(fd, "wb"));
58953a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        if (stream.get() == nullptr) {
5901fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes            fprintf(stderr, "adb: failed to open duplicate stream for %s: %s\n", output_name,
59153a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low                    strerror(errno));
59253a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low            unix_close(fd);
59353a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low            return EXIT_FAILURE;
59453a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        }
59553a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low
59653a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        // Unbuffer the stream because it will be buffered by default and we want subprocess output
59753a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        // to be shown immediately.
59853a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        if (setvbuf(stream.get(), NULL, _IONBF, 0) == -1) {
5991fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes            fprintf(stderr, "adb: failed to unbuffer %s: %s\n", output_name, strerror(errno));
60053a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low            return EXIT_FAILURE;
60153a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        }
60253a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low
60353a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        // fd will be closed when stream is closed.
60453a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low    }
6052122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
6062122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    while (true) {
6072122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        char    buf[64 * 1024];
6082122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        DWORD   bytes_read = 0;
6092122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        if (!ReadFile(read_pipe.get(), buf, sizeof(buf), &bytes_read, NULL)) {
6102122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            const DWORD err = GetLastError();
6112122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            // ERROR_BROKEN_PIPE is expected when the subprocess closes
6122122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            // the other end of the pipe.
6132122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            if (err == ERROR_BROKEN_PIPE) {
6142122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low                return EXIT_SUCCESS;
6152122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            } else {
6161fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes                fprintf(stderr, "adb: failed to read from %s: %s\n", output_name,
6175f787ed2b3b9f6cc02aa5923b95d77e2a5865438David Pursell                        android::base::SystemErrorCodeToString(err).c_str());
6182122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low                return EXIT_FAILURE;
6192122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            }
6202122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        }
6212122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
62253a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        // Don't try to write if our stdout/stderr was not setup by the parent process.
62353a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low        if (stream) {
62453a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low            // fwrite() actually calls adb_fwrite() which can write UTF-8 to the console.
62553a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low            const size_t bytes_written = fwrite(buf, 1, bytes_read, stream.get());
6262122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            if (bytes_written != bytes_read) {
6271fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes                fprintf(stderr, "adb: error: only wrote %zu of %lu bytes to %s\n", bytes_written,
6281fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes                        bytes_read, output_name);
6292122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low                return EXIT_FAILURE;
6302122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            }
6312122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        }
6322122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    }
6332122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low}
6342122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
6352122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Lowstatic unsigned __stdcall _redirect_stdout_thread(HANDLE h) {
63649ee7cf9a10f66ffa9a3490c69db5fa46e0a966bSiva Velusamy    adb_thread_setname("stdout redirect");
6372122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    return _redirect_pipe_thread(h, STD_OUTPUT_HANDLE);
6382122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low}
6392122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
6402122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Lowstatic unsigned __stdcall _redirect_stderr_thread(HANDLE h) {
64149ee7cf9a10f66ffa9a3490c69db5fa46e0a966bSiva Velusamy    adb_thread_setname("stderr redirect");
6422122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    return _redirect_pipe_thread(h, STD_ERROR_HANDLE);
6432122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low}
6442122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
6452122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low#endif
6462122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
6476eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughesstatic void ReportServerStartupFailure(pid_t pid) {
6486eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    fprintf(stderr, "ADB server didn't ACK\n");
6496eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    fprintf(stderr, "Full server startup log: %s\n", GetLogFilePath().c_str());
6506eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    fprintf(stderr, "Server had pid: %d\n", pid);
6516eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes
6526eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    unique_fd fd(adb_open(GetLogFilePath().c_str(), O_RDONLY));
6536eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    if (fd == -1) return;
6546eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes
6556eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    // Let's not show more than 128KiB of log...
6566eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    adb_lseek(fd, -128 * 1024, SEEK_END);
6576eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    std::string content;
6586eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    if (!android::base::ReadFdToString(fd, &content)) return;
6596eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes
6606eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    std::string header = android::base::StringPrintf("--- adb starting (pid %d) ---", pid);
6616eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    std::vector<std::string> lines = android::base::Split(content, "\n");
6626eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    int i = lines.size() - 1;
6636eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    while (i >= 0 && lines[i] != header) --i;
6646eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    while (static_cast<size_t>(i) < lines.size()) fprintf(stderr, "%s\n", lines[i++].c_str());
6656eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes}
6666eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes
6679c869b58a8cf4f7c3bc88931fbd27d3f5187b2dbJosh Gaoint launch_server(const std::string& socket_spec) {
668e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui#if defined(_WIN32)
669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* we need to start the server in the background                    */
670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* we create a PIPE that will be used to wait for the server's "OK" */
671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* message since the pipe handles must be inheritable, we use a     */
672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* security attribute                                               */
673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SECURITY_ATTRIBUTES   sa;
674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sa.nLength = sizeof(sa);
675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sa.lpSecurityDescriptor = NULL;
676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sa.bInheritHandle = TRUE;
677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
6782122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // Redirect stdin to Windows /dev/null. If we instead pass an original
6792122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // stdin/stdout/stderr handle and it is a console handle, when the adb
6802122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // server starts up, the C Runtime will see a console handle for a process
6812122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // that isn't connected to a console and it will configure
6822122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // stdin/stdout/stderr to be closed. At that point, freopen() could be used
6832122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // to reopen stderr/out, but it would take more massaging to fixup the file
6842122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // descriptor number that freopen() uses. It's simplest to avoid all of this
6852122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // complexity by just redirecting stdin to `nul' and then the C Runtime acts
6862122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // as expected.
6872122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    unique_handle   nul_read(CreateFileW(L"nul", GENERIC_READ,
6882122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_EXISTING,
6892122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            FILE_ATTRIBUTE_NORMAL, NULL));
6902122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    if (nul_read.get() == INVALID_HANDLE_VALUE) {
6911fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes        fprintf(stderr, "adb: CreateFileW 'nul' failed: %s\n",
6925f787ed2b3b9f6cc02aa5923b95d77e2a5865438David Pursell                android::base::SystemErrorCodeToString(GetLastError()).c_str());
693d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low        return -1;
694d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low    }
695d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low
69653a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low    // Create pipes with non-inheritable read handle, inheritable write handle. We need to connect
69753a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low    // the subprocess to pipes instead of just letting the subprocess inherit our existing
69853a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low    // stdout/stderr handles because a DETACHED_PROCESS cannot write to a console that it is not
69953a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low    // attached to.
7002122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    unique_handle   ack_read, ack_write;
7012122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    if (!_create_anonymous_pipe(&ack_read, &ack_write, &sa)) {
702d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low        return -1;
703d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low    }
7042122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    unique_handle   stdout_read, stdout_write;
7052122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    if (!_create_anonymous_pipe(&stdout_read, &stdout_write, &sa)) {
7062122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        return -1;
7072122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    }
7082122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    unique_handle   stderr_read, stderr_write;
7092122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    if (!_create_anonymous_pipe(&stderr_read, &stderr_write, &sa)) {
710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
713267aa8b00eadf273321e492026af74b7baad890eRay Donnelly    /* Some programs want to launch an adb command and collect its output by
714267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     * calling CreateProcess with inheritable stdout/stderr handles, then
715267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     * using read() to get its output. When this happens, the stdout/stderr
716267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     * handles passed to the adb client process will also be inheritable.
717267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     * When starting the adb server here, care must be taken to reset them
718267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     * to non-inheritable.
719267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     * Otherwise, something bad happens: even if the adb command completes,
720267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     * the calling process is stuck while read()-ing from the stdout/stderr
721267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     * descriptors, because they're connected to corresponding handles in the
722267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     * adb server process (even if the latter never uses/writes to them).
7232122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low     * Note that even if we don't pass these handles in the STARTUPINFO struct,
7242122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low     * if they're marked inheritable, they're still inherited, requiring us to
7252122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low     * deal with this.
7262122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low     *
7272122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low     * If we're still having problems with inheriting random handles in the
7282122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low     * future, consider using PROC_THREAD_ATTRIBUTE_HANDLE_LIST to explicitly
7292122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low     * specify which handles should be inherited: http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx
730bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low     *
731bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low     * Older versions of Windows return console pseudo-handles that cannot be
732bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low     * made non-inheritable, so ignore those failures.
733267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     */
734bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low    _try_make_handle_noninheritable(GetStdHandle(STD_INPUT_HANDLE));
735bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low    _try_make_handle_noninheritable(GetStdHandle(STD_OUTPUT_HANDLE));
736bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low    _try_make_handle_noninheritable(GetStdHandle(STD_ERROR_HANDLE));
737267aa8b00eadf273321e492026af74b7baad890eRay Donnelly
7382122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    STARTUPINFOW    startup;
739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ZeroMemory( &startup, sizeof(startup) );
740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    startup.cb = sizeof(startup);
7412122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    startup.hStdInput  = nul_read.get();
7422122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    startup.hStdOutput = stdout_write.get();
7432122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    startup.hStdError  = stderr_write.get();
744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    startup.dwFlags    = STARTF_USESTDHANDLES;
745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
7465c398d2ce96150e94e596e959bfe2246b94de660Spencer Low    // Verify that the pipe_write handle value can be passed on the command line
7475c398d2ce96150e94e596e959bfe2246b94de660Spencer Low    // as %d and that the rest of adb code can pass it around in an int.
7482122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    const int ack_write_as_int = cast_handle_to_int(ack_write.get());
7492122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    if (cast_int_to_handle(ack_write_as_int) != ack_write.get()) {
7505c398d2ce96150e94e596e959bfe2246b94de660Spencer Low        // If this fires, either handle values are larger than 32-bits or else
7515c398d2ce96150e94e596e959bfe2246b94de660Spencer Low        // there is a bug in our casting.
7525c398d2ce96150e94e596e959bfe2246b94de660Spencer Low        // https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx
7531fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes        fprintf(stderr, "adb: cannot fit pipe handle value into 32-bits: 0x%p\n", ack_write.get());
7545c398d2ce96150e94e596e959bfe2246b94de660Spencer Low        return -1;
7555c398d2ce96150e94e596e959bfe2246b94de660Spencer Low    }
7565c398d2ce96150e94e596e959bfe2246b94de660Spencer Low
7572122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // get path of current program
7582122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    WCHAR       program_path[MAX_PATH];
7592122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    const DWORD module_result = GetModuleFileNameW(NULL, program_path,
7602122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low                                                   arraysize(program_path));
7612122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    if ((module_result >= arraysize(program_path)) || (module_result == 0)) {
7622122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        // String truncation or some other error.
7631fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes        fprintf(stderr, "adb: cannot get executable path: %s\n",
7645f787ed2b3b9f6cc02aa5923b95d77e2a5865438David Pursell                android::base::SystemErrorCodeToString(GetLastError()).c_str());
7652122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        return -1;
7662122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    }
7672122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
7682122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    WCHAR   args[64];
7699c869b58a8cf4f7c3bc88931fbd27d3f5187b2dbJosh Gao    snwprintf(args, arraysize(args), L"adb -L %s fork-server server --reply-fd %d",
7709c869b58a8cf4f7c3bc88931fbd27d3f5187b2dbJosh Gao              socket_spec.c_str(), ack_write_as_int);
7712122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
7722122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    PROCESS_INFORMATION   pinfo;
7732122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    ZeroMemory(&pinfo, sizeof(pinfo));
7742122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
7752122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    if (!CreateProcessW(
776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            program_path,                              /* program path  */
777a09558c2e205771e6830eeb6241c5c0e3b1cf4ceWenhao Li            args,
778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                    /* the fork-server argument will set the
779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                       debug = 2 in the child           */
780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            NULL,                   /* process handle is not inheritable */
781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            NULL,                    /* thread handle is not inheritable */
782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            TRUE,                          /* yes, inherit some handles */
783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            DETACHED_PROCESS, /* the new process doesn't have a console */
784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            NULL,                     /* use parent's environment block */
785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            NULL,                    /* use parent's starting directory */
786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            &startup,                 /* startup info, i.e. std handles */
7872122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            &pinfo )) {
7881fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes        fprintf(stderr, "adb: CreateProcessW failed: %s\n",
7895f787ed2b3b9f6cc02aa5923b95d77e2a5865438David Pursell                android::base::SystemErrorCodeToString(GetLastError()).c_str());
7902122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        return -1;
7912122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    }
792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
7932122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    unique_handle   process_handle(pinfo.hProcess);
7942122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    pinfo.hProcess = NULL;
7952122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
7962122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // Close handles that we no longer need to complete the rest.
7972122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    CloseHandle(pinfo.hThread);
7982122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    pinfo.hThread = NULL;
7992122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
8002122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    nul_read.reset();
8012122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    ack_write.reset();
8022122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    stdout_write.reset();
8032122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    stderr_write.reset();
8042122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
80553a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low    // Start threads to read from subprocess stdout/stderr and write to ours to make subprocess
80653a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low    // errors easier to diagnose. Note that the threads internally create inheritable handles, but
80753a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low    // that is ok because we've already spawned the subprocess.
8082122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
8092122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // In the past, reading from a pipe before the child process's C Runtime
8102122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // started up and called GetFileType() caused a hang: http://blogs.msdn.com/b/oldnewthing/archive/2011/12/02/10243553.aspx#10244216
8112122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // This is reportedly fixed in Windows Vista: https://support.microsoft.com/en-us/kb/2009703
8122122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // I was unable to reproduce the problem on Windows XP. It sounds like a
8132122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // Windows Update may have fixed this: https://www.duckware.com/tech/peeknamedpipe.html
8142122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    unique_handle   stdout_thread(reinterpret_cast<HANDLE>(
8152122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            _beginthreadex(NULL, 0, _redirect_stdout_thread, stdout_read.get(),
8162122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low                           0, NULL)));
8172122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    if (stdout_thread.get() == nullptr) {
8181fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes        fprintf(stderr, "adb: cannot create thread: %s\n", strerror(errno));
8192122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        return -1;
8202122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    }
8212122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    stdout_read.release();  // Transfer ownership to new thread
822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
8232122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    unique_handle   stderr_thread(reinterpret_cast<HANDLE>(
8242122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            _beginthreadex(NULL, 0, _redirect_stderr_thread, stderr_read.get(),
8252122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low                           0, NULL)));
8262122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    if (stderr_thread.get() == nullptr) {
8271fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes        fprintf(stderr, "adb: cannot create thread: %s\n", strerror(errno));
828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
8302122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    stderr_read.release();  // Transfer ownership to new thread
831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
8322122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    bool    got_ack = false;
833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
8342122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // Wait for the "OK\n" message, for the pipe to be closed, or other error.
835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    {
8362122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        char    temp[3];
8372122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        DWORD   count = 0;
8382122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
8392122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        if (ReadFile(ack_read.get(), temp, sizeof(temp), &count, NULL)) {
8402122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            const CHAR  expected[] = "OK\n";
8412122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            const DWORD expected_length = arraysize(expected) - 1;
8422122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            if (count == expected_length &&
8432122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low                memcmp(temp, expected, expected_length) == 0) {
8442122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low                got_ack = true;
8452122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            } else {
8466eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes                ReportServerStartupFailure(GetProcessId(process_handle.get()));
8476eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes                return -1;
8482122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            }
8492122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        } else {
8502122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            const DWORD err = GetLastError();
8512122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            // If the ACK was not written and the process exited, GetLastError()
8522122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            // is probably ERROR_BROKEN_PIPE, in which case that info is not
8532122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            // useful to the user.
8542122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            fprintf(stderr, "could not read ok from ADB Server%s\n",
8552122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low                    err == ERROR_BROKEN_PIPE ? "" :
8562122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low                    android::base::StringPrintf(": %s",
8575f787ed2b3b9f6cc02aa5923b95d77e2a5865438David Pursell                            android::base::SystemErrorCodeToString(err).c_str()).c_str());
858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
8592122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    }
8602122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
8612122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // Always try to wait a bit for threads reading stdout/stderr to finish.
8622122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // If the process started ok, it should close the pipes causing the threads
8632122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // to finish. If the process had an error, it should exit, also causing
8642122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // the pipes to be closed. In that case we want to read all of the output
8652122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // and write it out so that the user can diagnose failures.
8662122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    const DWORD     thread_timeout_ms = 15 * 1000;
8672122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    const HANDLE    threads[] = { stdout_thread.get(), stderr_thread.get() };
8682122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    const DWORD     wait_result = WaitForMultipleObjects(arraysize(threads),
8692122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            threads, TRUE, thread_timeout_ms);
8702122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    if (wait_result == WAIT_TIMEOUT) {
8712122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        // Threads did not finish after waiting a little while. Perhaps the
8722122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        // server didn't close pipes, or it is hung.
8731fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes        fprintf(stderr, "adb: timed out waiting for threads to finish reading from ADB server\n");
8742122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        // Process handles are signaled when the process exits, so if we wait
8752122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        // on the handle for 0 seconds and it returns 'timeout', that means that
8762122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        // the process is still running.
8772122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        if (WaitForSingleObject(process_handle.get(), 0) == WAIT_TIMEOUT) {
8782122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low            // We could TerminateProcess(), but that seems somewhat presumptive.
8791fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes            fprintf(stderr, "adb: server is running with process id %lu\n", pinfo.dwProcessId);
880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
8812122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        return -1;
8822122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    }
8832122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
8842122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    if (wait_result != WAIT_OBJECT_0) {
8851fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes        fprintf(stderr, "adb: unexpected result waiting for threads: %lu: %s\n", wait_result,
8861fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes                android::base::SystemErrorCodeToString(GetLastError()).c_str());
8872122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        return -1;
8882122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    }
8892122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
8902122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    // For now ignore the thread exit codes and assume they worked properly.
8912122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low
8922122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low    if (!got_ack) {
8932122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low        return -1;
894dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
895e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui#else /* !defined(_WIN32) */
896dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // set up a pipe so the child can tell us when it is ready.
8979f2d1a9cfc04e1d5970823da1878097288a9a9cdSiva Velusamy    // fd[0] will be parent's end, and the child will write on fd[1]
89882ff315bb0fecb9127970e01b399be53c92ca14fElliott Hughes    int fd[2];
899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (pipe(fd)) {
900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
901dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
902dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
90382ff315bb0fecb9127970e01b399be53c92ca14fElliott Hughes
90482ff315bb0fecb9127970e01b399be53c92ca14fElliott Hughes    std::string path = android::base::GetExecutablePath();
90582ff315bb0fecb9127970e01b399be53c92ca14fElliott Hughes
906dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pid_t pid = fork();
90782ff315bb0fecb9127970e01b399be53c92ca14fElliott Hughes    if (pid < 0) return -1;
908dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (pid == 0) {
910dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // child side of the fork
911dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
912dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(fd[0]);
913dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
9149f2d1a9cfc04e1d5970823da1878097288a9a9cdSiva Velusamy        char reply_fd[30];
9159f2d1a9cfc04e1d5970823da1878097288a9a9cdSiva Velusamy        snprintf(reply_fd, sizeof(reply_fd), "%d", fd[1]);
916dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // child process
9179c869b58a8cf4f7c3bc88931fbd27d3f5187b2dbJosh Gao        int result = execl(path.c_str(), "adb", "-L", socket_spec.c_str(), "fork-server", "server",
9189c869b58a8cf4f7c3bc88931fbd27d3f5187b2dbJosh Gao                           "--reply-fd", reply_fd, NULL);
919dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // this should not return
9201fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes        fprintf(stderr, "adb: execl returned %d: %s\n", result, strerror(errno));
9216eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    } else {
922dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // parent side of the fork
9236eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes        char temp[3] = {};
924dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // wait for the "OK\n" message
925dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(fd[1]);
926dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int ret = adb_read(fd[0], temp, 3);
927408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        int saved_errno = errno;
928dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(fd[0]);
929dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (ret < 0) {
930408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall            fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
931dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
932dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
933dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
9346eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes            ReportServerStartupFailure(pid);
935dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
936dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
937dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
938e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui#endif /* !defined(_WIN32) */
939dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
940dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
941e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui#endif /* ADB_HOST */
942dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
943252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner// Try to handle a network forwarding request.
944252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner// This returns 1 on success, 0 on failure, and -1 to indicate this is not
945252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner// a forwarding-related request.
9461bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gaoint handle_forward_request(const char* service, TransportType type, const char* serial,
9471bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao                           TransportId transport_id, int reply_fd) {
948252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner    if (!strcmp(service, "list-forward")) {
949252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        // Create the list of forward redirections.
950e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        std::string listeners = format_listeners();
951252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#if ADB_HOST
952e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        SendOkay(reply_fd);
953252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#endif
9547e6683ce40ba79c94ccc1e3b984cd39e63651dd5Josh Gao        return SendProtocolString(reply_fd, listeners);
955252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner    }
956252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner
957252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner    if (!strcmp(service, "killforward-all")) {
958252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        remove_all_listeners();
959252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#if ADB_HOST
960252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        /* On the host: 1st OKAY is connect, 2nd OKAY is status */
961e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        SendOkay(reply_fd);
962252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#endif
963e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        SendOkay(reply_fd);
964252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        return 1;
965252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner    }
966252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner
967424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes    if (!strncmp(service, "forward:", 8) || !strncmp(service, "killforward:", 12)) {
968424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes        // killforward:local
969424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes        // forward:(norebind:)?local;remote
970424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes        bool kill_forward = false;
971424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes        bool no_rebind = false;
972424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes        if (android::base::StartsWith(service, "killforward:")) {
973424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            kill_forward = true;
974424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            service += 12;
975a6b340af123b82e3aaa33cb2a0d45f637eeb4759Spencer Low        } else {
976a6b340af123b82e3aaa33cb2a0d45f637eeb4759Spencer Low            service += 8;   // skip past "forward:"
977424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            if (android::base::StartsWith(service, "norebind:")) {
978424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes                no_rebind = true;
979424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes                service += 9;
980424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            }
981252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        }
982252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner
983424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes        std::vector<std::string> pieces = android::base::Split(service, ";");
984252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner
985424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes        if (kill_forward) {
986424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            // Check killforward: parameter format: '<local>'
987424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            if (pieces.size() != 1 || pieces[0].empty()) {
988424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes                SendFail(reply_fd, android::base::StringPrintf("bad killforward: %s", service));
989252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner                return 1;
990252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner            }
991252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        } else {
992424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            // Check forward: parameter format: '<local>;<remote>'
993424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            if (pieces.size() != 2 || pieces[0].empty() || pieces[1].empty() || pieces[1][0] == '*') {
994424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes                SendFail(reply_fd, android::base::StringPrintf("bad forward: %s", service));
995252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner                return 1;
996252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner            }
997252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        }
998252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner
9997be29c819b4fb8bf9b1d4b69a4333f8765de0281Elliott Hughes        std::string error_msg;
10001bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao        atransport* transport =
10011bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao            acquire_one_transport(type, serial, transport_id, nullptr, &error_msg);
1002252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        if (!transport) {
1003e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes            SendFail(reply_fd, error_msg);
1004252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner            return 1;
1005252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        }
1006252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner
10075200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low        std::string error;
10083bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes        InstallStatus r;
1009eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        int resolved_tcp_port = 0;
1010424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes        if (kill_forward) {
1011424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            r = remove_listener(pieces[0].c_str(), transport);
1012252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        } else {
1013eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            r = install_listener(pieces[0], pieces[1].c_str(), transport, no_rebind,
1014eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell                                 &resolved_tcp_port, &error);
1015252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        }
10167b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes        if (r == INSTALL_STATUS_OK) {
1017252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#if ADB_HOST
1018eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            // On the host: 1st OKAY is connect, 2nd OKAY is status.
1019e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes            SendOkay(reply_fd);
1020252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#endif
1021e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes            SendOkay(reply_fd);
1022eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell
1023eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            // If a TCP port was resolved, send the actual port number back.
1024eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            if (resolved_tcp_port != 0) {
1025eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell                SendProtocolString(reply_fd, android::base::StringPrintf("%d", resolved_tcp_port));
1026eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            }
1027eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell
1028252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner            return 1;
1029252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        }
1030252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner
10317b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes        std::string message;
10327b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes        switch (r) {
1033424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes          case INSTALL_STATUS_OK: message = "success (!)"; break;
10347b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes          case INSTALL_STATUS_INTERNAL_ERROR: message = "internal error"; break;
10357b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes          case INSTALL_STATUS_CANNOT_BIND:
1036bf7c605d87f87c03066c384cecb0f0c91aa31403Spencer Low            message = android::base::StringPrintf("cannot bind listener: %s",
10375200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low                                                  error.c_str());
10387b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes            break;
10397b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes          case INSTALL_STATUS_CANNOT_REBIND:
1040a6b340af123b82e3aaa33cb2a0d45f637eeb4759Spencer Low            message = android::base::StringPrintf("cannot rebind existing socket");
10417b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes            break;
1042424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes          case INSTALL_STATUS_LISTENER_NOT_FOUND:
1043424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            message = android::base::StringPrintf("listener '%s' not found", service);
1044424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            break;
1045252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        }
1046e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        SendFail(reply_fd, message);
1047252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        return 1;
1048252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner    }
1049252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner    return 0;
1050252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner}
1051252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner
1052e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes#if ADB_HOST
1053e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughesstatic int SendOkay(int fd, const std::string& s) {
1054e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes    SendOkay(fd);
1055e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes    SendProtocolString(fd, s);
1056e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes    return 0;
1057e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes}
1058e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes
10591bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gaoint handle_host_request(const char* service, TransportType type, const char* serial,
10601bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao                        TransportId transport_id, int reply_fd, asocket* s) {
1061c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    if (strcmp(service, "kill") == 0) {
1062c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert        fprintf(stderr, "adb server killed by remote request\n");
1063dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fflush(stdout);
1064f18fc0879be9cd506be6b1e051feb543b0746bdbSpencer Low
1065b3c14ec693d4c061fc9ec7fdaa7897169d179479Josh Gao        // Send a reply even though we don't read it anymore, so that old versions
1066b3c14ec693d4c061fc9ec7fdaa7897169d179479Josh Gao        // of adb that do read it don't spew error messages.
1067b3c14ec693d4c061fc9ec7fdaa7897169d179479Josh Gao        SendOkay(reply_fd);
1068f18fc0879be9cd506be6b1e051feb543b0746bdbSpencer Low
1069b3c14ec693d4c061fc9ec7fdaa7897169d179479Josh Gao        // Rely on process exit to close the socket for us.
10701c70e1bcbcced190b351d4fb418f32b4e428f496Josh Gao        android::base::quick_exit(0);
1071dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1072dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1073dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // "transport:" is used for switching transport with a specified serial number
1074dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // "transport-usb:" is used for switching transport to the only USB transport
1075dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // "transport-local:" is used for switching transport to the only local transport
1076dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // "transport-any:" is used for switching transport to the only transport
1077dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!strncmp(service, "transport", strlen("transport"))) {
10783bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes        TransportType type = kTransportAny;
1079dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
10801bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao        if (!strncmp(service, "transport-id:", strlen("transport-id:"))) {
10811bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao            service += strlen("transport-id:");
10821bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao            transport_id = strtoll(service, const_cast<char**>(&service), 10);
10831bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao            if (*service != '\0') {
10841bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao                SendFail(reply_fd, "invalid transport id");
10851bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao                return 1;
10861bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao            }
10871bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao        } else if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
1088dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            type = kTransportUsb;
1089dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (!strncmp(service, "transport-local", strlen("transport-local"))) {
1090dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            type = kTransportLocal;
1091dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (!strncmp(service, "transport-any", strlen("transport-any"))) {
1092dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            type = kTransportAny;
1093dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (!strncmp(service, "transport:", strlen("transport:"))) {
1094dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            service += strlen("transport:");
10953175c8e9bfcb01f181d7300755da15a999e5461cTom Marlin            serial = service;
1096dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1097dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
10988d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes        std::string error;
10991bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao        atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
1100e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes        if (t != nullptr) {
1101e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes            s->transport = t;
1102e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes            SendOkay(reply_fd);
1103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
11048d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes            SendFail(reply_fd, error);
1105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
1107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // return a list of all connected devices
1110e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson    if (!strncmp(service, "devices", 7)) {
1111e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        bool long_listing = (strcmp(service+7, "-l") == 0);
1112e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        if (long_listing || service[7] == 0) {
11137a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui            D("Getting device list...");
1114e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes            std::string device_list = list_transports(long_listing);
11157a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui            D("Sending device list...");
1116e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes            return SendOkay(reply_fd, device_list);
1117e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson        }
1118e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        return 1;
1119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
112122d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao    if (!strcmp(service, "reconnect-offline")) {
112222d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao        std::string response;
112322d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao        close_usb_devices([&response](const atransport* transport) {
1124b5e11415d9fdb929321c66889063dac50fb737afYabin Cui            switch (transport->GetConnectionState()) {
112522d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao                case kCsOffline:
112622d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao                case kCsUnauthorized:
1127b5e11415d9fdb929321c66889063dac50fb737afYabin Cui                    response += "reconnecting " + transport->serial_name() + "\n";
112822d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao                    return true;
112922d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao                default:
113022d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao                    return false;
113122d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao            }
113222d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao        });
113322d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao        if (!response.empty()) {
113422d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao            response.resize(response.size() - 1);
113522d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao        }
113622d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao        SendOkay(reply_fd, response);
113722d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao        return 0;
113822d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao    }
113922d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao
114090d4b739ab94fded63086de1261e70a3d39ceb1dDan Albert    if (!strcmp(service, "features")) {
11418d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes        std::string error;
11421bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao        atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
1143880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell        if (t != nullptr) {
11444e2fd36bc8c16147cab323b0418a7666812d3bc7David Pursell            SendOkay(reply_fd, FeatureSetToString(t->features()));
1145880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell        } else {
11468d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes            SendFail(reply_fd, error);
1147880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell        }
1148880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell        return 0;
1149880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell    }
1150880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell
11515d1756ceb58246a721e10464f788e81cdcdc455aJosh Gao    if (!strcmp(service, "host-features")) {
11525d1756ceb58246a721e10464f788e81cdcdc455aJosh Gao        FeatureSet features = supported_features();
11535d1756ceb58246a721e10464f788e81cdcdc455aJosh Gao        // Abuse features to report libusb status.
11545d1756ceb58246a721e10464f788e81cdcdc455aJosh Gao        if (should_use_libusb()) {
11555d1756ceb58246a721e10464f788e81cdcdc455aJosh Gao            features.insert(kFeatureLibusb);
11565d1756ceb58246a721e10464f788e81cdcdc455aJosh Gao        }
11575176df8d4a3f43aed35aa17508a0eb862c262ea4Dan Albert        features.insert(kFeaturePushSync);
11585d1756ceb58246a721e10464f788e81cdcdc455aJosh Gao        SendOkay(reply_fd, FeatureSetToString(features));
11595d1756ceb58246a721e10464f788e81cdcdc455aJosh Gao        return 0;
11605d1756ceb58246a721e10464f788e81cdcdc455aJosh Gao    }
11615d1756ceb58246a721e10464f788e81cdcdc455aJosh Gao
116274d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood    // remove TCP transport
116374d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood    if (!strncmp(service, "disconnect:", 11)) {
11643d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        const std::string address(service + 11);
11653d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        if (address.empty()) {
1166f4b9928563e97620fc1d9bd5c2efdaa0ded96488Yabin Cui            kick_all_tcp_devices();
11673d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes            return SendOkay(reply_fd, "disconnected everything");
116874d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood        }
116974d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood
11703d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        std::string serial;
11713d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        std::string host;
11723d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
11733d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        std::string error;
1174706955ff0d159d28bb6eb06dc10178624c505f4eDavid Pursell        if (!android::base::ParseNetAddress(address, &host, &port, &serial, &error)) {
11753d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes            return SendFail(reply_fd, android::base::StringPrintf("couldn't parse '%s': %s",
11763d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes                                                                  address.c_str(), error.c_str()));
11773d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        }
11783d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        atransport* t = find_transport(serial.c_str());
11793d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        if (t == nullptr) {
11803d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes            return SendFail(reply_fd, android::base::StringPrintf("no such device '%s'",
11813d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes                                                                  serial.c_str()));
11823d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        }
1183f4b9928563e97620fc1d9bd5c2efdaa0ded96488Yabin Cui        kick_transport(t);
11843d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        return SendOkay(reply_fd, android::base::StringPrintf("disconnected %s", address.c_str()));
11852f38b699713dc2587a771bd5d4c6a47329728f5eMike Lockwood    }
11862f38b699713dc2587a771bd5d4c6a47329728f5eMike Lockwood
11878d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes    // Returns our value for ADB_SERVER_VERSION.
1188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!strcmp(service, "version")) {
1189e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes        return SendOkay(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION));
1190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1192e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes    // These always report "unknown" rather than the actual error, for scripts.
1193e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes    if (!strcmp(service, "get-serialno")) {
11948d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes        std::string error;
11951bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao        atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
11968d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes        if (t) {
11978d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes            return SendOkay(reply_fd, t->serial ? t->serial : "unknown");
11988d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes        } else {
11998d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes            return SendFail(reply_fd, error);
12008d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes        }
1201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1202e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes    if (!strcmp(service, "get-devpath")) {
12038d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes        std::string error;
12041bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao        atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
12058d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes        if (t) {
12068d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes            return SendOkay(reply_fd, t->devpath ? t->devpath : "unknown");
12078d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes        } else {
12088d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes            return SendFail(reply_fd, error);
12098d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes        }
1210e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson    }
1211e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes    if (!strcmp(service, "get-state")) {
12128d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes        std::string error;
12131bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao        atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
12148d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes        if (t) {
12158d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes            return SendOkay(reply_fd, t->connection_state_name());
12168d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes        } else {
12178d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes            return SendFail(reply_fd, error);
12188d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes        }
1219e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes    }
1220e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes
12218d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes    // Indicates a new emulator instance has started.
1222e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes    if (!strncmp(service, "emulator:", 9)) {
1223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  port = atoi(service+9);
1224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        local_connect(port);
1225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* we don't even need to send a reply */
1226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
1227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
12281f4ec19e499ba981e4117f647d191603c2713e79Yabin Cui
12291f4ec19e499ba981e4117f647d191603c2713e79Yabin Cui    if (!strcmp(service, "reconnect")) {
1230b5e11415d9fdb929321c66889063dac50fb737afYabin Cui        std::string response;
12311bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao        atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &response, true);
1232b5e11415d9fdb929321c66889063dac50fb737afYabin Cui        if (t != nullptr) {
1233b5e11415d9fdb929321c66889063dac50fb737afYabin Cui            kick_transport(t);
1234b5e11415d9fdb929321c66889063dac50fb737afYabin Cui            response =
1235b5e11415d9fdb929321c66889063dac50fb737afYabin Cui                "reconnecting " + t->serial_name() + " [" + t->connection_state_name() + "]\n";
12361f4ec19e499ba981e4117f647d191603c2713e79Yabin Cui        }
1237b5e11415d9fdb929321c66889063dac50fb737afYabin Cui        return SendOkay(reply_fd, response);
12381f4ec19e499ba981e4117f647d191603c2713e79Yabin Cui    }
1239dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye
12401bd8498fc89d14b98e64142e07ad0c35c3bbffedJosh Gao    int ret = handle_forward_request(service, type, serial, transport_id, reply_fd);
1241dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye    if (ret >= 0)
1242dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye      return ret - 1;
1243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -1;
1244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1245fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao
1246fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gaostatic auto& init_mutex = *new std::mutex();
1247fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gaostatic auto& init_cv = *new std::condition_variable();
1248fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gaostatic bool device_scan_complete = false;
1249fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gaostatic bool transports_ready = false;
1250fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao
1251fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gaovoid update_transport_status() {
1252fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao    bool result = iterate_transports([](const atransport* t) {
1253fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao        if (t->type == kTransportUsb && t->online != 1) {
1254fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao            return false;
1255fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao        }
1256fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao        return true;
1257fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao    });
1258fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao
1259fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao    bool ready;
1260fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao    {
1261fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao        std::lock_guard<std::mutex> lock(init_mutex);
1262fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao        transports_ready = result;
1263fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao        ready = transports_ready && device_scan_complete;
1264fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao    }
1265fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao
1266fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao    if (ready) {
1267fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao        init_cv.notify_all();
1268fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao    }
1269fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao}
1270fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao
1271fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gaovoid adb_notify_device_scan_complete() {
1272fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao    {
1273fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao        std::lock_guard<std::mutex> lock(init_mutex);
12740b13c89f7a4df0c3105ca2aa4d9406ae4964fd8bJosh Gao        if (device_scan_complete) {
12750b13c89f7a4df0c3105ca2aa4d9406ae4964fd8bJosh Gao            return;
12760b13c89f7a4df0c3105ca2aa4d9406ae4964fd8bJosh Gao        }
12770b13c89f7a4df0c3105ca2aa4d9406ae4964fd8bJosh Gao
1278fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao        device_scan_complete = true;
1279fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao    }
1280fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao
1281fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao    update_transport_status();
1282fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao}
1283fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao
1284fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gaovoid adb_wait_for_device_initialization() {
1285fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao    std::unique_lock<std::mutex> lock(init_mutex);
1286fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao    init_cv.wait_for(lock, 3s, []() { return device_scan_complete && transports_ready; });
1287fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao}
1288fd713e53e890f5b3bf26a1c5a980137cc4378c3aJosh Gao
1289b5e11415d9fdb929321c66889063dac50fb737afYabin Cui#endif  // ADB_HOST
1290