adb.cpp revision f18fc0879be9cd506be6b1e051feb543b0746bdb
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
173313426fad9eaaf53017cdbde889ebcec91358ecDan Albert#define TRACE_TAG TRACE_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
33ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#include <string>
34e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert#include <vector>
35e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert#include <unordered_map>
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
379313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert#include <base/logging.h>
38cf4ff64f2d3cdc4ffa2f06e594d18a965f591a82Spencer Low#include <base/macros.h>
397b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes#include <base/stringprintf.h>
408d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes#include <base/strings.h>
417b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes
42d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#include "adb_auth.h"
43cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert#include "adb_io.h"
44e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert#include "adb_listeners.h"
453d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes#include "adb_utils.h"
467664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include "transport.h"
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
48e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
49e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if !ADB_HOST
51893a4a47e8c9290128b9254af0246e36f821c260Nick Kralevich#include <cutils/properties.h>
52e2864bf727d6a404bd871f063c03e36cc8eedeecNick Kralevich#include <sys/capability.h>
53885342a0f2c834a6b680284047c47c9d04b32565Jeff Sharkey#include <sys/mount.h>
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
569313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan AlbertADB_MUTEX_DEFINE(D_lock);
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
58e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson#if !ADB_HOST
599313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertconst char* adb_device_banner = "device";
609313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertstatic android::base::LogdLogger gLogdLogger;
61e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson#endif
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
639313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertvoid AdbLogger(android::base::LogId id, android::base::LogSeverity severity,
649313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert               const char* tag, const char* file, unsigned int line,
659313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert               const char* message) {
669313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert    android::base::StderrLogger(id, severity, tag, file, line, message);
679313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert#if !ADB_HOST
689313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert    gLogdLogger(id, severity, tag, file, line, message);
699313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert#endif
709313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert}
719313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert
7242ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughesstd::string adb_version() {
7342ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes    // Don't change the format of this --- it's parsed by ddmlib.
7442ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes    return android::base::StringPrintf("Android Debug Bridge version %d.%d.%d\n"
7542ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes                                       "Revision %s\n",
7642ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes                                       ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION,
7742ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes                                       ADB_REVISION);
7842ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes}
7942ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes
809313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertvoid fatal(const char *fmt, ...) {
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_list ap;
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_start(ap, fmt);
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr, "error: ");
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    vfprintf(stderr, fmt, ap);
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr, "\n");
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_end(ap);
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    exit(-1);
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
909313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertvoid fatal_errno(const char* fmt, ...) {
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_list ap;
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_start(ap, fmt);
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr, "error: %s: ", strerror(errno));
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    vfprintf(stderr, fmt, ap);
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr, "\n");
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_end(ap);
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    exit(-1);
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
100ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#if !ADB_HOST
1019313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertstatic std::string get_log_file_name() {
102ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    struct tm now;
103ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    time_t t;
104ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    tzset();
105ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    time(&t);
106ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    localtime_r(&t, &now);
107ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert
1088743ef98414b336f222327253f2cde6bf6aee386Dan Albert    char timestamp[PATH_MAX];
1098743ef98414b336f222327253f2cde6bf6aee386Dan Albert    strftime(timestamp, sizeof(timestamp), "%Y-%m-%d-%H-%M-%S", &now);
1108743ef98414b336f222327253f2cde6bf6aee386Dan Albert
1119313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert    return android::base::StringPrintf("/data/adb/adb-%s-%d", timestamp,
1129313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert                                       getpid());
1139313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert}
1149313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert
1159313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertvoid start_device_log(void) {
1169313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert    int fd = unix_open(get_log_file_name().c_str(),
1179313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert                       O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640);
118ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    if (fd == -1) {
119ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert        return;
120ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    }
121ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert
1229313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert    // Redirect stdout and stderr to the log file.
123ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    dup2(fd, STDOUT_FILENO);
124ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    dup2(fd, STDERR_FILENO);
125ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid());
1266ac5d7dc56a016718d2a26803435505e983e5d80Spencer Low    unix_close(fd);
127ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert}
128ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#endif
129ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert
130ea2175ab6bae74409620374a96fc9a0097a1845cDan Albertint adb_trace_mask;
131ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert
132ea2175ab6bae74409620374a96fc9a0097a1845cDan Albertstd::string get_trace_setting_from_env() {
133ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    const char* setting = getenv("ADB_TRACE");
134ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    if (setting == nullptr) {
135ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert        setting = "";
136ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    }
137ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert
138ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    return std::string(setting);
139ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert}
140ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert
141ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#if !ADB_HOST
142ea2175ab6bae74409620374a96fc9a0097a1845cDan Albertstd::string get_trace_setting_from_prop() {
143ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    char buf[PROPERTY_VALUE_MAX];
144ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    property_get("persist.adb.trace_mask", buf, "");
145ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    return std::string(buf);
146ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert}
147ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#endif
148ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert
149ea2175ab6bae74409620374a96fc9a0097a1845cDan Albertstd::string get_trace_setting() {
150ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#if ADB_HOST
151ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    return get_trace_setting_from_env();
152ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#else
153ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    return get_trace_setting_from_prop();
154ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#endif
155ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert}
156ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert
157e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert// Split the space separated list of tags from the trace setting and build the
158e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert// trace mask from it. note that '1' and 'all' are special cases to enable all
159e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert// tracing.
160ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert//
161ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert// adb's trace setting comes from the ADB_TRACE environment variable, whereas
162ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert// adbd's comes from the system property persist.adb.trace_mask.
1639313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertstatic void setup_trace_mask() {
164ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert    const std::string trace_setting = get_trace_setting();
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
166e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert    std::unordered_map<std::string, int> trace_flags = {
167e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert        {"1", 0},
168e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert        {"all", 0},
169e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert        {"adb", TRACE_ADB},
170e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert        {"sockets", TRACE_SOCKETS},
171e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert        {"packets", TRACE_PACKETS},
172e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert        {"rwx", TRACE_RWX},
173e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert        {"usb", TRACE_USB},
174e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert        {"sync", TRACE_SYNC},
175e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert        {"sysdeps", TRACE_SYSDEPS},
176e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert        {"transport", TRACE_TRANSPORT},
177e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert        {"jdwp", TRACE_JDWP},
178e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert        {"services", TRACE_SERVICES},
179e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert        {"auth", TRACE_AUTH}};
180e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert
181e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert    std::vector<std::string> elements = android::base::Split(trace_setting, " ");
182e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert    for (const auto& elem : elements) {
183e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert        const auto& flag = trace_flags.find(elem);
184e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert        if (flag == trace_flags.end()) {
1858d8126a705dd3c5734a0894f88c2c758784bd469Spencer Low            D("Unknown trace flag: %s\n", flag->first.c_str());
186e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert            continue;
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
188e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert
189e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert        if (flag->second == 0) {
190e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert            // 0 is used for the special values "1" and "all" that enable all
191e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert            // tracing.
192e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert            adb_trace_mask = ~0;
193e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert            return;
194e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert        } else {
195e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert            adb_trace_mask |= 1 << flag->second;
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1989313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert}
199ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert
2009313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertvoid adb_trace_init(char** argv) {
2017430916098fd264d569d398614d1d725adfca165Spencer Low#if !ADB_HOST
2026f009d9496fc060ba76f97348aa0702a62fcf927Paul Lawrence    // Don't open log file if no tracing, since this will block
2036f009d9496fc060ba76f97348aa0702a62fcf927Paul Lawrence    // the crypto unmount of /data
2047430916098fd264d569d398614d1d725adfca165Spencer Low    if (!get_trace_setting().empty()) {
2057430916098fd264d569d398614d1d725adfca165Spencer Low        if (isatty(STDOUT_FILENO) == 0) {
2067430916098fd264d569d398614d1d725adfca165Spencer Low            start_device_log();
2077430916098fd264d569d398614d1d725adfca165Spencer Low        }
2089313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert    }
209ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#endif
2109313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert
2119313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert    setup_trace_mask();
2129313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert    android::base::InitLogging(argv, AdbLogger);
21342ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes
21442ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes    D("%s", adb_version().c_str());
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
217bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albertapacket* get_apacket(void)
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
219bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert    apacket* p = reinterpret_cast<apacket*>(malloc(sizeof(apacket)));
220bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert    if (p == nullptr) {
221bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert      fatal("failed to allocate an apacket");
222bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert    }
223bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memset(p, 0, sizeof(apacket) - MAX_PAYLOAD);
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return p;
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid put_apacket(apacket *p)
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    free(p);
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
233d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobyvoid handle_online(atransport *t)
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D("adb: online\n");
236d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    t->online = 1;
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid handle_offline(atransport *t)
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D("adb: offline\n");
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //Close the associated usb
243d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    t->online = 0;
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    run_transport_disconnects(t);
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
247d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#if DEBUG_PACKETS
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define DUMPMAX 32
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid print_packet(const char *label, apacket *p)
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *tag;
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *x;
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned count;
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch(p->msg.command){
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_SYNC: tag = "SYNC"; break;
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_CNXN: tag = "CNXN" ; break;
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_OPEN: tag = "OPEN"; break;
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_OKAY: tag = "OKAY"; break;
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_CLSE: tag = "CLSE"; break;
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_WRTE: tag = "WRTE"; break;
262d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    case A_AUTH: tag = "AUTH"; break;
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    default: tag = "????"; break;
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr, "%s: %s %08x %08x %04x \"",
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length);
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    count = p->msg.data_length;
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    x = (char*) p->data;
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(count > DUMPMAX) {
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        count = DUMPMAX;
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        tag = "\n";
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        tag = "\"\n";
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while(count-- > 0){
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if((*x >= ' ') && (*x < 127)) {
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fputc(*x, stderr);
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fputc('.', stderr);
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        x++;
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
284d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    fputs(tag, stderr);
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void send_ready(unsigned local, unsigned remote, atransport *t)
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D("Calling send_ready \n");
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    apacket *p = get_apacket();
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p->msg.command = A_OKAY;
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p->msg.arg0 = local;
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p->msg.arg1 = remote;
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    send_packet(p, t);
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void send_close(unsigned local, unsigned remote, atransport *t)
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D("Calling send_close \n");
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    apacket *p = get_apacket();
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p->msg.command = A_CLSE;
303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p->msg.arg0 = local;
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p->msg.arg1 = remote;
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    send_packet(p, t);
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
308e82c2db05cae70a0490a1f84b7211ef42c329671Scott Andersonstatic size_t fill_connect_data(char *buf, size_t bufsize)
309e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson{
310e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson#if ADB_HOST
311e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson    return snprintf(buf, bufsize, "host::") + 1;
312e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson#else
313e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson    static const char *cnxn_props[] = {
314e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson        "ro.product.name",
315e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson        "ro.product.model",
316e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson        "ro.product.device",
317e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson    };
318e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson    static const int num_cnxn_props = ARRAY_SIZE(cnxn_props);
319e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson    int i;
320e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson    size_t remaining = bufsize;
321e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson    size_t len;
322e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson
323e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson    len = snprintf(buf, remaining, "%s::", adb_device_banner);
324e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson    remaining -= len;
325e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson    buf += len;
326e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson    for (i = 0; i < num_cnxn_props; i++) {
327e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson        char value[PROPERTY_VALUE_MAX];
328e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson        property_get(cnxn_props[i], value, "");
329e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson        len = snprintf(buf, remaining, "%s=%s;", cnxn_props[i], value);
330e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson        remaining -= len;
331e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson        buf += len;
332e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson    }
333e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson
334e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson    return bufsize - remaining + 1;
335e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson#endif
336e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson}
337e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson
338ba3a251749c88210949008ae26f8bc04812084c1Dan Albertvoid send_connect(atransport *t)
339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D("Calling send_connect \n");
341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    apacket *cp = get_apacket();
342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    cp->msg.command = A_CNXN;
3433d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer    cp->msg.arg0 = t->get_protocol_version();
3443d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer    cp->msg.arg1 = t->get_max_payload();
345e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson    cp->msg.data_length = fill_connect_data((char *)cp->data,
3463d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer                                            MAX_PAYLOAD_V1);
347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    send_packet(cp, t);
348d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby}
349d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
3508d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes// qual_overwrite is used to overwrite a qualifier string.  dst is a
3518d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes// pointer to a char pointer.  It is assumed that if *dst is non-NULL, it
3528d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes// was malloc'ed and needs to freed.  *dst will be set to a dup of src.
3538d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes// TODO: switch to std::string for these atransport fields instead.
3548d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughesstatic void qual_overwrite(char** dst, const std::string& src) {
355e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson    free(*dst);
3568d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    *dst = strdup(src.c_str());
357e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson}
358e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson
3598d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughesvoid parse_banner(const char* banner, atransport* t) {
360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D("parse_banner: %s\n", banner);
3618d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes
3628d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    // The format is something like:
3638d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    // "device::ro.product.name=x;ro.product.model=y;ro.product.device=z;".
3648d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    std::vector<std::string> pieces = android::base::Split(banner, ":");
3658d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes
3668d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    if (pieces.size() > 2) {
3678d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes        const std::string& props = pieces[2];
3688d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes        for (auto& prop : android::base::Split(props, ";")) {
3698d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes            // The list of properties was traditionally ;-terminated rather than ;-separated.
3708d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes            if (prop.empty()) continue;
3718d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes
3728d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes            std::vector<std::string> key_value = android::base::Split(prop, "=");
3738d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes            if (key_value.size() != 2) continue;
3748d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes
3758d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes            const std::string& key = key_value[0];
3768d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes            const std::string& value = key_value[1];
3778d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes            if (key == "ro.product.name") {
3788d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes                qual_overwrite(&t->product, value);
3798d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes            } else if (key == "ro.product.model") {
3808d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes                qual_overwrite(&t->model, value);
3818d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes            } else if (key == "ro.product.device") {
3828d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes                qual_overwrite(&t->device, value);
383e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson            }
384e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson        }
385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
3878d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    const std::string& type = pieces[0];
3888d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    if (type == "bootloader") {
389dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert        D("setting connection_state to kCsBootloader\n");
390dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert        t->connection_state = kCsBootloader;
391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        update_transports();
3928d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    } else if (type == "device") {
393dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert        D("setting connection_state to kCsDevice\n");
394dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert        t->connection_state = kCsDevice;
395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        update_transports();
3968d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    } else if (type == "recovery") {
397dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert        D("setting connection_state to kCsRecovery\n");
398dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert        t->connection_state = kCsRecovery;
399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        update_transports();
4008d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes    } else if (type == "sideload") {
401dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert        D("setting connection_state to kCsSideload\n");
402dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert        t->connection_state = kCsSideload;
403447f061da19fe46bae35f1cdd93eeb16bc225463Doug Zongker        update_transports();
4043ce9575af76fa6dc110506080434303b9459abf4Elliott Hughes    } else {
405dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert        D("setting connection_state to kCsHost\n");
406dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert        t->connection_state = kCsHost;
407447f061da19fe46bae35f1cdd93eeb16bc225463Doug Zongker    }
408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid handle_packet(apacket *p, atransport *t)
411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    asocket *s;
413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
414899913f8168b54e00971c0e8d4ae16d06a4651feViral Mehta    D("handle_packet() %c%c%c%c\n", ((char*) (&(p->msg.command)))[0],
415899913f8168b54e00971c0e8d4ae16d06a4651feViral Mehta            ((char*) (&(p->msg.command)))[1],
416899913f8168b54e00971c0e8d4ae16d06a4651feViral Mehta            ((char*) (&(p->msg.command)))[2],
417899913f8168b54e00971c0e8d4ae16d06a4651feViral Mehta            ((char*) (&(p->msg.command)))[3]);
418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    print_packet("recv", p);
419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch(p->msg.command){
421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_SYNC:
422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(p->msg.arg0){
423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            send_packet(p, t);
424661327e8e40f95076e0e8abe86193da16b061bd8Yabin Cui#if ADB_HOST
425661327e8e40f95076e0e8abe86193da16b061bd8Yabin Cui            send_connect(t);
426661327e8e40f95076e0e8abe86193da16b061bd8Yabin Cui#endif
427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
428dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert            t->connection_state = kCsOffline;
429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            handle_offline(t);
430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            send_packet(p, t);
431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
435dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert        if(t->connection_state != kCsOffline) {
436dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert            t->connection_state = kCsOffline;
437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            handle_offline(t);
438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
439d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
4403d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer        t->update_version(p->msg.arg0, p->msg.arg1);
4418d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes        parse_banner(reinterpret_cast<const char*>(p->data), t);
442d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
443661327e8e40f95076e0e8abe86193da16b061bd8Yabin Cui#if ADB_HOST
444661327e8e40f95076e0e8abe86193da16b061bd8Yabin Cui        handle_online(t);
445661327e8e40f95076e0e8abe86193da16b061bd8Yabin Cui#else
446661327e8e40f95076e0e8abe86193da16b061bd8Yabin Cui        if (!auth_required) {
447d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            handle_online(t);
448661327e8e40f95076e0e8abe86193da16b061bd8Yabin Cui            send_connect(t);
449d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        } else {
450d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            send_auth_request(t);
451d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        }
452661327e8e40f95076e0e8abe86193da16b061bd8Yabin Cui#endif
453d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        break;
454d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby
455d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby    case A_AUTH:
456d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        if (p->msg.arg0 == ADB_AUTH_TOKEN) {
457dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert            t->connection_state = kCsUnauthorized;
458d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            t->key = adb_auth_nextkey(t->key);
459d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            if (t->key) {
460d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby                send_auth_response(p->data, p->msg.data_length, t);
461d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            } else {
462d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby                /* No more private keys to try, send the public key */
463d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby                send_auth_publickey(t);
464d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            }
465d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        } else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) {
466d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            if (adb_auth_verify(t->token, p->data, p->msg.data_length)) {
467d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby                adb_auth_verified(t);
468d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby                t->failed_auth_attempts = 0;
469d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            } else {
470d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby                if (t->failed_auth_attempts++ > 10)
471d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby                    adb_sleep_ms(1000);
472d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby                send_auth_request(t);
473d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            }
474d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) {
475d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby            adb_auth_confirm_key(p->data, p->msg.data_length, t);
476d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby        }
477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_OPEN: /* OPEN(local-id, 0, "destination") */
480818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner        if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) {
481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            char *name = (char*) p->data;
482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            s = create_local_service_socket(name);
484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(s == 0) {
485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                send_close(0, p->msg.arg0, t);
486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                s->peer = create_remote_socket(p->msg.arg0, t);
488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                s->peer->peer = s;
489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                send_ready(s->id, s->peer->id, t);
490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                s->ready(s);
491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case A_OKAY: /* READY(local-id, remote-id, "") */
496818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner        if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
497818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner            if((s = find_local_socket(p->msg.arg1, 0))) {
498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if(s->peer == 0) {
499818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                    /* On first READY message, create the connection. */
500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    s->peer = create_remote_socket(p->msg.arg0, t);
501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    s->peer->peer = s;
502818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                    s->ready(s);
503818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                } else if (s->peer->id == p->msg.arg0) {
504818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                    /* Other READY messages must use the same local-id */
505818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                    s->ready(s);
506818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                } else {
507818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                    D("Invalid A_OKAY(%d,%d), expected A_OKAY(%d,%d) on transport %s\n",
508818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                      p->msg.arg0, p->msg.arg1, s->peer->id, p->msg.arg1, t->serial);
509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
514818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner    case A_CLSE: /* CLOSE(local-id, remote-id, "") or CLOSE(0, remote-id, "") */
515818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner        if (t->online && p->msg.arg1 != 0) {
516818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner            if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
517818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                /* According to protocol.txt, p->msg.arg0 might be 0 to indicate
518818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                 * a failed OPEN only. However, due to a bug in previous ADB
519818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                 * versions, CLOSE(0, remote-id, "") was also used for normal
520818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                 * CLOSE() operations.
521818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                 *
522818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                 * This is bad because it means a compromised adbd could
523818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                 * send packets to close connections between the host and
524818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                 * other devices. To avoid this, only allow this if the local
525818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                 * socket has a peer on the same transport.
526818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                 */
527818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                if (p->msg.arg0 == 0 && s->peer && s->peer->transport != t) {
528818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                    D("Invalid A_CLSE(0, %u) from transport %s, expected transport %s\n",
529818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                      p->msg.arg1, t->serial, s->peer->transport->serial);
530818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                } else {
531818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                    s->close(s);
532818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner                }
533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
537818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner    case A_WRTE: /* WRITE(local-id, remote-id, <data>) */
538818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner        if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
539818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner            if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                unsigned rid = p->msg.arg0;
541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                p->len = p->msg.data_length;
542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if(s->enqueue(s, p) == 0) {
544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    D("Enqueue the socket\n");
545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    send_ready(s->id, rid, t);
546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return;
548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    default:
553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("handle_packet: what is %08x?!\n", p->msg.command);
554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    put_apacket(p);
557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST
560571c1367682c83cb23481cc9c1028c8588a1fed0JP Abgrall
561a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzingerint launch_server(int server_port)
562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
563e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui#if defined(_WIN32)
564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* we need to start the server in the background                    */
565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* we create a PIPE that will be used to wait for the server's "OK" */
566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* message since the pipe handles must be inheritable, we use a     */
567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* security attribute                                               */
568d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low    HANDLE                nul_read, nul_write;
569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    HANDLE                pipe_read, pipe_write;
570267aa8b00eadf273321e492026af74b7baad890eRay Donnelly    HANDLE                stdout_handle, stderr_handle;
571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SECURITY_ATTRIBUTES   sa;
572cf4ff64f2d3cdc4ffa2f06e594d18a965f591a82Spencer Low    STARTUPINFOW          startup;
573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    PROCESS_INFORMATION   pinfo;
574cf4ff64f2d3cdc4ffa2f06e594d18a965f591a82Spencer Low    WCHAR                 program_path[ MAX_PATH ];
575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                   ret;
576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sa.nLength = sizeof(sa);
578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sa.lpSecurityDescriptor = NULL;
579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sa.bInheritHandle = TRUE;
580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
581d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low    /* Redirect stdin and stderr to Windows /dev/null. If we instead pass our
582d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low     * stdin/stderr handles and they are console handles, when the adb server
583d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low     * starts up, the C Runtime will see console handles for a process that
584d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low     * isn't connected to a console and it will configure stderr to be closed.
585d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low     * At that point, freopen() could be used to reopen stderr, but it would
586d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low     * take more massaging to fixup the file descriptor number that freopen()
587d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low     * uses. It's simplest to avoid all of this complexity by just redirecting
588d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low     * stdin/stderr to `nul' and then the C Runtime acts as expected.
589d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low     */
590d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low    nul_read = CreateFileW(L"nul", GENERIC_READ,
591d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low                           FILE_SHARE_READ | FILE_SHARE_WRITE, &sa,
592d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low                           OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
593d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low    if (nul_read == INVALID_HANDLE_VALUE) {
5948df90321769c670b546a7ff0e7a14f2d7a79cc25Spencer Low        fprintf(stderr, "CreateFileW(nul, GENERIC_READ) failed: %s\n",
5958df90321769c670b546a7ff0e7a14f2d7a79cc25Spencer Low                SystemErrorCodeToString(GetLastError()).c_str());
596d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low        return -1;
597d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low    }
598d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low
599d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low    nul_write = CreateFileW(L"nul", GENERIC_WRITE,
600d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low                            FILE_SHARE_READ | FILE_SHARE_WRITE, &sa,
601d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low                            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
602d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low    if (nul_write == INVALID_HANDLE_VALUE) {
6038df90321769c670b546a7ff0e7a14f2d7a79cc25Spencer Low        fprintf(stderr, "CreateFileW(nul, GENERIC_WRITE) failed: %s\n",
6048df90321769c670b546a7ff0e7a14f2d7a79cc25Spencer Low                SystemErrorCodeToString(GetLastError()).c_str());
605d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low        CloseHandle(nul_read);
606d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low        return -1;
607d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low    }
608d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low
609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* create pipe, and ensure its read handle isn't inheritable */
610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!ret) {
6128df90321769c670b546a7ff0e7a14f2d7a79cc25Spencer Low        fprintf(stderr, "CreatePipe() failed: %s\n",
6138df90321769c670b546a7ff0e7a14f2d7a79cc25Spencer Low                SystemErrorCodeToString(GetLastError()).c_str());
614d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low        CloseHandle(nul_read);
615d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low        CloseHandle(nul_write);
616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );
620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
621267aa8b00eadf273321e492026af74b7baad890eRay Donnelly    /* Some programs want to launch an adb command and collect its output by
622267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     * calling CreateProcess with inheritable stdout/stderr handles, then
623267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     * using read() to get its output. When this happens, the stdout/stderr
624267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     * handles passed to the adb client process will also be inheritable.
625267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     * When starting the adb server here, care must be taken to reset them
626267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     * to non-inheritable.
627267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     * Otherwise, something bad happens: even if the adb command completes,
628267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     * the calling process is stuck while read()-ing from the stdout/stderr
629267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     * descriptors, because they're connected to corresponding handles in the
630267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     * adb server process (even if the latter never uses/writes to them).
631267aa8b00eadf273321e492026af74b7baad890eRay Donnelly     */
632267aa8b00eadf273321e492026af74b7baad890eRay Donnelly    stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE );
633267aa8b00eadf273321e492026af74b7baad890eRay Donnelly    stderr_handle = GetStdHandle( STD_ERROR_HANDLE );
634267aa8b00eadf273321e492026af74b7baad890eRay Donnelly    if (stdout_handle != INVALID_HANDLE_VALUE) {
635267aa8b00eadf273321e492026af74b7baad890eRay Donnelly        SetHandleInformation( stdout_handle, HANDLE_FLAG_INHERIT, 0 );
636267aa8b00eadf273321e492026af74b7baad890eRay Donnelly    }
637267aa8b00eadf273321e492026af74b7baad890eRay Donnelly    if (stderr_handle != INVALID_HANDLE_VALUE) {
638267aa8b00eadf273321e492026af74b7baad890eRay Donnelly        SetHandleInformation( stderr_handle, HANDLE_FLAG_INHERIT, 0 );
639267aa8b00eadf273321e492026af74b7baad890eRay Donnelly    }
640267aa8b00eadf273321e492026af74b7baad890eRay Donnelly
641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ZeroMemory( &startup, sizeof(startup) );
642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    startup.cb = sizeof(startup);
643d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low    startup.hStdInput  = nul_read;
6445c398d2ce96150e94e596e959bfe2246b94de660Spencer Low    startup.hStdOutput = nul_write;
645d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low    startup.hStdError  = nul_write;
646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    startup.dwFlags    = STARTF_USESTDHANDLES;
647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ZeroMemory( &pinfo, sizeof(pinfo) );
649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* get path of current program */
651cf4ff64f2d3cdc4ffa2f06e594d18a965f591a82Spencer Low    DWORD module_result = GetModuleFileNameW(NULL, program_path,
652cf4ff64f2d3cdc4ffa2f06e594d18a965f591a82Spencer Low                                             arraysize(program_path));
653cf4ff64f2d3cdc4ffa2f06e594d18a965f591a82Spencer Low    if ((module_result == arraysize(program_path)) || (module_result == 0)) {
654cf4ff64f2d3cdc4ffa2f06e594d18a965f591a82Spencer Low        // String truncation or some other error.
6558df90321769c670b546a7ff0e7a14f2d7a79cc25Spencer Low        fprintf(stderr, "GetModuleFileNameW() failed: %s\n",
6568df90321769c670b546a7ff0e7a14f2d7a79cc25Spencer Low                SystemErrorCodeToString(GetLastError()).c_str());
657cf4ff64f2d3cdc4ffa2f06e594d18a965f591a82Spencer Low        return -1;
658cf4ff64f2d3cdc4ffa2f06e594d18a965f591a82Spencer Low    }
6595c398d2ce96150e94e596e959bfe2246b94de660Spencer Low
6605c398d2ce96150e94e596e959bfe2246b94de660Spencer Low    // Verify that the pipe_write handle value can be passed on the command line
6615c398d2ce96150e94e596e959bfe2246b94de660Spencer Low    // as %d and that the rest of adb code can pass it around in an int.
6625c398d2ce96150e94e596e959bfe2246b94de660Spencer Low    const int pipe_write_as_int = cast_handle_to_int(pipe_write);
6635c398d2ce96150e94e596e959bfe2246b94de660Spencer Low    if (cast_int_to_handle(pipe_write_as_int) != pipe_write) {
6645c398d2ce96150e94e596e959bfe2246b94de660Spencer Low        // If this fires, either handle values are larger than 32-bits or else
6655c398d2ce96150e94e596e959bfe2246b94de660Spencer Low        // there is a bug in our casting.
6665c398d2ce96150e94e596e959bfe2246b94de660Spencer Low        // https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx
6675c398d2ce96150e94e596e959bfe2246b94de660Spencer Low        fprintf(stderr, "CreatePipe handle value too large: 0x%p\n",
6685c398d2ce96150e94e596e959bfe2246b94de660Spencer Low                pipe_write);
6695c398d2ce96150e94e596e959bfe2246b94de660Spencer Low        return -1;
6705c398d2ce96150e94e596e959bfe2246b94de660Spencer Low    }
6715c398d2ce96150e94e596e959bfe2246b94de660Spencer Low
672cf4ff64f2d3cdc4ffa2f06e594d18a965f591a82Spencer Low    WCHAR args[64];
673cf4ff64f2d3cdc4ffa2f06e594d18a965f591a82Spencer Low    snwprintf(args, arraysize(args),
6745c398d2ce96150e94e596e959bfe2246b94de660Spencer Low              L"adb -P %d fork-server server --reply-fd %d", server_port,
6755c398d2ce96150e94e596e959bfe2246b94de660Spencer Low              pipe_write_as_int);
676cf4ff64f2d3cdc4ffa2f06e594d18a965f591a82Spencer Low    ret = CreateProcessW(
677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            program_path,                              /* program path  */
678a09558c2e205771e6830eeb6241c5c0e3b1cf4ceWenhao Li            args,
679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                    /* the fork-server argument will set the
680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                       debug = 2 in the child           */
681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            NULL,                   /* process handle is not inheritable */
682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            NULL,                    /* thread handle is not inheritable */
683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            TRUE,                          /* yes, inherit some handles */
684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            DETACHED_PROCESS, /* the new process doesn't have a console */
685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            NULL,                     /* use parent's environment block */
686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            NULL,                    /* use parent's starting directory */
687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            &startup,                 /* startup info, i.e. std handles */
688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            &pinfo );
689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
690d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low    CloseHandle( nul_read );
691d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low    CloseHandle( nul_write );
692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    CloseHandle( pipe_write );
693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!ret) {
6958df90321769c670b546a7ff0e7a14f2d7a79cc25Spencer Low        fprintf(stderr, "CreateProcess failed: %s\n",
6968df90321769c670b546a7ff0e7a14f2d7a79cc25Spencer Low                SystemErrorCodeToString(GetLastError()).c_str());
697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CloseHandle( pipe_read );
698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    CloseHandle( pinfo.hProcess );
702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    CloseHandle( pinfo.hThread );
703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* wait for the "OK\n" message */
705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    {
706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char  temp[3];
707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        DWORD  count;
708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = ReadFile( pipe_read, temp, 3, &count, NULL );
710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CloseHandle( pipe_read );
711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ( !ret ) {
7128df90321769c670b546a7ff0e7a14f2d7a79cc25Spencer Low            fprintf(stderr, "could not read ok from ADB Server, error: %s\n",
7138df90321769c670b546a7ff0e7a14f2d7a79cc25Spencer Low                    SystemErrorCodeToString(GetLastError()).c_str());
714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr, "ADB server didn't ACK\n" );
718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
721e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui#else /* !defined(_WIN32) */
722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char    path[PATH_MAX];
723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int     fd[2];
724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // set up a pipe so the child can tell us when it is ready.
7269f2d1a9cfc04e1d5970823da1878097288a9a9cdSiva Velusamy    // fd[0] will be parent's end, and the child will write on fd[1]
727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (pipe(fd)) {
728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
7313166410a82f43d39201be98a8d35c51baa86cb53Alexey Tarasov    get_my_path(path, PATH_MAX);
732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pid_t pid = fork();
733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(pid < 0) return -1;
734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (pid == 0) {
736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // child side of the fork
737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(fd[0]);
739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
740d7b33085117ccbb908a883f624cb1fe5495ee92aMatt Gumbel        char str_port[30];
7419f2d1a9cfc04e1d5970823da1878097288a9a9cdSiva Velusamy        snprintf(str_port, sizeof(str_port), "%d", server_port);
7429f2d1a9cfc04e1d5970823da1878097288a9a9cdSiva Velusamy        char reply_fd[30];
7439f2d1a9cfc04e1d5970823da1878097288a9a9cdSiva Velusamy        snprintf(reply_fd, sizeof(reply_fd), "%d", fd[1]);
744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // child process
7459f2d1a9cfc04e1d5970823da1878097288a9a9cdSiva Velusamy        int result = execl(path, "adb", "-P", str_port, "fork-server", "server", "--reply-fd", reply_fd, NULL);
746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // this should not return
747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else  {
749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // parent side of the fork
750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char  temp[3];
752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // wait for the "OK\n" message
755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(fd[1]);
756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int ret = adb_read(fd[0], temp, 3);
757408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        int saved_errno = errno;
758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(fd[0]);
759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (ret < 0) {
760408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall            fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr, "ADB server didn't ACK\n" );
765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        setsid();
769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
770e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui#endif /* !defined(_WIN32) */
771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
773e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui#endif /* ADB_HOST */
774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
775252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner// Try to handle a network forwarding request.
776252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner// This returns 1 on success, 0 on failure, and -1 to indicate this is not
777252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner// a forwarding-related request.
778aee80fb67bcc3fc5209050c40bd8efc1bbcc0610Elliott Hughesint handle_forward_request(const char* service, TransportType type, const char* serial, int reply_fd)
779252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner{
780252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner    if (!strcmp(service, "list-forward")) {
781252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        // Create the list of forward redirections.
782e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        std::string listeners = format_listeners();
783252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#if ADB_HOST
784e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        SendOkay(reply_fd);
785252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#endif
786e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        SendProtocolString(reply_fd, listeners);
787252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        return 1;
788252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner    }
789252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner
790252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner    if (!strcmp(service, "killforward-all")) {
791252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        remove_all_listeners();
792252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#if ADB_HOST
793252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        /* On the host: 1st OKAY is connect, 2nd OKAY is status */
794e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        SendOkay(reply_fd);
795252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#endif
796e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        SendOkay(reply_fd);
797252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        return 1;
798252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner    }
799252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner
800424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes    if (!strncmp(service, "forward:", 8) || !strncmp(service, "killforward:", 12)) {
801424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes        // killforward:local
802424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes        // forward:(norebind:)?local;remote
803424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes        bool kill_forward = false;
804424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes        bool no_rebind = false;
805424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes        if (android::base::StartsWith(service, "killforward:")) {
806424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            kill_forward = true;
807424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            service += 12;
808a6b340af123b82e3aaa33cb2a0d45f637eeb4759Spencer Low        } else {
809a6b340af123b82e3aaa33cb2a0d45f637eeb4759Spencer Low            service += 8;   // skip past "forward:"
810424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            if (android::base::StartsWith(service, "norebind:")) {
811424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes                no_rebind = true;
812424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes                service += 9;
813424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            }
814252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        }
815252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner
816424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes        std::vector<std::string> pieces = android::base::Split(service, ";");
817252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner
818424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes        if (kill_forward) {
819424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            // Check killforward: parameter format: '<local>'
820424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            if (pieces.size() != 1 || pieces[0].empty()) {
821424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes                SendFail(reply_fd, android::base::StringPrintf("bad killforward: %s", service));
822252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner                return 1;
823252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner            }
824252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        } else {
825424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            // Check forward: parameter format: '<local>;<remote>'
826424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            if (pieces.size() != 2 || pieces[0].empty() || pieces[1].empty() || pieces[1][0] == '*') {
827424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes                SendFail(reply_fd, android::base::StringPrintf("bad forward: %s", service));
828252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner                return 1;
829252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner            }
830252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        }
831252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner
8327be29c819b4fb8bf9b1d4b69a4333f8765de0281Elliott Hughes        std::string error_msg;
833424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes        atransport* transport = acquire_one_transport(kCsAny, type, serial, &error_msg);
834252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        if (!transport) {
835e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes            SendFail(reply_fd, error_msg);
836252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner            return 1;
837252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        }
838252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner
8395200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low        std::string error;
8403bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes        InstallStatus r;
841424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes        if (kill_forward) {
842424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            r = remove_listener(pieces[0].c_str(), transport);
843252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        } else {
8445200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low            r = install_listener(pieces[0], pieces[1].c_str(), transport,
8455200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low                                 no_rebind, &error);
846252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        }
8477b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes        if (r == INSTALL_STATUS_OK) {
848252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#if ADB_HOST
849252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner            /* On the host: 1st OKAY is connect, 2nd OKAY is status */
850e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes            SendOkay(reply_fd);
851252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#endif
852e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes            SendOkay(reply_fd);
853252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner            return 1;
854252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        }
855252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner
8567b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes        std::string message;
8577b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes        switch (r) {
858424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes          case INSTALL_STATUS_OK: message = "success (!)"; break;
8597b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes          case INSTALL_STATUS_INTERNAL_ERROR: message = "internal error"; break;
8607b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes          case INSTALL_STATUS_CANNOT_BIND:
8615200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low            message = android::base::StringPrintf("cannot bind to socket: %s",
8625200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low                                                  error.c_str());
8637b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes            break;
8647b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes          case INSTALL_STATUS_CANNOT_REBIND:
865a6b340af123b82e3aaa33cb2a0d45f637eeb4759Spencer Low            message = android::base::StringPrintf("cannot rebind existing socket");
8667b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes            break;
867424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes          case INSTALL_STATUS_LISTENER_NOT_FOUND:
868424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            message = android::base::StringPrintf("listener '%s' not found", service);
869424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes            break;
870252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        }
871e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        SendFail(reply_fd, message);
872252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner        return 1;
873252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner    }
874252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner    return 0;
875252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner}
876252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner
877e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes#if ADB_HOST
878e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughesstatic int SendOkay(int fd, const std::string& s) {
879e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes    SendOkay(fd);
880e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes    SendProtocolString(fd, s);
881e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes    return 0;
882e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes}
883e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes#endif
884e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes
885c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albertint handle_host_request(const char* service, TransportType type,
886c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert                        const char* serial, int reply_fd, asocket* s) {
887c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    if (strcmp(service, "kill") == 0) {
888c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert        fprintf(stderr, "adb server killed by remote request\n");
889dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fflush(stdout);
890e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        SendOkay(reply_fd);
891f18fc0879be9cd506be6b1e051feb543b0746bdbSpencer Low
892f18fc0879be9cd506be6b1e051feb543b0746bdbSpencer Low        // At least on Windows, if we exit() without shutdown(SD_SEND) or
893f18fc0879be9cd506be6b1e051feb543b0746bdbSpencer Low        // closesocket(), the client's next recv() will error-out with
894f18fc0879be9cd506be6b1e051feb543b0746bdbSpencer Low        // WSAECONNRESET and they'll never read the OKAY.
895f18fc0879be9cd506be6b1e051feb543b0746bdbSpencer Low        adb_shutdown(reply_fd);
896f18fc0879be9cd506be6b1e051feb543b0746bdbSpencer Low
897dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        exit(0);
898dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST
901dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // "transport:" is used for switching transport with a specified serial number
902dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // "transport-usb:" is used for switching transport to the only USB transport
903dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // "transport-local:" is used for switching transport to the only local transport
904dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // "transport-any:" is used for switching transport to the only transport
905dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!strncmp(service, "transport", strlen("transport"))) {
9063bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes        TransportType type = kTransportAny;
907dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
908dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            type = kTransportUsb;
910dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (!strncmp(service, "transport-local", strlen("transport-local"))) {
911dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            type = kTransportLocal;
912dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (!strncmp(service, "transport-any", strlen("transport-any"))) {
913dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            type = kTransportAny;
914dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (!strncmp(service, "transport:", strlen("transport:"))) {
915dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            service += strlen("transport:");
9163175c8e9bfcb01f181d7300755da15a999e5461cTom Marlin            serial = service;
917dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
918dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
919e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes        std::string error_msg;
920e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes        atransport* t = acquire_one_transport(kCsAny, type, serial, &error_msg);
921e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes        if (t != nullptr) {
922e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes            s->transport = t;
923e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes            SendOkay(reply_fd);
924dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
925e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes            SendFail(reply_fd, error_msg);
926dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
927dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
928dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
929dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
930dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // return a list of all connected devices
931e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson    if (!strncmp(service, "devices", 7)) {
932e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        bool long_listing = (strcmp(service+7, "-l") == 0);
933e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        if (long_listing || service[7] == 0) {
934e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes            D("Getting device list...\n");
935e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes            std::string device_list = list_transports(long_listing);
936e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes            D("Sending device list...\n");
937e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes            return SendOkay(reply_fd, device_list);
938e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson        }
939e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        return 1;
940dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
941dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
94274d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood    // remove TCP transport
94374d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood    if (!strncmp(service, "disconnect:", 11)) {
9443d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        const std::string address(service + 11);
9453d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        if (address.empty()) {
946cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood            // disconnect from all TCP devices
947cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood            unregister_all_tcp_transports();
9483d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes            return SendOkay(reply_fd, "disconnected everything");
94974d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood        }
95074d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood
9513d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        std::string serial;
9523d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        std::string host;
9533d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
9543d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        std::string error;
9553d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        if (!parse_host_and_port(address, &serial, &host, &port, &error)) {
9563d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes            return SendFail(reply_fd, android::base::StringPrintf("couldn't parse '%s': %s",
9573d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes                                                                  address.c_str(), error.c_str()));
9583d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        }
9593d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        atransport* t = find_transport(serial.c_str());
9603d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        if (t == nullptr) {
9613d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes            return SendFail(reply_fd, android::base::StringPrintf("no such device '%s'",
9623d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes                                                                  serial.c_str()));
9633d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        }
9643d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        unregister_transport(t);
9653d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        return SendOkay(reply_fd, android::base::StringPrintf("disconnected %s", address.c_str()));
9662f38b699713dc2587a771bd5d4c6a47329728f5eMike Lockwood    }
9672f38b699713dc2587a771bd5d4c6a47329728f5eMike Lockwood
968dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // returns our value for ADB_SERVER_VERSION
969dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!strcmp(service, "version")) {
970e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes        return SendOkay(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION));
971dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
972dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
973e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes    // These always report "unknown" rather than the actual error, for scripts.
974e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes    if (!strcmp(service, "get-serialno")) {
975e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes        std::string ignored;
976e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes        atransport* t = acquire_one_transport(kCsAny, type, serial, &ignored);
977e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes        return SendOkay(reply_fd, (t && t->serial) ? t->serial : "unknown");
978dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
979e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes    if (!strcmp(service, "get-devpath")) {
980e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes        std::string ignored;
981e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes        atransport* t = acquire_one_transport(kCsAny, type, serial, &ignored);
982e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes        return SendOkay(reply_fd, (t && t->devpath) ? t->devpath : "unknown");
983e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson    }
984e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes    if (!strcmp(service, "get-state")) {
985e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes        std::string ignored;
986e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes        atransport* t = acquire_one_transport(kCsAny, type, serial, &ignored);
987e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes        return SendOkay(reply_fd, t ? t->connection_state_name() : "unknown");
988e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes    }
989e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes
990dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // indicates a new emulator instance has started
991e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes    if (!strncmp(service, "emulator:", 9)) {
992dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  port = atoi(service+9);
993dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        local_connect(port);
994dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* we don't even need to send a reply */
995dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
996dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
997dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye#endif // ADB_HOST
998dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye
9993bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes    int ret = handle_forward_request(service, type, serial, reply_fd);
1000dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye    if (ret >= 0)
1001dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye      return ret - 1;
1002dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -1;
1003dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1004