adb.cpp revision 571c1367682c83cb23481cc9c1028c8588a1fed0
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 TRACE_ADB 183313426fad9eaaf53017cdbde889ebcec91358ecDan Albert 193313426fad9eaaf53017cdbde889ebcec91358ecDan Albert#include <stdio.h> 203313426fad9eaaf53017cdbde889ebcec91358ecDan Albert#include <stdlib.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <ctype.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdarg.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 24ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#include <stddef.h> 25c7993af64baec271a238646bc20aaa846866c4a9Scott Anderson#include <string.h> 26ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#include <time.h> 27ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#include <sys/time.h> 28ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "sysdeps.h" 301f546e6d1f6ccd1964336ddf0d8e8b3b11b1e945Mike Lockwood#include "adb.h" 31ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#include "adb_auth.h" 32ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 33ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 34e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if !ADB_HOST 365f787ed2b3b9f6cc02aa5923b95d77e2a5865438David Pursell#include <private/android_filesystem_config.h> 3782ff315bb0fecb9127970e01b399be53c92ca14fElliott Hughes#include <linux/capability.h> 384f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <linux/prctl.h> 394f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <sys/mount.h> 40706955ff0d159d28bb6eb06dc10178624c505f4eDavid Pursell#else 414f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include "usb_vendors.h" 424f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#endif 437b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes 44d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#if ADB_TRACE 45cc731cc76786b6bdc58764aad9924c0d0c8d645fDan AlbertADB_MUTEX_DEFINE( D_lock ); 46e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert#endif 473d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes 487664901a355b959f312e9acff5a0fd31b7139623Dan Albertint HOST = 0; 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint gListenAll = 0; 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 51893a4a47e8c9290128b9254af0246e36f821c260Nick Kralevichstatic int auth_enabled = 0; 52e2864bf727d6a404bd871f063c03e36cc8eedeecNick Kralevich 53885342a0f2c834a6b680284047c47c9d04b32565Jeff Sharkey#if !ADB_HOST 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *adb_device_banner = "device"; 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 5642ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes 5742ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughesvoid fatal(const char *fmt, ...) 5842ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes{ 5942ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes va_list ap; 6042ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes va_start(ap, fmt); 6142ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes fprintf(stderr, "error: "); 6242ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes vfprintf(stderr, fmt, ap); 6342ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes fprintf(stderr, "\n"); 649313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert va_end(ap); 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 674abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao 684abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gaovoid fatal_errno(const char *fmt, ...) 694abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao{ 704abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao va_list ap; 714abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao va_start(ap, fmt); 724abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao fprintf(stderr, "error: %s: ", strerror(errno)); 734abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao vfprintf(stderr, fmt, ap); 744abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao fprintf(stderr, "\n"); 754abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao va_end(ap); 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 774abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao} 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint adb_trace_mask; 809313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert 814abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao/* read a comma/space/colum/semi-column separated list of tags 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * from the ADB_TRACE environment variable and build the trace 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * mask from it. note that '1' and 'all' are special cases to 844abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao * enable all tracing 854abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao */ 864abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gaovoid adb_trace_init(void) 874abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao{ 884abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao const char* p = getenv("ADB_TRACE"); 894abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao const char* q; 904abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao 914abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao static const struct { 924abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao const char* tag; 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int flag; 944abdeee073aecd2130e82f301ceff03dbd27fd72Josh Gao } tags[] = { 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "1", 0 }, 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "all", 0 }, 97bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert { "adb", TRACE_ADB }, 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "sockets", TRACE_SOCKETS }, 99bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert { "packets", TRACE_PACKETS }, 100bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert { "rwx", TRACE_RWX }, 101bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert { "usb", TRACE_USB }, 102bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert { "sync", TRACE_SYNC }, 103bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert { "sysdeps", TRACE_SYSDEPS }, 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "transport", TRACE_TRANSPORT }, 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "jdwp", TRACE_JDWP }, 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "services", TRACE_SERVICES }, 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "auth", TRACE_AUTH }, 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { NULL, 0 } 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project }; 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (p == NULL) 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 113d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* use a comma/column/semi-colum/space separated list */ 1157a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui while (*p) { 116d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby int len, tagn; 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project q = strpbrk(p, " ,:;"); 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (q == NULL) { 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project q = p + strlen(p); 1217a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui } 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = q - p; 123d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby 12434f45c566365c966c78264e8a4dc0cf69957b6faYabin Cui for (tagn = 0; tags[tagn].tag != NULL; tagn++) 125b329824e6c5373ae303269dca285d835ce57e514Yabin Cui { 12634f45c566365c966c78264e8a4dc0cf69957b6faYabin Cui int taglen = strlen(tags[tagn].tag); 12734f45c566365c966c78264e8a4dc0cf69957b6faYabin Cui 12834f45c566365c966c78264e8a4dc0cf69957b6faYabin Cui if (len == taglen && !memcmp(tags[tagn].tag, p, len) ) 129b329824e6c5373ae303269dca285d835ce57e514Yabin Cui { 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int flag = tags[tagn].flag; 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (flag == 0) { 132d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby adb_trace_mask = ~0; 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_trace_mask |= (1 << flag); 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = q; 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*p) 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p++; 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if !ADB_HOST 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 147d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby * Implements ADB tracing inside the emulator. 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdarg.h> 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Redefine open and write for qemu_pipe.h that contains inlined references 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * to those routines. We will redifine them back after qemu_pipe.h inclusion. 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#undef open 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#undef write 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define open adb_open 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define write adb_write 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <hardware/qemu_pipe.h> 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#undef open 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#undef write 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define open ___xxx_open 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define write ___xxx_write 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* A handle to adb-debug qemud service in the emulator. */ 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint adb_debug_qemu = -1; 169d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Initializes connection with the adb-debug qemud service in the emulator. */ 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int adb_qemu_trace_init(void) 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char con_name[32]; 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1757a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui if (adb_debug_qemu >= 0) { 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* adb debugging QEMUD service connection request. */ 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(con_name, sizeof(con_name), "qemud:adb-debug"); 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_debug_qemu = qemu_pipe_open(con_name); 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (adb_debug_qemu >= 0) ? 0 : -1; 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1857a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cuivoid adb_qemu_trace(const char* fmt, ...) 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_list args; 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_start(args, fmt); 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char msg[1024]; 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (adb_debug_qemu >= 0) { 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project vsnprintf(msg, sizeof(msg), fmt, args); 1931792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert adb_write(adb_debug_qemu, msg, strlen(msg)); 1941792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert } 1951792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert} 1961792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert#endif /* !ADB_HOST */ 1971792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert 198e82c2db05cae70a0490a1f84b7211ef42c329671Scott Andersonapacket *get_apacket(void) 199e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson{ 200e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson apacket *p = malloc(sizeof(apacket)); 201e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson if(p == 0) fatal("failed to allocate an apacket"); 2021792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert memset(p, 0, sizeof(apacket) - MAX_PAYLOAD); 2031792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert return p; 204e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson} 2051792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert 2061792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albertvoid put_apacket(apacket *p) 2071792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert{ 208e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson free(p); 209e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson} 2101792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert 2111792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albertvoid handle_online(atransport *t) 2124e2fd36bc8c16147cab323b0418a7666812d3bc7David Pursell{ 2131792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert D("adb: online\n"); 2141792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert t->online = 1; 2151792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert} 2161792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert 217e82c2db05cae70a0490a1f84b7211ef42c329671Scott Andersonvoid handle_offline(atransport *t) 218e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson{ 2191792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert D("adb: offline\n"); 2207a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui //Close the associated usb 2211792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert t->online = 0; 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project run_transport_disconnects(t); 2233d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer} 2243d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer 2251792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert#if DEBUG_PACKETS 2261792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert#define DUMPMAX 32 2271792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albertvoid print_packet(const char *label, apacket *p) 2281792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert{ 2291792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert char *tag; 2301792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert char *x; 2311792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert unsigned count; 2321792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert 2331792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert switch(p->msg.command){ 2341792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert case A_SYNC: tag = "SYNC"; break; 2351792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert case A_CNXN: tag = "CNXN" ; break; 2361792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert case A_OPEN: tag = "OPEN"; break; 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_OKAY: tag = "OKAY"; break; 238d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby case A_CLSE: tag = "CLSE"; break; 239d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby case A_WRTE: tag = "WRTE"; break; 2408d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes case A_AUTH: tag = "AUTH"; break; 2418d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes default: tag = "????"; break; 2428d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes } 2438d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes 2448d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes fprintf(stderr, "%s: %s %08x %08x %04x \"", 245e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length); 2468d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes count = p->msg.data_length; 247e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson x = (char*) p->data; 248e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson if(count > DUMPMAX) { 2491792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert count = DUMPMAX; 2507a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui tag = "\n"; 2518d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes } else { 2528d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes tag = "\"\n"; 2538d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes } 2548d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes while(count-- > 0){ 2558d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes if((*x >= ' ') && (*x < 127)) { 256d2b588e23901538f4b459a71fefdac6fc2748f7eDavid Pursell fputc(*x, stderr); 257d2b588e23901538f4b459a71fefdac6fc2748f7eDavid Pursell } else { 258d2b588e23901538f4b459a71fefdac6fc2748f7eDavid Pursell fputc('.', stderr); 259d2b588e23901538f4b459a71fefdac6fc2748f7eDavid Pursell } 2608d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes x++; 2618d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes } 26265fe2516b402ed8903f2ce39a86fa0bdc2b263a6Elliott Hughes fputs(tag, stderr); 2638d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes} 2648d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes#endif 2658d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes 2668d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughesstatic void send_ready(unsigned local, unsigned remote, atransport *t) 2678d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes{ 2688d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes D("Calling send_ready \n"); 2698d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes apacket *p = get_apacket(); 2708d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes p->msg.command = A_OKAY; 2718d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes p->msg.arg0 = local; 2728d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes p->msg.arg1 = remote; 2738d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes send_packet(p, t); 2748d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes} 2758d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes 2768d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughesstatic void send_close(unsigned local, unsigned remote, atransport *t) 2771792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert{ 2784e2fd36bc8c16147cab323b0418a7666812d3bc7David Pursell D("Calling send_close \n"); 279e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson apacket *p = get_apacket(); 280e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson p->msg.command = A_CLSE; 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = local; 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = remote; 2838d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes send_packet(p, t); 2848d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes} 2857a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui 286dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albertstatic size_t fill_connect_data(char *buf, size_t bufsize) 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 2888d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes#if ADB_HOST 2897a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui return snprintf(buf, bufsize, "host::") + 1; 290dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert#else 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static const char *cnxn_props[] = { 2928d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes "ro.product.name", 2937a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui "ro.product.model", 294dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert "ro.product.device", 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project }; 2968d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes static const int num_cnxn_props = ARRAY_SIZE(cnxn_props); 2977a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui int i; 298dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert size_t remaining = bufsize; 299447f061da19fe46bae35f1cdd93eeb16bc225463Doug Zongker size_t len; 3003ce9575af76fa6dc110506080434303b9459abf4Elliott Hughes 3017a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui len = snprintf(buf, remaining, "%s::", adb_device_banner); 302dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert remaining -= len; 303447f061da19fe46bae35f1cdd93eeb16bc225463Doug Zongker buf += len; 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0; i < num_cnxn_props; i++) { 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 3061792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert property_get(cnxn_props[i], value, ""); 3071792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert len = snprintf(buf, remaining, "%s=%s;", cnxn_props[i], value); 3081792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert remaining -= len; 3091792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert buf += len; 3101792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert } 3111792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert 3121792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert return bufsize - remaining + 1; 3131792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert#endif 3141792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert} 3151792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert 3161792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albertstatic void send_connect(atransport *t) 3171792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert{ 3181792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert D("Calling send_connect \n"); 3191792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert apacket *cp = get_apacket(); 3201792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert cp->msg.command = A_CNXN; 3211792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert cp->msg.arg0 = A_VERSION; 3221792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert cp->msg.arg1 = MAX_PAYLOAD; 3231792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert cp->msg.data_length = fill_connect_data((char *)cp->data, 3241792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert sizeof(cp->data)); 3251792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert send_packet(cp, t); 3261792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert} 3271792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert 3281792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albertstatic void send_auth_request(atransport *t) 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("Calling send_auth_request\n"); 3317a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui apacket *p; 332899913f8168b54e00971c0e8d4ae16d06a4651feViral Mehta int ret; 333899913f8168b54e00971c0e8d4ae16d06a4651feViral Mehta 334899913f8168b54e00971c0e8d4ae16d06a4651feViral Mehta ret = adb_auth_generate_token(t->token, sizeof(t->token)); 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret != sizeof(t->token)) { 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("Error generating token ret=%d\n", ret); 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 339ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = get_apacket(); 341661327e8e40f95076e0e8abe86193da16b061bd8Yabin Cui memcpy(p->data, t->token, ret); 342661327e8e40f95076e0e8abe86193da16b061bd8Yabin Cui p->msg.command = A_AUTH; 343661327e8e40f95076e0e8abe86193da16b061bd8Yabin Cui p->msg.arg0 = ADB_AUTH_TOKEN; 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.data_length = ret; 345dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert send_packet(p, t); 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void send_auth_response(uint8_t *token, size_t token_size, atransport *t) 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("Calling send_auth_response\n"); 3511792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert apacket *p = get_apacket(); 3521792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert int ret; 353d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby 354d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby ret = adb_auth_sign(t->key, token, token_size, p->data); 355d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby if (!ret) { 356d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby D("Error signing the token\n"); 357dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert put_apacket(p); 3580aeb50500c76ea67d6f452907f5503d590e81a54Elliott Hughes return; 359d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby } 3600aeb50500c76ea67d6f452907f5503d590e81a54Elliott Hughes 361d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby p->msg.command = A_AUTH; 362d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby p->msg.arg0 = ADB_AUTH_SIGNATURE; 363d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby p->msg.data_length = ret; 364c8cb38803af20e922419760663ed1627e865fad2Josh Gao send_packet(p, t); 365d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby} 366d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby 367d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobystatic void send_auth_publickey(atransport *t) 368d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby{ 369d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby D("Calling send_auth_publickey\n"); 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p = get_apacket(); 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 373818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner ret = adb_auth_get_userkey(p->data, sizeof(p->data)); 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!ret) { 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("Failed to get user public key\n"); 376ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes put_apacket(p); 377ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes return; 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_AUTH; 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = ADB_AUTH_RSAPUBLICKEY; 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.data_length = ret; 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, t); 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid adb_auth_verified(atransport *t) 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle_online(t); 389818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner send_connect(t); 390ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes} 391ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char *connection_state_name(atransport *t) 393818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner{ 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t == NULL) { 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return "unknown"; 396818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner } 397818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner 398818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner switch(t->connection_state) { 399818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner case CS_BOOTLOADER: 400818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner return "bootloader"; 4017a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui case CS_DEVICE: 402818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner return "device"; 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_OFFLINE: 404aa77e22d7384a97757e2d2194f4e265f7ad3b71aYabin Cui return "offline"; 405aa77e22d7384a97757e2d2194f4e265f7ad3b71aYabin Cui default: 406aa77e22d7384a97757e2d2194f4e265f7ad3b71aYabin Cui return "unknown"; 407aa77e22d7384a97757e2d2194f4e265f7ad3b71aYabin Cui } 408aa77e22d7384a97757e2d2194f4e265f7ad3b71aYabin Cui} 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* qual_overwrite is used to overwrite a qualifier string. dst is a 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * pointer to a char pointer. It is assumed that if *dst is non-NULL, it 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * was malloc'ed and needs to freed. *dst will be set to a dup of src. 413818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner */ 414818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turnerstatic void qual_overwrite(char **dst, const char *src) 415ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes{ 416ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes if (!dst) 417818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner return; 418818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner 419818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner free(*dst); 420818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner *dst = NULL; 421818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner 422818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if (!src || !*src) 423818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner return; 424818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner 425818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner *dst = strdup(src); 426818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner} 427818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner 4287a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cuivoid parse_banner(char *banner, atransport *t) 429818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner{ 430818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner static const char *prop_seps = ";"; 431818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner static const char key_val_sep = '='; 432818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner char *cp; 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *type; 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("parse_banner: %s\n", banner); 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project type = banner; 437818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner cp = strchr(type, ':'); 438818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if (cp) { 439ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes *cp++ = 0; 440ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes /* Nothing is done with second field. */ 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cp = strchr(cp, ':'); 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (cp) { 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *save; 444ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes char *key; 4457a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui key = adb_strtok_r(cp + 1, prop_seps, &save); 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (key) { 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cp = strchr(key, key_val_sep); 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (cp) { 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *cp++ = '\0'; 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strcmp(key, "ro.product.name")) 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project qual_overwrite(&t->product, cp); 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if (!strcmp(key, "ro.product.model")) 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project qual_overwrite(&t->model, cp); 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if (!strcmp(key, "ro.product.device")) 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project qual_overwrite(&t->device, cp); 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project key = adb_strtok_r(NULL, prop_seps, &save); 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 461571c1367682c83cb23481cc9c1028c8588a1fed0JP Abgrall 4622122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if(!strcmp(type, "bootloader")){ 4632122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low D("setting connection_state to CS_BOOTLOADER\n"); 464bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low t->connection_state = CS_BOOTLOADER; 465bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low update_transports(); 466bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low return; 467bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low } 468bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low 4692122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if(!strcmp(type, "device")) { 470bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low D("setting connection_state to CS_DEVICE\n"); 471bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low t->connection_state = CS_DEVICE; 472bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low update_transports(); 473bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low return; 474bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low } 475bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low 476bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low if(!strcmp(type, "recovery")) { 477bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low D("setting connection_state to CS_RECOVERY\n"); 478bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low t->connection_state = CS_RECOVERY; 479bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low update_transports(); 480bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low return; 481bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low } 482bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low 4835f787ed2b3b9f6cc02aa5923b95d77e2a5865438David Pursell if(!strcmp(type, "sideload")) { 484bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low D("setting connection_state to CS_SIDELOAD\n"); 4852122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low t->connection_state = CS_SIDELOAD; 4862122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low update_transports(); 4872122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return; 4882122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 4892122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 4902122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low t->connection_state = CS_HOST; 4912122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low} 4922122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 4932122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Lowvoid handle_packet(apacket *p, atransport *t) 4942122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low{ 4952122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low asocket *s; 4962122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 4972122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low D("handle_packet() %c%c%c%c\n", ((char*) (&(p->msg.command)))[0], 4982122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low ((char*) (&(p->msg.command)))[1], 4995f787ed2b3b9f6cc02aa5923b95d77e2a5865438David Pursell ((char*) (&(p->msg.command)))[2], 5002122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low ((char*) (&(p->msg.command)))[3]); 5012122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low print_packet("recv", p); 5022122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 5032122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low switch(p->msg.command){ 5042122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low case A_SYNC: 5052122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if(p->msg.arg0){ 5062122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low send_packet(p, t); 5072122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if(HOST) send_connect(t); 5082122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } else { 5092122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low t->connection_state = CS_OFFLINE; 5102122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low handle_offline(t); 5112122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low send_packet(p, t); 5122122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 5132122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return; 5142122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 5152122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */ 5162122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low /* XXX verify version, etc */ 5172122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if(t->connection_state != CS_OFFLINE) { 51853a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low t->connection_state = CS_OFFLINE; 51953a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low handle_offline(t); 52053a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low } 5212122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 5222122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low parse_banner((char*) p->data, t); 5232122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 52453a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low if (HOST || !auth_enabled) { 52553a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low handle_online(t); 52653a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low if(!HOST) send_connect(t); 52753a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low } else { 52853a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low send_auth_request(t); 52953a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low } 53053a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low break; 53153a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low 53253a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low case A_AUTH: 53353a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low if (p->msg.arg0 == ADB_AUTH_TOKEN) { 53453a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low t->key = adb_auth_nextkey(t->key); 53553a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low if (t->key) { 53653a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low send_auth_response(p->data, p->msg.data_length, t); 53753a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low } else { 53853a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low /* No more private keys to try, send the public key */ 53953a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low send_auth_publickey(t); 54053a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low } 54153a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low } else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) { 54253a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low if (adb_auth_verify(t->token, p->data, p->msg.data_length)) { 54353a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low adb_auth_verified(t); 54453a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low t->failed_auth_attempts = 0; 54553a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low } else { 54653a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low if (t->failed_auth_attempts++ > 10) 54753a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low adb_sleep_ms(1000); 54853a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low send_auth_request(t); 54953a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low } 55053a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) { 55153a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low adb_auth_confirm_key(p->data, p->msg.data_length, t); 55253a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low } 55353a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low break; 55453a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low 55553a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low case A_OPEN: /* OPEN(local-id, 0, "destination") */ 55653a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low if (t->online) { 55753a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low char *name = (char*) p->data; 55853a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0; 55953a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low s = create_local_service_socket(name); 56053a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low if(s == 0) { 56153a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low send_close(0, p->msg.arg0, t); 56253a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low } else { 56353a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low s->peer = create_remote_socket(p->msg.arg0, t); 56453a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low s->peer->peer = s; 56553a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low send_ready(s->id, s->peer->id, t); 56653a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low s->ready(s); 56753a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low } 56853a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low } 56953a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low break; 57053a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low 57153a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low case A_OKAY: /* READY(local-id, remote-id, "") */ 5722122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (t->online) { 5732122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if((s = find_local_socket(p->msg.arg1))) { 5742122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if(s->peer == 0) { 5752122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low s->peer = create_remote_socket(p->msg.arg0, t); 5762122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low s->peer->peer = s; 5772122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 5782122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low s->ready(s); 5792122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 5802122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 5812122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low break; 5822122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 5832122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low case A_CLSE: /* CLOSE(local-id, remote-id, "") */ 5845f787ed2b3b9f6cc02aa5923b95d77e2a5865438David Pursell if (t->online) { 5852122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if((s = find_local_socket(p->msg.arg1))) { 5862122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low s->close(s); 5872122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 5882122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 58953a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low break; 59053a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low 59153a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low case A_WRTE: 59253a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low if (t->online) { 5932122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if((s = find_local_socket(p->msg.arg1))) { 59453a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low unsigned rid = p->msg.arg0; 59553a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low p->len = p->msg.data_length; 5962122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 5972122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if(s->enqueue(s, p) == 0) { 5982122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low D("Enqueue the socket\n"); 5992122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low send_ready(s->id, rid, t); 6002122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 6012122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return; 6022122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 60349ee7cf9a10f66ffa9a3490c69db5fa46e0a966bSiva Velusamy } 6042122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low break; 6052122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6062122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low default: 6072122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low printf("handle_packet: what is %08x?!\n", p->msg.command); 60849ee7cf9a10f66ffa9a3490c69db5fa46e0a966bSiva Velusamy } 6092122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6102122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low put_apacket(p); 6112122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low} 6122122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6132122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Lowalistener listener_list = { 614a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger .next = &listener_list, 615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project .prev = &listener_list, 616e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui}; 617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void ss_listener_event_func(int _fd, unsigned ev, void *_l) 619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket *s; 621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ev & FDE_READ) { 623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct sockaddr addr; 624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project socklen_t alen; 625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 6262122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6272122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low alen = sizeof(addr); 6282122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low fd = adb_socket_accept(_fd, &addr, &alen); 6292122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if(fd < 0) return; 6302122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6312122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low adb_socket_setbufsize(fd, CHUNK_SIZE); 6322122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6332122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low s = create_local_socket(fd); 6342122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if(s) { 6352122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low connect_to_smartsocket(s); 6362122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return; 6372122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 6382122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6392122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low adb_close(fd); 6405f787ed2b3b9f6cc02aa5923b95d77e2a5865438David Pursell } 641d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low} 642d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low 643d0f66c361641dc30162877ee3e4b4690d6833442Spencer Lowstatic void listener_event_func(int _fd, unsigned ev, void *_l) 64453a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low{ 64553a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low alistener *l = _l; 64653a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low asocket *s; 64753a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low 6482122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if(ev & FDE_READ) { 6492122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low struct sockaddr addr; 650d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low socklen_t alen; 651d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low int fd; 6522122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6532122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low alen = sizeof(addr); 6542122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low fd = adb_socket_accept(_fd, &addr, &alen); 6552122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if(fd < 0) return; 6562122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6572122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low s = create_local_socket(fd); 658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s) { 659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->transport = l->transport; 660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project connect_to_remote(s, l->connect_to); 661267aa8b00eadf273321e492026af74b7baad890eRay Donnelly return; 662267aa8b00eadf273321e492026af74b7baad890eRay Donnelly } 663267aa8b00eadf273321e492026af74b7baad890eRay Donnelly 664267aa8b00eadf273321e492026af74b7baad890eRay Donnelly adb_close(fd); 665267aa8b00eadf273321e492026af74b7baad890eRay Donnelly } 666267aa8b00eadf273321e492026af74b7baad890eRay Donnelly} 667267aa8b00eadf273321e492026af74b7baad890eRay Donnelly 668267aa8b00eadf273321e492026af74b7baad890eRay Donnellystatic void free_listener(alistener* l) 669267aa8b00eadf273321e492026af74b7baad890eRay Donnelly{ 670267aa8b00eadf273321e492026af74b7baad890eRay Donnelly if (l->next) { 6712122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low l->next->prev = l->prev; 6722122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low l->prev->next = l->next; 6732122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low l->next = l->prev = l; 6742122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 6752122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6762122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // closes the corresponding fd 6772122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low fdevent_remove(&l->fde); 678bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low 679bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low if (l->local_name) 680bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low free((char*)l->local_name); 681267aa8b00eadf273321e492026af74b7baad890eRay Donnelly 682bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low if (l->connect_to) 683bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low free((char*)l->connect_to); 684bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low 685267aa8b00eadf273321e492026af74b7baad890eRay Donnelly if (l->transport) { 6862122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low remove_transport_disconnect(l->transport, &l->disconnect); 687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(l); 6892122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low} 6902122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6912122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Lowstatic void listener_disconnect(void* _l, atransport* t) 692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project alistener* l = _l; 6945c398d2ce96150e94e596e959bfe2246b94de660Spencer Low 6955c398d2ce96150e94e596e959bfe2246b94de660Spencer Low free_listener(l); 6962122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low} 6972122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6985c398d2ce96150e94e596e959bfe2246b94de660Spencer Lowint local_name_to_fd(const char *name) 6995c398d2ce96150e94e596e959bfe2246b94de660Spencer Low{ 7005c398d2ce96150e94e596e959bfe2246b94de660Spencer Low int port; 7012122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 7022122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if(!strncmp("tcp:", name, 4)){ 7035c398d2ce96150e94e596e959bfe2246b94de660Spencer Low int ret; 7045c398d2ce96150e94e596e959bfe2246b94de660Spencer Low port = atoi(name + 4); 7055c398d2ce96150e94e596e959bfe2246b94de660Spencer Low 7062122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (gListenAll > 0) { 7072122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low ret = socket_inaddr_any_server(port, SOCK_STREAM); 7082122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } else { 7092122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low ret = socket_loopback_server(port, SOCK_STREAM); 7102122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 7112122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 7122122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return ret; 7135f787ed2b3b9f6cc02aa5923b95d77e2a5865438David Pursell } 7142122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low#ifndef HAVE_WIN32_IPC /* no Unix-domain sockets on Win32 */ 7152122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // It's non-sensical to support the "reserved" space on the adb host side 7162122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if(!strncmp(name, "local:", 6)) { 7172122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return socket_local_server(name + 6, 718cf4ff64f2d3cdc4ffa2f06e594d18a965f591a82Spencer Low ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); 7195c398d2ce96150e94e596e959bfe2246b94de660Spencer Low } else if(!strncmp(name, "localabstract:", 14)) { 7202122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return socket_local_server(name + 14, 7212122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); 7222122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } else if(!strncmp(name, "localfilesystem:", 16)) { 7232122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return socket_local_server(name + 16, 7242122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM); 7252122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 727a09558c2e205771e6830eeb6241c5c0e3b1cf4ceWenhao Li#endif 728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("unknown local portname '%s'\n", name); 729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// Write a single line describing a listener to a user-provided buffer. 733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// Appends a trailing zero, even in case of truncation, but the function 734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// returns the full line length. 735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// If |buffer| is NULL, does not write but returns required size. 736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int format_listener(alistener* l, char* buffer, size_t buffer_len) { 7372122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // Format is simply: 7382122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // 7395f787ed2b3b9f6cc02aa5923b95d77e2a5865438David Pursell // <device-serial> " " <local-name> " " <remote-name> "\n" 7402122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // 7412122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low int local_len = strlen(l->local_name); 742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int connect_len = strlen(l->connect_to); 7432122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low int serial_len = strlen(l->transport->serial); 7442122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 7452122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (buffer != NULL) { 7462122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low snprintf(buffer, buffer_len, "%s %s %s\n", 7472122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low l->transport->serial, l->local_name, l->connect_to); 7482122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 7492122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // NOTE: snprintf() on Windows returns -1 in case of truncation, so 7502122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // return the computed line length instead. 7512122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return local_len + connect_len + serial_len + 3; 7522122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low} 7532122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 7542122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low// Write the list of current listeners (network redirections) into a 75553a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low// user-provided buffer. Appends a trailing zero, even in case of 75653a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low// trunctaion, but return the full size in bytes. 75753a0a99fe8197984acd5ed6324e945c09772a73eSpencer Low// If |buffer| is NULL, does not write but returns required size. 7582122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Lowstatic int format_listeners(char* buf, size_t buflen) 7592122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low{ 7602122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low alistener* l; 7612122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low int result = 0; 7622122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low for (l = listener_list.next; l != &listener_list; l = l->next) { 7632122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // Ignore special listeners like those for *smartsocket* 7642122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (l->connect_to[0] == '*') 7652122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low continue; 7662122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low int len = format_listener(l, buf, buflen); 7672122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // Ensure there is space for the trailing zero. 7682122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low result += len; 7692122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (buf != NULL) { 7702122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low buf += len; 7712122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low buflen -= len; 772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (buflen <= 0) 7732122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low break; 7742122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 7752122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 7762122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return result; 7772122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low} 778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int remove_listener(const char *local_name, atransport* transport) 7802122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low{ 781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project alistener *l; 7822122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (l = listener_list.next; l != &listener_list; l = l->next) { 7842122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (!strcmp(local_name, l->local_name)) { 785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project listener_disconnect(l, l->transport); 7862122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return 0; 7872122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 7882122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 7892122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return -1; 7902122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low} 7912122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 7922122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Lowstatic void remove_all_listeners(void) 7932122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low{ 7942122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low alistener *l, *l_next; 7952122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low for (l = listener_list.next; l != &listener_list; l = l_next) { 7962122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low l_next = l->next; 7972122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // Never remove smart sockets. 7982122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (l->connect_to[0] == '*') 7992122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low continue; 8002122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low listener_disconnect(l, l->transport); 8012122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 8022122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low} 8032122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 8042122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low// error/status codes for install_listener. 8052122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Lowtypedef enum { 8065f787ed2b3b9f6cc02aa5923b95d77e2a5865438David Pursell INSTALL_STATUS_OK = 0, 807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INSTALL_STATUS_INTERNAL_ERROR = -1, 8082122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low INSTALL_STATUS_CANNOT_BIND = -2, 8092122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low INSTALL_STATUS_CANNOT_REBIND = -3, 8102122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low} install_status_t; 8112122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 8122122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Lowstatic install_status_t install_listener(const char *local_name, 8132122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low const char *connect_to, 8142122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low atransport* transport, 8152122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low int no_rebind) 8162122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low{ 8172122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low alistener *l; 8182122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 8192122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low //printf("install_listener('%s','%s')\n", local_name, connect_to); 8202122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 8212122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low for(l = listener_list.next; l != &listener_list; l = l->next){ 8222122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if(strcmp(local_name, l->local_name) == 0) { 8232122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low char *cto; 8242122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 8252122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low /* can't repurpose a smartsocket */ 8262122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if(l->connect_to[0] == '*') { 8272122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return INSTALL_STATUS_INTERNAL_ERROR; 8282122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 8292122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 8302122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low /* can't repurpose a listener if 'no_rebind' is true */ 831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (no_rebind) { 8322122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return INSTALL_STATUS_CANNOT_REBIND; 8332122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 8342122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 8352122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low cto = strdup(connect_to); 8362122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if(cto == 0) { 8375f787ed2b3b9f6cc02aa5923b95d77e2a5865438David Pursell return INSTALL_STATUS_INTERNAL_ERROR; 8382122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 8392122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 8402122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low //printf("rebinding '%s' to '%s'\n", local_name, connect_to); 8412122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low free((void*) l->connect_to); 8422122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low l->connect_to = cto; 8432122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (l->transport != transport) { 8442122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low remove_transport_disconnect(l->transport, &l->disconnect); 845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project l->transport = transport; 846e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui add_transport_disconnect(l->transport, &l->disconnect); 847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 8489f2d1a9cfc04e1d5970823da1878097288a9a9cdSiva Velusamy return INSTALL_STATUS_OK; 84982ff315bb0fecb9127970e01b399be53c92ca14fElliott Hughes } 850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((l = calloc(1, sizeof(alistener))) == 0) goto nomem; 853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((l->local_name = strdup(local_name)) == 0) goto nomem; 85482ff315bb0fecb9127970e01b399be53c92ca14fElliott Hughes if((l->connect_to = strdup(connect_to)) == 0) goto nomem; 85582ff315bb0fecb9127970e01b399be53c92ca14fElliott Hughes 85682ff315bb0fecb9127970e01b399be53c92ca14fElliott Hughes 857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project l->fd = local_name_to_fd(local_name); 85882ff315bb0fecb9127970e01b399be53c92ca14fElliott Hughes if(l->fd < 0) { 859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free((void*) l->local_name); 860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free((void*) l->connect_to); 861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(l); 862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("cannot bind '%s'\n", local_name); 863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -2; 864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 865d7b33085117ccbb908a883f624cb1fe5495ee92aMatt Gumbel 8669f2d1a9cfc04e1d5970823da1878097288a9a9cdSiva Velusamy close_on_exec(l->fd); 8679f2d1a9cfc04e1d5970823da1878097288a9a9cdSiva Velusamy if(!strcmp(l->connect_to, "*smartsocket*")) { 8689f2d1a9cfc04e1d5970823da1878097288a9a9cdSiva Velusamy fdevent_install(&l->fde, l->fd, ss_listener_event_func, l); 869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 87082ff315bb0fecb9127970e01b399be53c92ca14fElliott Hughes fdevent_install(&l->fde, l->fd, listener_event_func, l); 871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_set(&l->fde, FDE_READ); 873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project l->next = &listener_list; 875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project l->prev = listener_list.prev; 876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project l->next->prev = l; 877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project l->prev->next = l; 878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project l->transport = transport; 879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (transport) { 881dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project l->disconnect.opaque = l; 882408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall l->disconnect.func = listener_disconnect; 883dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project add_transport_disconnect(transport, &l->disconnect); 884dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 885408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall return INSTALL_STATUS_OK; 886dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 887dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnomem: 888dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal("cannot allocate listener"); 889dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return INSTALL_STATUS_INTERNAL_ERROR; 890dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_WIN32_PROC 893e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cuistatic BOOL WINAPI ctrlc_handler(DWORD type) 894dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 895dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(STATUS_CONTROL_C_EXIT); 896e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui return TRUE; 897dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 898252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#endif 899252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 900252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turnerstatic void adb_cleanup(void) 901aee80fb67bcc3fc5209050c40bd8efc1bbcc0610Elliott Hughes{ 902252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner usb_cleanup(); 903252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner} 904252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 905e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughesvoid start_logging(void) 906252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner{ 907e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes#ifdef HAVE_WIN32_PROC 908252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner char temp[ MAX_PATH ]; 9097e6683ce40ba79c94ccc1e3b984cd39e63651dd5Josh Gao FILE* fnul; 910252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner FILE* flog; 911252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 912252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner GetTempPath( sizeof(temp) - 8, temp ); 913252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner strcat( temp, "adb.log" ); 914252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 915252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner /* Win32 specific redirections */ 916e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes fnul = fopen( "NUL", "rt" ); 917252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if (fnul != NULL) 918e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes stdin[0] = fnul[0]; 919252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 920252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner flog = fopen( temp, "at" ); 921252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if (flog == NULL) 922424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes flog = fnul; 923424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes 924424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes setvbuf( flog, NULL, _IONBF, 0 ); 925424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes 926424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes stdout[0] = flog[0]; 927424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes stderr[0] = flog[0]; 928424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid()); 929424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes#else 930a6b340af123b82e3aaa33cb2a0d45f637eeb4759Spencer Low int fd; 931a6b340af123b82e3aaa33cb2a0d45f637eeb4759Spencer Low 932424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes fd = unix_open("/dev/null", O_RDONLY); 933424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes dup2(fd, 0); 934424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes adb_close(fd); 935424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes 936252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner fd = unix_open("/tmp/adb.log", O_WRONLY | O_CREAT | O_APPEND, 0640); 937252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if(fd < 0) { 938424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes fd = unix_open("/dev/null", O_WRONLY); 939252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 940424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes dup2(fd, 1); 941424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes dup2(fd, 2); 942424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes adb_close(fd); 943424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid()); 944252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#endif 945252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner} 946252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 947424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes#if !ADB_HOST 948424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughesvoid start_device_log(void) 949424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes{ 950252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner int fd; 951252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner char path[PATH_MAX]; 952252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner struct tm now; 953252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner time_t t; 9547be29c819b4fb8bf9b1d4b69a4333f8765de0281Elliott Hughes char value[PROPERTY_VALUE_MAX]; 9558d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes 956252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner // read the trace mask from persistent property persist.adb.trace_mask 957e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes // give up if the property is not set or cannot be parsed 958252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner property_get("persist.adb.trace_mask", value, ""); 959252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if (sscanf(value, "%x", &adb_trace_mask) != 1) 960252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return; 9615200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low 9623bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes adb_mkdir("/data/adb", 0775); 963eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell tzset(); 964424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes time(&t); 965424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes localtime_r(&t, &now); 966252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner strftime(path, sizeof(path), 967eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell "/data/adb/adb-%Y-%m-%d-%H-%M-%S.txt", 968eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell &now); 969252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner fd = unix_open(path, O_WRONLY | O_CREAT | O_TRUNC, 0640); 9707b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes if (fd < 0) 971252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return; 972eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell 973e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes // redirect stdout and stderr to the log file 974252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner dup2(fd, 1); 975e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes dup2(fd, 2); 976eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid()); 977eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell adb_close(fd); 978eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell 979eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell fd = unix_open("/dev/null", O_RDONLY); 980eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell dup2(fd, 0); 981eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell adb_close(fd); 982252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner} 983252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#endif 984252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 9857b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes#if ADB_HOST 9867b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes 987424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes#ifdef WORKAROUND_BUG6558362 9887b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes#include <sched.h> 9897b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes#define AFFINITY_ENVVAR "ADB_CPU_AFFINITY_BUG6558362" 990bf7c605d87f87c03066c384cecb0f0c91aa31403Spencer Lowvoid adb_set_affinity(void) 9915200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low{ 9927b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes cpu_set_t cpu_set; 9937b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes const char* cpunum_str = getenv(AFFINITY_ENVVAR); 994a6b340af123b82e3aaa33cb2a0d45f637eeb4759Spencer Low char* strtol_res; 9957b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes int cpu_num; 996424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes 997424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes if (!cpunum_str || !*cpunum_str) 998424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes return; 999252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner cpu_num = strtol(cpunum_str, &strtol_res, 0); 1000e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes if (*strtol_res != '\0') 1001252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner fatal("bad number (%s) in env var %s. Expecting 0..n.\n", cpunum_str, AFFINITY_ENVVAR); 1002252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 1003252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner sched_getaffinity(0, sizeof(cpu_set), &cpu_set); 1004252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner D("orig cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]); 1005252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner CPU_ZERO(&cpu_set); 1006e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes CPU_SET(cpu_num, &cpu_set); 1007e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes sched_setaffinity(0, sizeof(cpu_set), &cpu_set); 1008e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes sched_getaffinity(0, sizeof(cpu_set), &cpu_set); 1009e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes D("new cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]); 1010e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes} 1011e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes#endif 1012e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes 1013e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughesint launch_server(int server_port) 1014c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert{ 1015c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert#ifdef HAVE_WIN32_PROC 1016c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert /* we need to start the server in the background */ 1017c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert /* we create a PIPE that will be used to wait for the server's "OK" */ 1018dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* message since the pipe handles must be inheritable, we use a */ 1019e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes /* security attribute */ 1020f18fc0879be9cd506be6b1e051feb543b0746bdbSpencer Low HANDLE pipe_read, pipe_write; 1021351ecd15b29f0ce528ffac119640b9c01874562bSpencer Low SECURITY_ATTRIBUTES sa; 1022351ecd15b29f0ce528ffac119640b9c01874562bSpencer Low STARTUPINFO startup; 1023351ecd15b29f0ce528ffac119640b9c01874562bSpencer Low PROCESS_INFORMATION pinfo; 1024351ecd15b29f0ce528ffac119640b9c01874562bSpencer Low char program_path[ MAX_PATH ]; 1025351ecd15b29f0ce528ffac119640b9c01874562bSpencer Low int ret; 1026f18fc0879be9cd506be6b1e051feb543b0746bdbSpencer Low 1027f18fc0879be9cd506be6b1e051feb543b0746bdbSpencer Low sa.nLength = sizeof(sa); 1028dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sa.lpSecurityDescriptor = NULL; 1029dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sa.bInheritHandle = TRUE; 1030dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1031dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* create pipe, and ensure its read handle isn't inheritable */ 1032dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 ); 1033dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!ret) { 1034dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() ); 1035dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1036dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 10373bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes 1038dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 ); 1039dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1040dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ZeroMemory( &startup, sizeof(startup) ); 1041dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project startup.cb = sizeof(startup); 1042dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project startup.hStdInput = GetStdHandle( STD_INPUT_HANDLE ); 1043dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project startup.hStdOutput = pipe_write; 1044dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project startup.hStdError = GetStdHandle( STD_ERROR_HANDLE ); 1045dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project startup.dwFlags = STARTF_USESTDHANDLES; 1046dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 10473175c8e9bfcb01f181d7300755da15a999e5461cTom Marlin ZeroMemory( &pinfo, sizeof(pinfo) ); 1048dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1049dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* get path of current program */ 10508d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes GetModuleFileName( NULL, program_path, sizeof(program_path) ); 10518d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes 1052e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes ret = CreateProcess( 1053e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes program_path, /* program path */ 1054e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes "adb fork-server server", 1055dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* the fork-server argument will set the 10568d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes debug = 2 in the child */ 1057dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NULL, /* process handle is not inheritable */ 1058dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NULL, /* thread handle is not inheritable */ 1059dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRUE, /* yes, inherit some handles */ 1060dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DETACHED_PROCESS, /* the new process doesn't have a console */ 1061dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NULL, /* use parent's environment block */ 1062e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson NULL, /* use parent's starting directory */ 1063e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes &startup, /* startup info, i.e. std handles */ 1064e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes &pinfo ); 10657a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui 1066e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes CloseHandle( pipe_write ); 10677a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui 1068e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes if (!ret) { 1069e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() ); 1070e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes CloseHandle( pipe_read ); 1071dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1072dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 107390d4b739ab94fded63086de1261e70a3d39ceb1dDan Albert 10748d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes CloseHandle( pinfo.hProcess ); 10758d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes CloseHandle( pinfo.hThread ); 1076880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell 10774e2fd36bc8c16147cab323b0418a7666812d3bc7David Pursell /* wait for the "OK\n" message */ 1078880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell { 10798d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes char temp[3]; 1080880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell DWORD count; 1081880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell 1082880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell ret = ReadFile( pipe_read, temp, 3, &count, NULL ); 1083880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell CloseHandle( pipe_read ); 108474d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood if ( !ret ) { 108574d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() ); 10863d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes return -1; 10873d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes } 1088f4b9928563e97620fc1d9bd5c2efdaa0ded96488Yabin Cui if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { 10893d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes fprintf(stderr, "ADB server didn't ACK\n" ); 109074d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood return -1; 109174d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood } 10923d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes } 10933d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes#elif defined(HAVE_FORKEXEC) 10943d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes char path[PATH_MAX]; 10953d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes int fd[2]; 1096706955ff0d159d28bb6eb06dc10178624c505f4eDavid Pursell 10973d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes // set up a pipe so the child can tell us when it is ready. 10983d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child. 10993d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes if (pipe(fd)) { 11003d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno); 11013d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes return -1; 11023d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes } 11033d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes get_my_path(path, PATH_MAX); 11043d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes pid_t pid = fork(); 1105f4b9928563e97620fc1d9bd5c2efdaa0ded96488Yabin Cui if(pid < 0) return -1; 11063d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes 11072f38b699713dc2587a771bd5d4c6a47329728f5eMike Lockwood if (pid == 0) { 11082f38b699713dc2587a771bd5d4c6a47329728f5eMike Lockwood // child side of the fork 11098d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes 1110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // redirect stderr to the pipe 1111e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes // we use stderr instead of stdout due to stdout's buffering behavior. 1112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd[0]); 1113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd[1], STDERR_FILENO); 1114e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes adb_close(fd[1]); 1115e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes 11168d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes char str_port[30]; 11178d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes snprintf(str_port, sizeof(str_port), "%d", server_port); 11188d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes // child process 11198d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes int result = execl(path, "adb", "-P", str_port, "fork-server", "server", NULL); 11208d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes // this should not return 11218d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno); 11228d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes } else { 1123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // parent side of the fork 1124e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes 11258d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes char temp[3]; 11268d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes 11278d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C'; 11288d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes // wait for the "OK\n" message 11298d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes adb_close(fd[1]); 11308d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes int ret = adb_read(fd[0], temp, 3); 11318d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes int saved_errno = errno; 1132e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson adb_close(fd[0]); 1133e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes if (ret < 0) { 11348d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno); 11358d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes return -1; 11368d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes } 11378d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { 11388d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes fprintf(stderr, "ADB server didn't ACK\n" ); 11398d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes return -1; 11408d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes } 1141e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes 1142e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes setsid(); 11438d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes } 1144e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes#else 1145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#error "cannot implement background server start on this platform" 1146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 11501f4ec19e499ba981e4117f647d191603c2713e79Yabin Cui 11511f4ec19e499ba981e4117f647d191603c2713e79Yabin Cui/* Constructs a local name of form tcp:port. 11521f4ec19e499ba981e4117f647d191603c2713e79Yabin Cui * target_str points to the target string, it's content will be overwritten. 11531f4ec19e499ba981e4117f647d191603c2713e79Yabin Cui * target_size is the capacity of the target string. 11541f4ec19e499ba981e4117f647d191603c2713e79Yabin Cui * server_port is the port number to use for the local name. 11551f4ec19e499ba981e4117f647d191603c2713e79Yabin Cui */ 11561f4ec19e499ba981e4117f647d191603c2713e79Yabin Cuivoid build_local_name(char* target_str, size_t target_size, int server_port) 1157dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye{ 1158dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye snprintf(target_str, target_size, "tcp:%d", server_port); 11593bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes} 1160dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye 1161dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye#if !ADB_HOST 1162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int should_drop_privileges() { 1163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef ALLOW_ADBD_ROOT 1164 return 1; 1165#else /* ALLOW_ADBD_ROOT */ 1166 int secure = 0; 1167 char value[PROPERTY_VALUE_MAX]; 1168 1169 /* run adbd in secure mode if ro.secure is set and 1170 ** we are not in the emulator 1171 */ 1172 property_get("ro.kernel.qemu", value, ""); 1173 if (strcmp(value, "1") != 0) { 1174 property_get("ro.secure", value, "1"); 1175 if (strcmp(value, "1") == 0) { 1176 // don't run as root if ro.secure is set... 1177 secure = 1; 1178 1179 // ... except we allow running as root in userdebug builds if the 1180 // service.adb.root property has been set by the "adb root" command 1181 property_get("ro.debuggable", value, ""); 1182 if (strcmp(value, "1") == 0) { 1183 property_get("service.adb.root", value, ""); 1184 if (strcmp(value, "1") == 0) { 1185 secure = 0; 1186 } 1187 } 1188 } 1189 } 1190 return secure; 1191#endif /* ALLOW_ADBD_ROOT */ 1192} 1193#endif /* !ADB_HOST */ 1194 1195int adb_main(int is_daemon, int server_port) 1196{ 1197#if !ADB_HOST 1198 int port; 1199 char value[PROPERTY_VALUE_MAX]; 1200 1201 umask(000); 1202#endif 1203 1204 atexit(adb_cleanup); 1205#ifdef HAVE_WIN32_PROC 1206 SetConsoleCtrlHandler( ctrlc_handler, TRUE ); 1207#elif defined(HAVE_FORKEXEC) 1208 // No SIGCHLD. Let the service subproc handle its children. 1209 signal(SIGPIPE, SIG_IGN); 1210#endif 1211 1212 init_transport_registration(); 1213 1214#if ADB_HOST 1215 HOST = 1; 1216 1217#ifdef WORKAROUND_BUG6558362 1218 if(is_daemon) adb_set_affinity(); 1219#endif 1220 usb_vendors_init(); 1221 usb_init(); 1222 local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); 1223 adb_auth_init(); 1224 1225 char local_name[30]; 1226 build_local_name(local_name, sizeof(local_name), server_port); 1227 if(install_listener(local_name, "*smartsocket*", NULL, 0)) { 1228 exit(1); 1229 } 1230#else 1231 property_get("ro.adb.secure", value, "0"); 1232 auth_enabled = !strcmp(value, "1"); 1233 if (auth_enabled) 1234 adb_auth_init(); 1235 1236 // Our external storage path may be different than apps, since 1237 // we aren't able to bind mount after dropping root. 1238 const char* adb_external_storage = getenv("ADB_EXTERNAL_STORAGE"); 1239 if (NULL != adb_external_storage) { 1240 setenv("EXTERNAL_STORAGE", adb_external_storage, 1); 1241 } else { 1242 D("Warning: ADB_EXTERNAL_STORAGE is not set. Leaving EXTERNAL_STORAGE" 1243 " unchanged.\n"); 1244 } 1245 1246 /* don't listen on a port (default 5037) if running in secure mode */ 1247 /* don't run as root if we are running in secure mode */ 1248 if (should_drop_privileges()) { 1249 struct __user_cap_header_struct header; 1250 struct __user_cap_data_struct cap; 1251 1252 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) { 1253 exit(1); 1254 } 1255 1256 /* add extra groups: 1257 ** AID_ADB to access the USB driver 1258 ** AID_LOG to read system logs (adb logcat) 1259 ** AID_INPUT to diagnose input issues (getevent) 1260 ** AID_INET to diagnose network issues (netcfg, ping) 1261 ** AID_GRAPHICS to access the frame buffer 1262 ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump) 1263 ** AID_SDCARD_R to allow reading from the SD card 1264 ** AID_SDCARD_RW to allow writing to the SD card 1265 ** AID_MOUNT to allow unmounting the SD card before rebooting 1266 ** AID_NET_BW_STATS to read out qtaguid statistics 1267 */ 1268 gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS, 1269 AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW, 1270 AID_MOUNT, AID_NET_BW_STATS }; 1271 if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) { 1272 exit(1); 1273 } 1274 1275 /* then switch user and group to "shell" */ 1276 if (setgid(AID_SHELL) != 0) { 1277 exit(1); 1278 } 1279 if (setuid(AID_SHELL) != 0) { 1280 exit(1); 1281 } 1282 1283 /* set CAP_SYS_BOOT capability, so "adb reboot" will succeed */ 1284 header.version = _LINUX_CAPABILITY_VERSION; 1285 header.pid = 0; 1286 cap.effective = cap.permitted = (1 << CAP_SYS_BOOT); 1287 cap.inheritable = 0; 1288 capset(&header, &cap); 1289 1290 D("Local port disabled\n"); 1291 } else { 1292 char local_name[30]; 1293 build_local_name(local_name, sizeof(local_name), server_port); 1294 if(install_listener(local_name, "*smartsocket*", NULL, 0)) { 1295 exit(1); 1296 } 1297 } 1298 1299 int usb = 0; 1300 if (access(USB_ADB_PATH, F_OK) == 0 || access(USB_FFS_ADB_EP0, F_OK) == 0) { 1301 // listen on USB 1302 usb_init(); 1303 usb = 1; 1304 } 1305 1306 // If one of these properties is set, also listen on that port 1307 // If one of the properties isn't set and we couldn't listen on usb, 1308 // listen on the default port. 1309 property_get("service.adb.tcp.port", value, ""); 1310 if (!value[0]) { 1311 property_get("persist.adb.tcp.port", value, ""); 1312 } 1313 if (sscanf(value, "%d", &port) == 1 && port > 0) { 1314 printf("using port=%d\n", port); 1315 // listen on TCP port specified by service.adb.tcp.port property 1316 local_init(port); 1317 } else if (!usb) { 1318 // listen on default port 1319 local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); 1320 } 1321 1322 D("adb_main(): pre init_jdwp()\n"); 1323 init_jdwp(); 1324 D("adb_main(): post init_jdwp()\n"); 1325#endif 1326 1327 if (is_daemon) 1328 { 1329 // inform our parent that we are up and running. 1330#ifdef HAVE_WIN32_PROC 1331 DWORD count; 1332 WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), "OK\n", 3, &count, NULL ); 1333#elif defined(HAVE_FORKEXEC) 1334 fprintf(stderr, "OK\n"); 1335#endif 1336 start_logging(); 1337 } 1338 D("Event loop starting\n"); 1339 1340 fdevent_loop(); 1341 1342 usb_cleanup(); 1343 1344 return 0; 1345} 1346 1347#if ADB_HOST 1348void connect_device(char* host, char* buffer, int buffer_size) 1349{ 1350 int port, fd; 1351 char* portstr = strchr(host, ':'); 1352 char hostbuf[100]; 1353 char serial[100]; 1354 1355 strncpy(hostbuf, host, sizeof(hostbuf) - 1); 1356 if (portstr) { 1357 if (portstr - host >= (ptrdiff_t)sizeof(hostbuf)) { 1358 snprintf(buffer, buffer_size, "bad host name %s", host); 1359 return; 1360 } 1361 // zero terminate the host at the point we found the colon 1362 hostbuf[portstr - host] = 0; 1363 if (sscanf(portstr + 1, "%d", &port) == 0) { 1364 snprintf(buffer, buffer_size, "bad port number %s", portstr); 1365 return; 1366 } 1367 } else { 1368 port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; 1369 } 1370 1371 snprintf(serial, sizeof(serial), "%s:%d", hostbuf, port); 1372 if (find_transport(serial)) { 1373 snprintf(buffer, buffer_size, "already connected to %s", serial); 1374 return; 1375 } 1376 1377 fd = socket_network_client(hostbuf, port, SOCK_STREAM); 1378 if (fd < 0) { 1379 snprintf(buffer, buffer_size, "unable to connect to %s:%d", host, port); 1380 return; 1381 } 1382 1383 D("client: connected on remote on fd %d\n", fd); 1384 close_on_exec(fd); 1385 disable_tcp_nagle(fd); 1386 register_socket_transport(fd, serial, port, 0); 1387 snprintf(buffer, buffer_size, "connected to %s", serial); 1388} 1389 1390void connect_emulator(char* port_spec, char* buffer, int buffer_size) 1391{ 1392 char* port_separator = strchr(port_spec, ','); 1393 if (!port_separator) { 1394 snprintf(buffer, buffer_size, 1395 "unable to parse '%s' as <console port>,<adb port>", 1396 port_spec); 1397 return; 1398 } 1399 1400 // Zero-terminate console port and make port_separator point to 2nd port. 1401 *port_separator++ = 0; 1402 int console_port = strtol(port_spec, NULL, 0); 1403 int adb_port = strtol(port_separator, NULL, 0); 1404 if (!(console_port > 0 && adb_port > 0)) { 1405 *(port_separator - 1) = ','; 1406 snprintf(buffer, buffer_size, 1407 "Invalid port numbers: Expected positive numbers, got '%s'", 1408 port_spec); 1409 return; 1410 } 1411 1412 /* Check if the emulator is already known. 1413 * Note: There's a small but harmless race condition here: An emulator not 1414 * present just yet could be registered by another invocation right 1415 * after doing this check here. However, local_connect protects 1416 * against double-registration too. From here, a better error message 1417 * can be produced. In the case of the race condition, the very specific 1418 * error message won't be shown, but the data doesn't get corrupted. */ 1419 atransport* known_emulator = find_emulator_transport_by_adb_port(adb_port); 1420 if (known_emulator != NULL) { 1421 snprintf(buffer, buffer_size, 1422 "Emulator on port %d already registered.", adb_port); 1423 return; 1424 } 1425 1426 /* Check if more emulators can be registered. Similar unproblematic 1427 * race condition as above. */ 1428 int candidate_slot = get_available_local_transport_index(); 1429 if (candidate_slot < 0) { 1430 snprintf(buffer, buffer_size, "Cannot accept more emulators."); 1431 return; 1432 } 1433 1434 /* Preconditions met, try to connect to the emulator. */ 1435 if (!local_connect_arbitrary_ports(console_port, adb_port)) { 1436 snprintf(buffer, buffer_size, 1437 "Connected to emulator on ports %d,%d", console_port, adb_port); 1438 } else { 1439 snprintf(buffer, buffer_size, 1440 "Could not connect to emulator on ports %d,%d", 1441 console_port, adb_port); 1442 } 1443} 1444#endif 1445 1446int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s) 1447{ 1448 atransport *transport = NULL; 1449 char buf[4096]; 1450 1451 if(!strcmp(service, "kill")) { 1452 fprintf(stderr,"adb server killed by remote request\n"); 1453 fflush(stdout); 1454 adb_write(reply_fd, "OKAY", 4); 1455 usb_cleanup(); 1456 exit(0); 1457 } 1458 1459#if ADB_HOST 1460 // "transport:" is used for switching transport with a specified serial number 1461 // "transport-usb:" is used for switching transport to the only USB transport 1462 // "transport-local:" is used for switching transport to the only local transport 1463 // "transport-any:" is used for switching transport to the only transport 1464 if (!strncmp(service, "transport", strlen("transport"))) { 1465 char* error_string = "unknown failure"; 1466 transport_type type = kTransportAny; 1467 1468 if (!strncmp(service, "transport-usb", strlen("transport-usb"))) { 1469 type = kTransportUsb; 1470 } else if (!strncmp(service, "transport-local", strlen("transport-local"))) { 1471 type = kTransportLocal; 1472 } else if (!strncmp(service, "transport-any", strlen("transport-any"))) { 1473 type = kTransportAny; 1474 } else if (!strncmp(service, "transport:", strlen("transport:"))) { 1475 service += strlen("transport:"); 1476 serial = service; 1477 } 1478 1479 transport = acquire_one_transport(CS_ANY, type, serial, &error_string); 1480 1481 if (transport) { 1482 s->transport = transport; 1483 adb_write(reply_fd, "OKAY", 4); 1484 } else { 1485 sendfailmsg(reply_fd, error_string); 1486 } 1487 return 1; 1488 } 1489 1490 // return a list of all connected devices 1491 if (!strncmp(service, "devices", 7)) { 1492 char buffer[4096]; 1493 int use_long = !strcmp(service+7, "-l"); 1494 if (use_long || service[7] == 0) { 1495 memset(buf, 0, sizeof(buf)); 1496 memset(buffer, 0, sizeof(buffer)); 1497 D("Getting device list \n"); 1498 list_transports(buffer, sizeof(buffer), use_long); 1499 snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer); 1500 D("Wrote device list \n"); 1501 writex(reply_fd, buf, strlen(buf)); 1502 return 0; 1503 } 1504 } 1505 1506 // add a new TCP transport, device or emulator 1507 if (!strncmp(service, "connect:", 8)) { 1508 char buffer[4096]; 1509 char* host = service + 8; 1510 if (!strncmp(host, "emu:", 4)) { 1511 connect_emulator(host + 4, buffer, sizeof(buffer)); 1512 } else { 1513 connect_device(host, buffer, sizeof(buffer)); 1514 } 1515 // Send response for emulator and device 1516 snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer); 1517 writex(reply_fd, buf, strlen(buf)); 1518 return 0; 1519 } 1520 1521 // remove TCP transport 1522 if (!strncmp(service, "disconnect:", 11)) { 1523 char buffer[4096]; 1524 memset(buffer, 0, sizeof(buffer)); 1525 char* serial = service + 11; 1526 if (serial[0] == 0) { 1527 // disconnect from all TCP devices 1528 unregister_all_tcp_transports(); 1529 } else { 1530 char hostbuf[100]; 1531 // assume port 5555 if no port is specified 1532 if (!strchr(serial, ':')) { 1533 snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial); 1534 serial = hostbuf; 1535 } 1536 atransport *t = find_transport(serial); 1537 1538 if (t) { 1539 unregister_transport(t); 1540 } else { 1541 snprintf(buffer, sizeof(buffer), "No such device %s", serial); 1542 } 1543 } 1544 1545 snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer); 1546 writex(reply_fd, buf, strlen(buf)); 1547 return 0; 1548 } 1549 1550 // returns our value for ADB_SERVER_VERSION 1551 if (!strcmp(service, "version")) { 1552 char version[12]; 1553 snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION); 1554 snprintf(buf, sizeof buf, "OKAY%04x%s", (unsigned)strlen(version), version); 1555 writex(reply_fd, buf, strlen(buf)); 1556 return 0; 1557 } 1558 1559 if(!strncmp(service,"get-serialno",strlen("get-serialno"))) { 1560 char *out = "unknown"; 1561 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); 1562 if (transport && transport->serial) { 1563 out = transport->serial; 1564 } 1565 snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out); 1566 writex(reply_fd, buf, strlen(buf)); 1567 return 0; 1568 } 1569 if(!strncmp(service,"get-devpath",strlen("get-devpath"))) { 1570 char *out = "unknown"; 1571 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); 1572 if (transport && transport->devpath) { 1573 out = transport->devpath; 1574 } 1575 snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out); 1576 writex(reply_fd, buf, strlen(buf)); 1577 return 0; 1578 } 1579 // indicates a new emulator instance has started 1580 if (!strncmp(service,"emulator:",9)) { 1581 int port = atoi(service+9); 1582 local_connect(port); 1583 /* we don't even need to send a reply */ 1584 return 0; 1585 } 1586#endif // ADB_HOST 1587 1588 if(!strcmp(service,"list-forward")) { 1589 // Create the list of forward redirections. 1590 char header[9]; 1591 int buffer_size = format_listeners(NULL, 0); 1592 // Add one byte for the trailing zero. 1593 char* buffer = malloc(buffer_size+1); 1594 (void) format_listeners(buffer, buffer_size+1); 1595 snprintf(header, sizeof header, "OKAY%04x", buffer_size); 1596 writex(reply_fd, header, 8); 1597 writex(reply_fd, buffer, buffer_size); 1598 free(buffer); 1599 return 0; 1600 } 1601 1602 if (!strcmp(service,"killforward-all")) { 1603 remove_all_listeners(); 1604 adb_write(reply_fd, "OKAYOKAY", 8); 1605 return 0; 1606 } 1607 1608 if(!strncmp(service,"forward:",8) || 1609 !strncmp(service,"killforward:",12)) { 1610 char *local, *remote, *err; 1611 int r; 1612 atransport *transport; 1613 1614 int createForward = strncmp(service,"kill",4); 1615 int no_rebind = 0; 1616 1617 local = strchr(service, ':') + 1; 1618 1619 // Handle forward:norebind:<local>... here 1620 if (createForward && !strncmp(local, "norebind:", 9)) { 1621 no_rebind = 1; 1622 local = strchr(local, ':') + 1; 1623 } 1624 1625 remote = strchr(local,';'); 1626 1627 if (createForward) { 1628 // Check forward: parameter format: '<local>;<remote>' 1629 if(remote == 0) { 1630 sendfailmsg(reply_fd, "malformed forward spec"); 1631 return 0; 1632 } 1633 1634 *remote++ = 0; 1635 if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')){ 1636 sendfailmsg(reply_fd, "malformed forward spec"); 1637 return 0; 1638 } 1639 } else { 1640 // Check killforward: parameter format: '<local>' 1641 if (local[0] == 0) { 1642 sendfailmsg(reply_fd, "malformed forward spec"); 1643 return 0; 1644 } 1645 } 1646 1647 transport = acquire_one_transport(CS_ANY, ttype, serial, &err); 1648 if (!transport) { 1649 sendfailmsg(reply_fd, err); 1650 return 0; 1651 } 1652 1653 if (createForward) { 1654 r = install_listener(local, remote, transport, no_rebind); 1655 } else { 1656 r = remove_listener(local, transport); 1657 } 1658 if(r == 0) { 1659 /* 1st OKAY is connect, 2nd OKAY is status */ 1660 writex(reply_fd, "OKAYOKAY", 8); 1661 return 0; 1662 } 1663 1664 if (createForward) { 1665 const char* message; 1666 switch (r) { 1667 case INSTALL_STATUS_CANNOT_BIND: 1668 message = "cannot bind to socket"; 1669 break; 1670 case INSTALL_STATUS_CANNOT_REBIND: 1671 message = "cannot rebind existing socket"; 1672 break; 1673 default: 1674 message = "internal error"; 1675 } 1676 sendfailmsg(reply_fd, message); 1677 } else { 1678 sendfailmsg(reply_fd, "cannot remove listener"); 1679 } 1680 return 0; 1681 } 1682 1683 if(!strncmp(service,"get-state",strlen("get-state"))) { 1684 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); 1685 char *state = connection_state_name(transport); 1686 snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(state),state); 1687 writex(reply_fd, buf, strlen(buf)); 1688 return 0; 1689 } 1690 return -1; 1691} 1692 1693#if !ADB_HOST 1694int recovery_mode = 0; 1695#endif 1696 1697int main(int argc, char **argv) 1698{ 1699#if ADB_HOST 1700 adb_sysdeps_init(); 1701 adb_trace_init(); 1702 D("Handling commandline()\n"); 1703 return adb_commandline(argc - 1, argv + 1); 1704#else 1705 /* If adbd runs inside the emulator this will enable adb tracing via 1706 * adb-debug qemud service in the emulator. */ 1707 adb_qemu_trace_init(); 1708 if((argc > 1) && (!strcmp(argv[1],"recovery"))) { 1709 adb_device_banner = "recovery"; 1710 recovery_mode = 1; 1711 } 1712 1713 start_device_log(); 1714 D("Handling main()\n"); 1715 return adb_main(0, DEFAULT_ADB_PORT); 1716#endif 1717} 1718