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