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