adb.cpp revision 8d5fa6da44d56511b3e173bc463cbc65ff221b4a
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> 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 357b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes#include <base/stringprintf.h> 368d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes#include <base/strings.h> 377b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes 38d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#include "adb_auth.h" 39cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert#include "adb_io.h" 40e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert#include "adb_listeners.h" 417664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include "transport.h" 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 43e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 44e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if !ADB_HOST 46893a4a47e8c9290128b9254af0246e36f821c260Nick Kralevich#include <cutils/properties.h> 47e2864bf727d6a404bd871f063c03e36cc8eedeecNick Kralevich#include <sys/capability.h> 48885342a0f2c834a6b680284047c47c9d04b32565Jeff Sharkey#include <sys/mount.h> 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 51408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#if ADB_TRACE 52408fa57864c01113deaa213e5c1848a9c594ae92JP AbgrallADB_MUTEX_DEFINE( D_lock ); 53408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#endif 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint HOST = 0; 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 57e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson#if !ADB_HOST 58bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albertconst char *adb_device_banner = "device"; 59e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson#endif 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fatal(const char *fmt, ...) 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_list ap; 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_start(ap, fmt); 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "error: "); 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project vfprintf(stderr, fmt, ap); 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "\n"); 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_end(ap); 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fatal_errno(const char *fmt, ...) 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_list ap; 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_start(ap, fmt); 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "error: %s: ", strerror(errno)); 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project vfprintf(stderr, fmt, ap); 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "\n"); 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_end(ap); 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 83ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#if !ADB_HOST 84ea2175ab6bae74409620374a96fc9a0097a1845cDan Albertvoid start_device_log(void) { 85ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert struct tm now; 86ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert time_t t; 87ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert tzset(); 88ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert time(&t); 89ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert localtime_r(&t, &now); 90ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 918743ef98414b336f222327253f2cde6bf6aee386Dan Albert char timestamp[PATH_MAX]; 928743ef98414b336f222327253f2cde6bf6aee386Dan Albert strftime(timestamp, sizeof(timestamp), "%Y-%m-%d-%H-%M-%S", &now); 938743ef98414b336f222327253f2cde6bf6aee386Dan Albert 94ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert char path[PATH_MAX]; 958743ef98414b336f222327253f2cde6bf6aee386Dan Albert snprintf(path, sizeof(path), "/data/adb/adb-%s-%d", timestamp, getpid()); 96ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 978743ef98414b336f222327253f2cde6bf6aee386Dan Albert int fd = unix_open(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640); 98ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert if (fd == -1) { 99ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert return; 100ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert } 101ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 102ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert // redirect stdout and stderr to the log file 103ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert dup2(fd, STDOUT_FILENO); 104ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert dup2(fd, STDERR_FILENO); 105ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid()); 106ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert adb_close(fd); 107ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert} 108ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#endif 109ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 110ea2175ab6bae74409620374a96fc9a0097a1845cDan Albertint adb_trace_mask; 111ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 112ea2175ab6bae74409620374a96fc9a0097a1845cDan Albertstd::string get_trace_setting_from_env() { 113ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert const char* setting = getenv("ADB_TRACE"); 114ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert if (setting == nullptr) { 115ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert setting = ""; 116ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert } 117ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 118ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert return std::string(setting); 119ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert} 120ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 121ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#if !ADB_HOST 122ea2175ab6bae74409620374a96fc9a0097a1845cDan Albertstd::string get_trace_setting_from_prop() { 123ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert char buf[PROPERTY_VALUE_MAX]; 124ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert property_get("persist.adb.trace_mask", buf, ""); 125ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert return std::string(buf); 126ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert} 127ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#endif 128ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 129ea2175ab6bae74409620374a96fc9a0097a1845cDan Albertstd::string get_trace_setting() { 130ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#if ADB_HOST 131ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert return get_trace_setting_from_env(); 132ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#else 133ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert return get_trace_setting_from_prop(); 134ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#endif 135ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert} 136ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 137ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert// Split the comma/space/colum/semi-column separated list of tags from the trace 138ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert// setting and build the trace mask from it. note that '1' and 'all' are special 139ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert// cases to enable all tracing. 140ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert// 141ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert// adb's trace setting comes from the ADB_TRACE environment variable, whereas 142ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert// adbd's comes from the system property persist.adb.trace_mask. 143ea2175ab6bae74409620374a96fc9a0097a1845cDan Albertvoid adb_trace_init() { 144ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert const std::string trace_setting = get_trace_setting(); 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static const struct { 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char* tag; 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int flag; 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } tags[] = { 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "1", 0 }, 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "all", 0 }, 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "adb", TRACE_ADB }, 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "sockets", TRACE_SOCKETS }, 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "packets", TRACE_PACKETS }, 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "rwx", TRACE_RWX }, 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "usb", TRACE_USB }, 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "sync", TRACE_SYNC }, 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "sysdeps", TRACE_SYSDEPS }, 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "transport", TRACE_TRANSPORT }, 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "jdwp", TRACE_JDWP }, 161408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall { "services", TRACE_SERVICES }, 162d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby { "auth", TRACE_AUTH }, 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { NULL, 0 } 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project }; 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 166ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert if (trace_setting.empty()) { 167ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert return; 168ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert } 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 170ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert // Use a comma/colon/semi-colon/space separated list 171ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert const char* p = trace_setting.c_str(); 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (*p) { 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len, tagn; 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 175ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert const char* q = strpbrk(p, " ,:;"); 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (q == NULL) { 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project q = p + strlen(p); 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = q - p; 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 181ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert for (tagn = 0; tags[tagn].tag != NULL; tagn++) { 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int taglen = strlen(tags[tagn].tag); 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 184ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert if (len == taglen && !memcmp(tags[tagn].tag, p, len)) { 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int flag = tags[tagn].flag; 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (flag == 0) { 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_trace_mask = ~0; 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_trace_mask |= (1 << flag); 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = q; 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*p) 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p++; 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 198ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 199ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#if !ADB_HOST 200ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert start_device_log(); 201ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#endif 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 204bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albertapacket* get_apacket(void) 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 206bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert apacket* p = reinterpret_cast<apacket*>(malloc(sizeof(apacket))); 207bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (p == nullptr) { 208bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert fatal("failed to allocate an apacket"); 209bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert } 210bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(p, 0, sizeof(apacket) - MAX_PAYLOAD); 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return p; 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid put_apacket(apacket *p) 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(p); 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 220d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobyvoid handle_online(atransport *t) 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("adb: online\n"); 223d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby t->online = 1; 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid handle_offline(atransport *t) 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("adb: offline\n"); 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //Close the associated usb 230d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby t->online = 0; 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project run_transport_disconnects(t); 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 234d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#if DEBUG_PACKETS 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define DUMPMAX 32 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid print_packet(const char *label, apacket *p) 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *tag; 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *x; 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned count; 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(p->msg.command){ 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_SYNC: tag = "SYNC"; break; 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_CNXN: tag = "CNXN" ; break; 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_OPEN: tag = "OPEN"; break; 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_OKAY: tag = "OKAY"; break; 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_CLSE: tag = "CLSE"; break; 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_WRTE: tag = "WRTE"; break; 249d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby case A_AUTH: tag = "AUTH"; break; 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: tag = "????"; break; 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "%s: %s %08x %08x %04x \"", 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length); 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project count = p->msg.data_length; 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x = (char*) p->data; 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(count > DUMPMAX) { 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project count = DUMPMAX; 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tag = "\n"; 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tag = "\"\n"; 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(count-- > 0){ 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((*x >= ' ') && (*x < 127)) { 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fputc(*x, stderr); 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fputc('.', stderr); 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x++; 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 271d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby fputs(tag, stderr); 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void send_ready(unsigned local, unsigned remote, atransport *t) 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("Calling send_ready \n"); 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p = get_apacket(); 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_OKAY; 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = local; 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = remote; 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, t); 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void send_close(unsigned local, unsigned remote, atransport *t) 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("Calling send_close \n"); 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p = get_apacket(); 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_CLSE; 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = local; 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = remote; 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, t); 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 295e82c2db05cae70a0490a1f84b7211ef42c329671Scott Andersonstatic size_t fill_connect_data(char *buf, size_t bufsize) 296e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson{ 297e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson#if ADB_HOST 298e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson return snprintf(buf, bufsize, "host::") + 1; 299e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson#else 300e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson static const char *cnxn_props[] = { 301e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson "ro.product.name", 302e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson "ro.product.model", 303e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson "ro.product.device", 304e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson }; 305e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson static const int num_cnxn_props = ARRAY_SIZE(cnxn_props); 306e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson int i; 307e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson size_t remaining = bufsize; 308e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson size_t len; 309e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson 310e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson len = snprintf(buf, remaining, "%s::", adb_device_banner); 311e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson remaining -= len; 312e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson buf += len; 313e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson for (i = 0; i < num_cnxn_props; i++) { 314e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson char value[PROPERTY_VALUE_MAX]; 315e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson property_get(cnxn_props[i], value, ""); 316e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson len = snprintf(buf, remaining, "%s=%s;", cnxn_props[i], value); 317e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson remaining -= len; 318e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson buf += len; 319e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson } 320e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson 321e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson return bufsize - remaining + 1; 322e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson#endif 323e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson} 324e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson 325252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#if !ADB_HOST 326252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turnerstatic void send_msg_with_header(int fd, const char* msg, size_t msglen) { 327252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner char header[5]; 328252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if (msglen > 0xffff) 329252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner msglen = 0xffff; 330252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner snprintf(header, sizeof(header), "%04x", (unsigned)msglen); 331cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert WriteFdExactly(fd, header, 4); 332cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert WriteFdExactly(fd, msg, msglen); 333252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner} 334252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#endif 335252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 336f787b381b6a304415030ed54bdba6ca482763e4cChih-Hung Hsieh#if ADB_HOST 337252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turnerstatic void send_msg_with_okay(int fd, const char* msg, size_t msglen) { 3382264e7cfef6b1236a90a13b1d99abb4aadcb0b93Snild Dolkow char header[9]; 3392264e7cfef6b1236a90a13b1d99abb4aadcb0b93Snild Dolkow if (msglen > 0xffff) 3402264e7cfef6b1236a90a13b1d99abb4aadcb0b93Snild Dolkow msglen = 0xffff; 3412264e7cfef6b1236a90a13b1d99abb4aadcb0b93Snild Dolkow snprintf(header, sizeof(header), "OKAY%04x", (unsigned)msglen); 342cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert WriteFdExactly(fd, header, 8); 343cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert WriteFdExactly(fd, msg, msglen); 3442264e7cfef6b1236a90a13b1d99abb4aadcb0b93Snild Dolkow} 345f787b381b6a304415030ed54bdba6ca482763e4cChih-Hung Hsieh#endif // ADB_HOST 3462264e7cfef6b1236a90a13b1d99abb4aadcb0b93Snild Dolkow 347ba3a251749c88210949008ae26f8bc04812084c1Dan Albertvoid send_connect(atransport *t) 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("Calling send_connect \n"); 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *cp = get_apacket(); 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cp->msg.command = A_CNXN; 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cp->msg.arg0 = A_VERSION; 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cp->msg.arg1 = MAX_PAYLOAD; 354e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson cp->msg.data_length = fill_connect_data((char *)cp->data, 355e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson sizeof(cp->data)); 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(cp, t); 357d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby} 358d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby 359f787b381b6a304415030ed54bdba6ca482763e4cChih-Hung Hsieh#if ADB_HOST 360bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albertstatic const char* connection_state_name(atransport *t) 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t == NULL) { 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return "unknown"; 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(t->connection_state) { 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_BOOTLOADER: 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return "bootloader"; 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_DEVICE: 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return "device"; 371a5ad539cff9dba92650425b8bec79c071ef5993btrevd case CS_RECOVERY: 372a5ad539cff9dba92650425b8bec79c071ef5993btrevd return "recovery"; 373a5ad539cff9dba92650425b8bec79c071ef5993btrevd case CS_SIDELOAD: 374a5ad539cff9dba92650425b8bec79c071ef5993btrevd return "sideload"; 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_OFFLINE: 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return "offline"; 37777e8e5851d3b951b5382663bd50f1f83cb531eb2Benoit Goby case CS_UNAUTHORIZED: 37877e8e5851d3b951b5382663bd50f1f83cb531eb2Benoit Goby return "unauthorized"; 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return "unknown"; 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 383f787b381b6a304415030ed54bdba6ca482763e4cChih-Hung Hsieh#endif // ADB_HOST 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3858d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes// qual_overwrite is used to overwrite a qualifier string. dst is a 3868d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes// pointer to a char pointer. It is assumed that if *dst is non-NULL, it 3878d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes// was malloc'ed and needs to freed. *dst will be set to a dup of src. 3888d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes// TODO: switch to std::string for these atransport fields instead. 3898d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughesstatic void qual_overwrite(char** dst, const std::string& src) { 390e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson free(*dst); 3918d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes *dst = strdup(src.c_str()); 392e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson} 393e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson 3948d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughesvoid parse_banner(const char* banner, atransport* t) { 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("parse_banner: %s\n", banner); 3968d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes 3978d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes // The format is something like: 3988d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes // "device::ro.product.name=x;ro.product.model=y;ro.product.device=z;". 3998d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes std::vector<std::string> pieces = android::base::Split(banner, ":"); 4008d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes 4018d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes if (pieces.size() > 2) { 4028d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes const std::string& props = pieces[2]; 4038d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes for (auto& prop : android::base::Split(props, ";")) { 4048d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes // The list of properties was traditionally ;-terminated rather than ;-separated. 4058d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes if (prop.empty()) continue; 4068d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes 4078d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes std::vector<std::string> key_value = android::base::Split(prop, "="); 4088d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes if (key_value.size() != 2) continue; 4098d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes 4108d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes const std::string& key = key_value[0]; 4118d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes const std::string& value = key_value[1]; 4128d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes if (key == "ro.product.name") { 4138d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes qual_overwrite(&t->product, value); 4148d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes } else if (key == "ro.product.model") { 4158d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes qual_overwrite(&t->model, value); 4168d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes } else if (key == "ro.product.device") { 4178d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes qual_overwrite(&t->device, value); 418e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson } 419e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson } 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 4228d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes const std::string& type = pieces[0]; 4238d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes if (type == "bootloader") { 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("setting connection_state to CS_BOOTLOADER\n"); 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->connection_state = CS_BOOTLOADER; 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project update_transports(); 4278d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes } else if (type == "device") { 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("setting connection_state to CS_DEVICE\n"); 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->connection_state = CS_DEVICE; 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project update_transports(); 4318d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes } else if (type == "recovery") { 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("setting connection_state to CS_RECOVERY\n"); 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->connection_state = CS_RECOVERY; 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project update_transports(); 4358d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes } else if (type == "sideload") { 436447f061da19fe46bae35f1cdd93eeb16bc225463Doug Zongker D("setting connection_state to CS_SIDELOAD\n"); 437447f061da19fe46bae35f1cdd93eeb16bc225463Doug Zongker t->connection_state = CS_SIDELOAD; 438447f061da19fe46bae35f1cdd93eeb16bc225463Doug Zongker update_transports(); 439447f061da19fe46bae35f1cdd93eeb16bc225463Doug Zongker } 440447f061da19fe46bae35f1cdd93eeb16bc225463Doug Zongker 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->connection_state = CS_HOST; 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid handle_packet(apacket *p, atransport *t) 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket *s; 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 448899913f8168b54e00971c0e8d4ae16d06a4651feViral Mehta D("handle_packet() %c%c%c%c\n", ((char*) (&(p->msg.command)))[0], 449899913f8168b54e00971c0e8d4ae16d06a4651feViral Mehta ((char*) (&(p->msg.command)))[1], 450899913f8168b54e00971c0e8d4ae16d06a4651feViral Mehta ((char*) (&(p->msg.command)))[2], 451899913f8168b54e00971c0e8d4ae16d06a4651feViral Mehta ((char*) (&(p->msg.command)))[3]); 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project print_packet("recv", p); 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(p->msg.command){ 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_SYNC: 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.arg0){ 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, t); 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(HOST) send_connect(t); 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->connection_state = CS_OFFLINE; 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle_offline(t); 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, t); 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */ 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* XXX verify version, etc */ 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(t->connection_state != CS_OFFLINE) { 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->connection_state = CS_OFFLINE; 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle_offline(t); 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 472d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby 4738d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes parse_banner(reinterpret_cast<const char*>(p->data), t); 474d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby 475d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby if (HOST || !auth_enabled) { 476d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby handle_online(t); 477d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby if(!HOST) send_connect(t); 478d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby } else { 479d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby send_auth_request(t); 480d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby } 481d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby break; 482d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby 483d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby case A_AUTH: 484d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby if (p->msg.arg0 == ADB_AUTH_TOKEN) { 48577e8e5851d3b951b5382663bd50f1f83cb531eb2Benoit Goby t->connection_state = CS_UNAUTHORIZED; 486d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby t->key = adb_auth_nextkey(t->key); 487d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby if (t->key) { 488d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby send_auth_response(p->data, p->msg.data_length, t); 489d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby } else { 490d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby /* No more private keys to try, send the public key */ 491d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby send_auth_publickey(t); 492d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby } 493d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby } else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) { 494d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby if (adb_auth_verify(t->token, p->data, p->msg.data_length)) { 495d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby adb_auth_verified(t); 496d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby t->failed_auth_attempts = 0; 497d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby } else { 498d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby if (t->failed_auth_attempts++ > 10) 499d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby adb_sleep_ms(1000); 500d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby send_auth_request(t); 501d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby } 502d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) { 503d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby adb_auth_confirm_key(p->data, p->msg.data_length, t); 504d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby } 505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_OPEN: /* OPEN(local-id, 0, "destination") */ 508818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) { 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *name = (char*) p->data; 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0; 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s = create_local_service_socket(name); 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s == 0) { 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_close(0, p->msg.arg0, t); 514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer = create_remote_socket(p->msg.arg0, t); 516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->peer = s; 517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_ready(s->id, s->peer->id, t); 518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready(s); 519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_OKAY: /* READY(local-id, remote-id, "") */ 524818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) { 525818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if((s = find_local_socket(p->msg.arg1, 0))) { 526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s->peer == 0) { 527818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner /* On first READY message, create the connection. */ 528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer = create_remote_socket(p->msg.arg0, t); 529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->peer = s; 530818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner s->ready(s); 531818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner } else if (s->peer->id == p->msg.arg0) { 532818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner /* Other READY messages must use the same local-id */ 533818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner s->ready(s); 534818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner } else { 535818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner D("Invalid A_OKAY(%d,%d), expected A_OKAY(%d,%d) on transport %s\n", 536818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner p->msg.arg0, p->msg.arg1, s->peer->id, p->msg.arg1, t->serial); 537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 542818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner case A_CLSE: /* CLOSE(local-id, remote-id, "") or CLOSE(0, remote-id, "") */ 543818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if (t->online && p->msg.arg1 != 0) { 544818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) { 545818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner /* According to protocol.txt, p->msg.arg0 might be 0 to indicate 546818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * a failed OPEN only. However, due to a bug in previous ADB 547818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * versions, CLOSE(0, remote-id, "") was also used for normal 548818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * CLOSE() operations. 549818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * 550818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * This is bad because it means a compromised adbd could 551818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * send packets to close connections between the host and 552818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * other devices. To avoid this, only allow this if the local 553818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * socket has a peer on the same transport. 554818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner */ 555818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if (p->msg.arg0 == 0 && s->peer && s->peer->transport != t) { 556818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner D("Invalid A_CLSE(0, %u) from transport %s, expected transport %s\n", 557818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner p->msg.arg1, t->serial, s->peer->transport->serial); 558818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner } else { 559818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner s->close(s); 560818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner } 561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 565818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner case A_WRTE: /* WRITE(local-id, remote-id, <data>) */ 566818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) { 567818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) { 568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned rid = p->msg.arg0; 569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->len = p->msg.data_length; 570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s->enqueue(s, p) == 0) { 572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("Enqueue the socket\n"); 573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_ready(s->id, rid, t); 574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("handle_packet: what is %08x?!\n", p->msg.command); 582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 588571c1367682c83cb23481cc9c1028c8588a1fed0JP Abgrall 589a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzingerint launch_server(int server_port) 590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 591e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui#if defined(_WIN32) 592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* we need to start the server in the background */ 593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* we create a PIPE that will be used to wait for the server's "OK" */ 594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* message since the pipe handles must be inheritable, we use a */ 595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* security attribute */ 596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project HANDLE pipe_read, pipe_write; 597267aa8b00eadf273321e492026af74b7baad890eRay Donnelly HANDLE stdout_handle, stderr_handle; 598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SECURITY_ATTRIBUTES sa; 599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STARTUPINFO startup; 600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project PROCESS_INFORMATION pinfo; 601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char program_path[ MAX_PATH ]; 602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sa.nLength = sizeof(sa); 605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sa.lpSecurityDescriptor = NULL; 606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sa.bInheritHandle = TRUE; 607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* create pipe, and ensure its read handle isn't inheritable */ 609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 ); 610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!ret) { 611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() ); 612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 ); 616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 617267aa8b00eadf273321e492026af74b7baad890eRay Donnelly /* Some programs want to launch an adb command and collect its output by 618267aa8b00eadf273321e492026af74b7baad890eRay Donnelly * calling CreateProcess with inheritable stdout/stderr handles, then 619267aa8b00eadf273321e492026af74b7baad890eRay Donnelly * using read() to get its output. When this happens, the stdout/stderr 620267aa8b00eadf273321e492026af74b7baad890eRay Donnelly * handles passed to the adb client process will also be inheritable. 621267aa8b00eadf273321e492026af74b7baad890eRay Donnelly * When starting the adb server here, care must be taken to reset them 622267aa8b00eadf273321e492026af74b7baad890eRay Donnelly * to non-inheritable. 623267aa8b00eadf273321e492026af74b7baad890eRay Donnelly * Otherwise, something bad happens: even if the adb command completes, 624267aa8b00eadf273321e492026af74b7baad890eRay Donnelly * the calling process is stuck while read()-ing from the stdout/stderr 625267aa8b00eadf273321e492026af74b7baad890eRay Donnelly * descriptors, because they're connected to corresponding handles in the 626267aa8b00eadf273321e492026af74b7baad890eRay Donnelly * adb server process (even if the latter never uses/writes to them). 627267aa8b00eadf273321e492026af74b7baad890eRay Donnelly */ 628267aa8b00eadf273321e492026af74b7baad890eRay Donnelly stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE ); 629267aa8b00eadf273321e492026af74b7baad890eRay Donnelly stderr_handle = GetStdHandle( STD_ERROR_HANDLE ); 630267aa8b00eadf273321e492026af74b7baad890eRay Donnelly if (stdout_handle != INVALID_HANDLE_VALUE) { 631267aa8b00eadf273321e492026af74b7baad890eRay Donnelly SetHandleInformation( stdout_handle, HANDLE_FLAG_INHERIT, 0 ); 632267aa8b00eadf273321e492026af74b7baad890eRay Donnelly } 633267aa8b00eadf273321e492026af74b7baad890eRay Donnelly if (stderr_handle != INVALID_HANDLE_VALUE) { 634267aa8b00eadf273321e492026af74b7baad890eRay Donnelly SetHandleInformation( stderr_handle, HANDLE_FLAG_INHERIT, 0 ); 635267aa8b00eadf273321e492026af74b7baad890eRay Donnelly } 636267aa8b00eadf273321e492026af74b7baad890eRay Donnelly 637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ZeroMemory( &startup, sizeof(startup) ); 638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project startup.cb = sizeof(startup); 639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project startup.hStdInput = GetStdHandle( STD_INPUT_HANDLE ); 640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project startup.hStdOutput = pipe_write; 641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project startup.hStdError = GetStdHandle( STD_ERROR_HANDLE ); 642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project startup.dwFlags = STARTF_USESTDHANDLES; 643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ZeroMemory( &pinfo, sizeof(pinfo) ); 645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* get path of current program */ 647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project GetModuleFileName( NULL, program_path, sizeof(program_path) ); 648a09558c2e205771e6830eeb6241c5c0e3b1cf4ceWenhao Li char args[64]; 649a09558c2e205771e6830eeb6241c5c0e3b1cf4ceWenhao Li snprintf(args, sizeof(args), "adb -P %d fork-server server", server_port); 650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = CreateProcess( 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project program_path, /* program path */ 652a09558c2e205771e6830eeb6241c5c0e3b1cf4ceWenhao Li args, 653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* the fork-server argument will set the 654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project debug = 2 in the child */ 655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NULL, /* process handle is not inheritable */ 656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NULL, /* thread handle is not inheritable */ 657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRUE, /* yes, inherit some handles */ 658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DETACHED_PROCESS, /* the new process doesn't have a console */ 659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NULL, /* use parent's environment block */ 660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NULL, /* use parent's starting directory */ 661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &startup, /* startup info, i.e. std handles */ 662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &pinfo ); 663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project CloseHandle( pipe_write ); 665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!ret) { 667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() ); 668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project CloseHandle( pipe_read ); 669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project CloseHandle( pinfo.hProcess ); 673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project CloseHandle( pinfo.hThread ); 674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* wait for the "OK\n" message */ 676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char temp[3]; 678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DWORD count; 679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = ReadFile( pipe_read, temp, 3, &count, NULL ); 681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project CloseHandle( pipe_read ); 682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ( !ret ) { 683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() ); 684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { 687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "ADB server didn't ACK\n" ); 688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 691e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui#else /* !defined(_WIN32) */ 692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char path[PATH_MAX]; 693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd[2]; 694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // set up a pipe so the child can tell us when it is ready. 696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child. 697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (pipe(fd)) { 698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno); 699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 7013166410a82f43d39201be98a8d35c51baa86cb53Alexey Tarasov get_my_path(path, PATH_MAX); 702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pid_t pid = fork(); 703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(pid < 0) return -1; 704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (pid == 0) { 706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // child side of the fork 707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // redirect stderr to the pipe 709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // we use stderr instead of stdout due to stdout's buffering behavior. 710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd[0]); 711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd[1], STDERR_FILENO); 712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd[1]); 713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 714d7b33085117ccbb908a883f624cb1fe5495ee92aMatt Gumbel char str_port[30]; 715d7b33085117ccbb908a883f624cb1fe5495ee92aMatt Gumbel snprintf(str_port, sizeof(str_port), "%d", server_port); 716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // child process 717d7b33085117ccbb908a883f624cb1fe5495ee92aMatt Gumbel int result = execl(path, "adb", "-P", str_port, "fork-server", "server", NULL); 718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // this should not return 719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno); 720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // parent side of the fork 722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char temp[3]; 724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C'; 726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // wait for the "OK\n" message 727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd[1]); 728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret = adb_read(fd[0], temp, 3); 729408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int saved_errno = errno; 730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd[0]); 731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret < 0) { 732408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno); 733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { 736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "ADB server didn't ACK\n" ); 737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setsid(); 741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 742e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui#endif /* !defined(_WIN32) */ 743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 745e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui#endif /* ADB_HOST */ 746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 747252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner// Try to handle a network forwarding request. 748252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner// This returns 1 on success, 0 on failure, and -1 to indicate this is not 749252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner// a forwarding-related request. 750252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turnerint handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd) 751252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner{ 752252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if (!strcmp(service, "list-forward")) { 753252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner // Create the list of forward redirections. 754252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner int buffer_size = format_listeners(NULL, 0); 755252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner // Add one byte for the trailing zero. 756bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert char* buffer = reinterpret_cast<char*>(malloc(buffer_size + 1)); 757bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (buffer == nullptr) { 758252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner sendfailmsg(reply_fd, "not enough memory"); 759252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return 1; 760252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 761252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner (void) format_listeners(buffer, buffer_size + 1); 762252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#if ADB_HOST 763252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner send_msg_with_okay(reply_fd, buffer, buffer_size); 764252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#else 765252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner send_msg_with_header(reply_fd, buffer, buffer_size); 766252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#endif 767252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner free(buffer); 768252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return 1; 769252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 770252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 771252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if (!strcmp(service, "killforward-all")) { 772252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner remove_all_listeners(); 773252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#if ADB_HOST 774252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner /* On the host: 1st OKAY is connect, 2nd OKAY is status */ 775252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner adb_write(reply_fd, "OKAY", 4); 776252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#endif 777252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner adb_write(reply_fd, "OKAY", 4); 778252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return 1; 779252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 780252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 781252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if (!strncmp(service, "forward:",8) || 782252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner !strncmp(service, "killforward:",12)) { 783bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert char *local, *remote; 784252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner atransport *transport; 785252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 786252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner int createForward = strncmp(service, "kill", 4); 787252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner int no_rebind = 0; 788252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 789252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner local = strchr(service, ':') + 1; 790252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 791252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner // Handle forward:norebind:<local>... here 792252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if (createForward && !strncmp(local, "norebind:", 9)) { 793252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner no_rebind = 1; 794252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner local = strchr(local, ':') + 1; 795252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 796252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 797252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner remote = strchr(local,';'); 798252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 799252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if (createForward) { 800252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner // Check forward: parameter format: '<local>;<remote>' 801252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if(remote == 0) { 802252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner sendfailmsg(reply_fd, "malformed forward spec"); 803252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return 1; 804252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 805252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 806252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner *remote++ = 0; 807252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) { 808252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner sendfailmsg(reply_fd, "malformed forward spec"); 809252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return 1; 810252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 811252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } else { 812252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner // Check killforward: parameter format: '<local>' 813252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if (local[0] == 0) { 814252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner sendfailmsg(reply_fd, "malformed forward spec"); 815252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return 1; 816252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 817252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 818252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 8197be29c819b4fb8bf9b1d4b69a4333f8765de0281Elliott Hughes std::string error_msg; 8207be29c819b4fb8bf9b1d4b69a4333f8765de0281Elliott Hughes transport = acquire_one_transport(CS_ANY, ttype, serial, &error_msg); 821252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if (!transport) { 8227be29c819b4fb8bf9b1d4b69a4333f8765de0281Elliott Hughes sendfailmsg(reply_fd, error_msg.c_str()); 823252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return 1; 824252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 825252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 8267b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes install_status_t r; 827252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if (createForward) { 828252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner r = install_listener(local, remote, transport, no_rebind); 829252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } else { 830252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner r = remove_listener(local, transport); 831252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 8327b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes if (r == INSTALL_STATUS_OK) { 833252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#if ADB_HOST 834252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner /* On the host: 1st OKAY is connect, 2nd OKAY is status */ 835cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert WriteFdExactly(reply_fd, "OKAY", 4); 836252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#endif 837cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert WriteFdExactly(reply_fd, "OKAY", 4); 838252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return 1; 839252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 840252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 8417b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes std::string message; 8427b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes switch (r) { 8437b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes case INSTALL_STATUS_OK: message = " "; break; 8447b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes case INSTALL_STATUS_INTERNAL_ERROR: message = "internal error"; break; 8457b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes case INSTALL_STATUS_CANNOT_BIND: 8467b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes message = android::base::StringPrintf("cannot bind to socket: %s", strerror(errno)); 8477b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes break; 8487b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes case INSTALL_STATUS_CANNOT_REBIND: 8497b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes message = android::base::StringPrintf("cannot rebind existing socket: %s", strerror(errno)); 8507b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes break; 8517b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes case INSTALL_STATUS_LISTENER_NOT_FOUND: message = "listener not found"; break; 852252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 8537b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes sendfailmsg(reply_fd, message.c_str()); 854252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return 1; 855252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 856252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return 0; 857252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner} 858252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s) 860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!strcmp(service, "kill")) { 862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"adb server killed by remote request\n"); 863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fflush(stdout); 864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_write(reply_fd, "OKAY", 4); 865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_cleanup(); 866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(0); 867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 870f787b381b6a304415030ed54bdba6ca482763e4cChih-Hung Hsieh atransport *transport = NULL; 871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // "transport:" is used for switching transport with a specified serial number 872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // "transport-usb:" is used for switching transport to the only USB transport 873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // "transport-local:" is used for switching transport to the only local transport 874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // "transport-any:" is used for switching transport to the only transport 875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strncmp(service, "transport", strlen("transport"))) { 876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_type type = kTransportAny; 877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strncmp(service, "transport-usb", strlen("transport-usb"))) { 879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project type = kTransportUsb; 880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(service, "transport-local", strlen("transport-local"))) { 881dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project type = kTransportLocal; 882dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(service, "transport-any", strlen("transport-any"))) { 883dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project type = kTransportAny; 884dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(service, "transport:", strlen("transport:"))) { 885dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service += strlen("transport:"); 8863175c8e9bfcb01f181d7300755da15a999e5461cTom Marlin serial = service; 887dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 888dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 8897be29c819b4fb8bf9b1d4b69a4333f8765de0281Elliott Hughes std::string error_msg = "unknown failure"; 8907be29c819b4fb8bf9b1d4b69a4333f8765de0281Elliott Hughes transport = acquire_one_transport(CS_ANY, type, serial, &error_msg); 891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (transport) { 893dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->transport = transport; 894dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_write(reply_fd, "OKAY", 4); 895dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 8967be29c819b4fb8bf9b1d4b69a4333f8765de0281Elliott Hughes sendfailmsg(reply_fd, error_msg.c_str()); 897dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 898dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 901dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // return a list of all connected devices 902e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson if (!strncmp(service, "devices", 7)) { 903dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buffer[4096]; 904e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson int use_long = !strcmp(service+7, "-l"); 905e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson if (use_long || service[7] == 0) { 906e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson memset(buffer, 0, sizeof(buffer)); 907e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson D("Getting device list \n"); 908e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson list_transports(buffer, sizeof(buffer), use_long); 909e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson D("Wrote device list \n"); 9102264e7cfef6b1236a90a13b1d99abb4aadcb0b93Snild Dolkow send_msg_with_okay(reply_fd, buffer, strlen(buffer)); 911e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson return 0; 912e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson } 913dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 914dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 91574d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood // remove TCP transport 91674d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood if (!strncmp(service, "disconnect:", 11)) { 91774d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood char buffer[4096]; 91874d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood memset(buffer, 0, sizeof(buffer)); 91974d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood char* serial = service + 11; 920cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (serial[0] == 0) { 921cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood // disconnect from all TCP devices 922cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood unregister_all_tcp_transports(); 92374d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood } else { 924cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood char hostbuf[100]; 925cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood // assume port 5555 if no port is specified 926cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (!strchr(serial, ':')) { 927cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial); 928cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood serial = hostbuf; 929cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 930cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood atransport *t = find_transport(serial); 931cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood 932cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (t) { 933cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood unregister_transport(t); 934cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } else { 935cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood snprintf(buffer, sizeof(buffer), "No such device %s", serial); 936cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 93774d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood } 93874d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood 9392264e7cfef6b1236a90a13b1d99abb4aadcb0b93Snild Dolkow send_msg_with_okay(reply_fd, buffer, strlen(buffer)); 9402f38b699713dc2587a771bd5d4c6a47329728f5eMike Lockwood return 0; 9412f38b699713dc2587a771bd5d4c6a47329728f5eMike Lockwood } 9422f38b699713dc2587a771bd5d4c6a47329728f5eMike Lockwood 943dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // returns our value for ADB_SERVER_VERSION 944dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strcmp(service, "version")) { 945dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char version[12]; 946dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION); 9472264e7cfef6b1236a90a13b1d99abb4aadcb0b93Snild Dolkow send_msg_with_okay(reply_fd, version, strlen(version)); 948dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 949dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 950dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 951dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!strncmp(service,"get-serialno",strlen("get-serialno"))) { 952bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert const char *out = "unknown"; 953bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); 9547be29c819b4fb8bf9b1d4b69a4333f8765de0281Elliott Hughes if (transport && transport->serial) { 955dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out = transport->serial; 956dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 9572264e7cfef6b1236a90a13b1d99abb4aadcb0b93Snild Dolkow send_msg_with_okay(reply_fd, out, strlen(out)); 958dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 959dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 960e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson if(!strncmp(service,"get-devpath",strlen("get-devpath"))) { 961bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert const char *out = "unknown"; 962bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); 9637be29c819b4fb8bf9b1d4b69a4333f8765de0281Elliott Hughes if (transport && transport->devpath) { 964e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson out = transport->devpath; 965e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson } 9662264e7cfef6b1236a90a13b1d99abb4aadcb0b93Snild Dolkow send_msg_with_okay(reply_fd, out, strlen(out)); 967e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson return 0; 968e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson } 969dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // indicates a new emulator instance has started 970dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strncmp(service,"emulator:",9)) { 971dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int port = atoi(service+9); 972dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project local_connect(port); 973dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* we don't even need to send a reply */ 974dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 975dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 976dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 977dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!strncmp(service,"get-state",strlen("get-state"))) { 978dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); 979bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert const char *state = connection_state_name(transport); 9802264e7cfef6b1236a90a13b1d99abb4aadcb0b93Snild Dolkow send_msg_with_okay(reply_fd, state, strlen(state)); 981dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 982dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 983dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye#endif // ADB_HOST 984dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye 985dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye int ret = handle_forward_request(service, ttype, serial, reply_fd); 986dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye if (ret >= 0) 987dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye return ret - 1; 988dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 989dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 990