├── Android.mk ├── MODULE_LICENSE_APACHE2 ├── NOTICE ├── OVERVIEW.TXT ├── SERVICES.TXT ├── adb.c ├── adb.h ├── adb_client.c ├── adb_client.h ├── backup_service.c ├── changes.diff ├── commandline.c ├── console.c ├── fdevent.c ├── fdevent.h ├── file_sync_client.c ├── file_sync_service.c ├── file_sync_service.h ├── framebuffer_service.c ├── get_my_path_darwin.c ├── get_my_path_freebsd.c ├── get_my_path_linux.c ├── get_my_path_windows.c ├── jdwp_service.c ├── log_service.c ├── mutex_list.h ├── protocol.txt ├── remount_service.c ├── services.c ├── sockets.c ├── sockets.dia ├── sysdeps.h ├── sysdeps_win32.c ├── test_track_devices.c ├── test_track_jdwp.c ├── transport.c ├── transport.h ├── transport_local.c ├── transport_usb.c ├── usb_libusb.c ├── usb_linux.c ├── usb_linux_client.c ├── usb_osx.c ├── usb_vendors.c ├── usb_vendors.h ├── usb_windows.c ├── utils.c └── utils.h /Android.mk: -------------------------------------------------------------------------------- 1 | # Copyright 2005 The Android Open Source Project 2 | # 3 | # Android.mk for adb 4 | # 5 | 6 | LOCAL_PATH:= $(call my-dir) 7 | # adbd device daemon 8 | # ========================================================= 9 | 10 | include $(CLEAR_VARS) 11 | 12 | LOCAL_SRC_FILES := \ 13 | adb.c \ 14 | backup_service.c \ 15 | fdevent.c \ 16 | transport.c \ 17 | transport_local.c \ 18 | transport_usb.c \ 19 | sockets.c \ 20 | services.c \ 21 | file_sync_service.c \ 22 | jdwp_service.c \ 23 | framebuffer_service.c \ 24 | remount_service.c \ 25 | usb_linux_client.c \ 26 | log_service.c \ 27 | utils.c 28 | 29 | LOCAL_CFLAGS := -g -DADB_HOST=0 -Wall -Wno-unused-parameter 30 | # adb can't be built without optimizations, so we enforce -O2 if no 31 | # other optimization flag is set - but we don't override what the global 32 | # flags are saying if something else is given (-Os or -O3 are useful) 33 | ifeq ($(findstring -O, $(TARGET_GLOBAL_CFLAGS)),) 34 | LOCAL_CFLAGS += -O2 35 | endif 36 | ifneq ($(findstring -O0, $(TARGET_GLOBAL_CFLAGS)),) 37 | LOCAL_CFLAGS += -O2 38 | endif 39 | LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE 40 | 41 | ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT))) 42 | LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1 43 | endif 44 | 45 | ifeq ($(BOARD_ALWAYS_INSECURE),true) 46 | LOCAL_CFLAGS += -DBOARD_ALWAYS_INSECURE 47 | endif 48 | 49 | LOCAL_MODULE := mrom_adbd 50 | 51 | LOCAL_FORCE_STATIC_EXECUTABLE := true 52 | LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) 53 | LOCAL_UNSTRIPPED_PATH := $(TARGET_OUT_EXECUTABLES_UNSTRIPPED) 54 | 55 | LOCAL_STATIC_LIBRARIES := libcutils libc liblog 56 | include $(BUILD_EXECUTABLE) 57 | -------------------------------------------------------------------------------- /MODULE_LICENSE_APACHE2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tasssadar/multirom_adbd/6db99f070766bc948e2b405cd52aa1e61ddd55bb/MODULE_LICENSE_APACHE2 -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2006-2009, The Android Open Source Project 3 | Copyright 2006, Brian Swetland 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | See the License for the specific language governing permissions and 12 | limitations under the License. 13 | 14 | 15 | Apache License 16 | Version 2.0, January 2004 17 | http://www.apache.org/licenses/ 18 | 19 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 20 | 21 | 1. Definitions. 22 | 23 | "License" shall mean the terms and conditions for use, reproduction, 24 | and distribution as defined by Sections 1 through 9 of this document. 25 | 26 | "Licensor" shall mean the copyright owner or entity authorized by 27 | the copyright owner that is granting the License. 28 | 29 | "Legal Entity" shall mean the union of the acting entity and all 30 | other entities that control, are controlled by, or are under common 31 | control with that entity. For the purposes of this definition, 32 | "control" means (i) the power, direct or indirect, to cause the 33 | direction or management of such entity, whether by contract or 34 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 35 | outstanding shares, or (iii) beneficial ownership of such entity. 36 | 37 | "You" (or "Your") shall mean an individual or Legal Entity 38 | exercising permissions granted by this License. 39 | 40 | "Source" form shall mean the preferred form for making modifications, 41 | including but not limited to software source code, documentation 42 | source, and configuration files. 43 | 44 | "Object" form shall mean any form resulting from mechanical 45 | transformation or translation of a Source form, including but 46 | not limited to compiled object code, generated documentation, 47 | and conversions to other media types. 48 | 49 | "Work" shall mean the work of authorship, whether in Source or 50 | Object form, made available under the License, as indicated by a 51 | copyright notice that is included in or attached to the work 52 | (an example is provided in the Appendix below). 53 | 54 | "Derivative Works" shall mean any work, whether in Source or Object 55 | form, that is based on (or derived from) the Work and for which the 56 | editorial revisions, annotations, elaborations, or other modifications 57 | represent, as a whole, an original work of authorship. For the purposes 58 | of this License, Derivative Works shall not include works that remain 59 | separable from, or merely link (or bind by name) to the interfaces of, 60 | the Work and Derivative Works thereof. 61 | 62 | "Contribution" shall mean any work of authorship, including 63 | the original version of the Work and any modifications or additions 64 | to that Work or Derivative Works thereof, that is intentionally 65 | submitted to Licensor for inclusion in the Work by the copyright owner 66 | or by an individual or Legal Entity authorized to submit on behalf of 67 | the copyright owner. For the purposes of this definition, "submitted" 68 | means any form of electronic, verbal, or written communication sent 69 | to the Licensor or its representatives, including but not limited to 70 | communication on electronic mailing lists, source code control systems, 71 | and issue tracking systems that are managed by, or on behalf of, the 72 | Licensor for the purpose of discussing and improving the Work, but 73 | excluding communication that is conspicuously marked or otherwise 74 | designated in writing by the copyright owner as "Not a Contribution." 75 | 76 | "Contributor" shall mean Licensor and any individual or Legal Entity 77 | on behalf of whom a Contribution has been received by Licensor and 78 | subsequently incorporated within the Work. 79 | 80 | 2. Grant of Copyright License. Subject to the terms and conditions of 81 | this License, each Contributor hereby grants to You a perpetual, 82 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 83 | copyright license to reproduce, prepare Derivative Works of, 84 | publicly display, publicly perform, sublicense, and distribute the 85 | Work and such Derivative Works in Source or Object form. 86 | 87 | 3. Grant of Patent License. Subject to the terms and conditions of 88 | this License, each Contributor hereby grants to You a perpetual, 89 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 90 | (except as stated in this section) patent license to make, have made, 91 | use, offer to sell, sell, import, and otherwise transfer the Work, 92 | where such license applies only to those patent claims licensable 93 | by such Contributor that are necessarily infringed by their 94 | Contribution(s) alone or by combination of their Contribution(s) 95 | with the Work to which such Contribution(s) was submitted. If You 96 | institute patent litigation against any entity (including a 97 | cross-claim or counterclaim in a lawsuit) alleging that the Work 98 | or a Contribution incorporated within the Work constitutes direct 99 | or contributory patent infringement, then any patent licenses 100 | granted to You under this License for that Work shall terminate 101 | as of the date such litigation is filed. 102 | 103 | 4. Redistribution. You may reproduce and distribute copies of the 104 | Work or Derivative Works thereof in any medium, with or without 105 | modifications, and in Source or Object form, provided that You 106 | meet the following conditions: 107 | 108 | (a) You must give any other recipients of the Work or 109 | Derivative Works a copy of this License; and 110 | 111 | (b) You must cause any modified files to carry prominent notices 112 | stating that You changed the files; and 113 | 114 | (c) You must retain, in the Source form of any Derivative Works 115 | that You distribute, all copyright, patent, trademark, and 116 | attribution notices from the Source form of the Work, 117 | excluding those notices that do not pertain to any part of 118 | the Derivative Works; and 119 | 120 | (d) If the Work includes a "NOTICE" text file as part of its 121 | distribution, then any Derivative Works that You distribute must 122 | include a readable copy of the attribution notices contained 123 | within such NOTICE file, excluding those notices that do not 124 | pertain to any part of the Derivative Works, in at least one 125 | of the following places: within a NOTICE text file distributed 126 | as part of the Derivative Works; within the Source form or 127 | documentation, if provided along with the Derivative Works; or, 128 | within a display generated by the Derivative Works, if and 129 | wherever such third-party notices normally appear. The contents 130 | of the NOTICE file are for informational purposes only and 131 | do not modify the License. You may add Your own attribution 132 | notices within Derivative Works that You distribute, alongside 133 | or as an addendum to the NOTICE text from the Work, provided 134 | that such additional attribution notices cannot be construed 135 | as modifying the License. 136 | 137 | You may add Your own copyright statement to Your modifications and 138 | may provide additional or different license terms and conditions 139 | for use, reproduction, or distribution of Your modifications, or 140 | for any such Derivative Works as a whole, provided Your use, 141 | reproduction, and distribution of the Work otherwise complies with 142 | the conditions stated in this License. 143 | 144 | 5. Submission of Contributions. Unless You explicitly state otherwise, 145 | any Contribution intentionally submitted for inclusion in the Work 146 | by You to the Licensor shall be under the terms and conditions of 147 | this License, without any additional terms or conditions. 148 | Notwithstanding the above, nothing herein shall supersede or modify 149 | the terms of any separate license agreement you may have executed 150 | with Licensor regarding such Contributions. 151 | 152 | 6. Trademarks. This License does not grant permission to use the trade 153 | names, trademarks, service marks, or product names of the Licensor, 154 | except as required for reasonable and customary use in describing the 155 | origin of the Work and reproducing the content of the NOTICE file. 156 | 157 | 7. Disclaimer of Warranty. Unless required by applicable law or 158 | agreed to in writing, Licensor provides the Work (and each 159 | Contributor provides its Contributions) on an "AS IS" BASIS, 160 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 161 | implied, including, without limitation, any warranties or conditions 162 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 163 | PARTICULAR PURPOSE. You are solely responsible for determining the 164 | appropriateness of using or redistributing the Work and assume any 165 | risks associated with Your exercise of permissions under this License. 166 | 167 | 8. Limitation of Liability. In no event and under no legal theory, 168 | whether in tort (including negligence), contract, or otherwise, 169 | unless required by applicable law (such as deliberate and grossly 170 | negligent acts) or agreed to in writing, shall any Contributor be 171 | liable to You for damages, including any direct, indirect, special, 172 | incidental, or consequential damages of any character arising as a 173 | result of this License or out of the use or inability to use the 174 | Work (including but not limited to damages for loss of goodwill, 175 | work stoppage, computer failure or malfunction, or any and all 176 | other commercial damages or losses), even if such Contributor 177 | has been advised of the possibility of such damages. 178 | 179 | 9. Accepting Warranty or Additional Liability. While redistributing 180 | the Work or Derivative Works thereof, You may choose to offer, 181 | and charge a fee for, acceptance of support, warranty, indemnity, 182 | or other liability obligations and/or rights consistent with this 183 | License. However, in accepting such obligations, You may act only 184 | on Your own behalf and on Your sole responsibility, not on behalf 185 | of any other Contributor, and only if You agree to indemnify, 186 | defend, and hold each Contributor harmless for any liability 187 | incurred by, or claims asserted against, such Contributor by reason 188 | of your accepting any such warranty or additional liability. 189 | 190 | END OF TERMS AND CONDITIONS 191 | 192 | -------------------------------------------------------------------------------- /OVERVIEW.TXT: -------------------------------------------------------------------------------- 1 | Implementation notes regarding ADB. 2 | 3 | I. General Overview: 4 | 5 | The Android Debug Bridge (ADB) is used to: 6 | 7 | - keep track of all Android devices and emulators instances 8 | connected to or running on a given host developer machine 9 | 10 | - implement various control commands (e.g. "adb shell", "adb pull", etc..) 11 | for the benefit of clients (command-line users, or helper programs like 12 | DDMS). These commands are what is called a 'service' in ADB. 13 | 14 | As a whole, everything works through the following components: 15 | 16 | 1. The ADB server 17 | 18 | This is a background process that runs on the host machine. Its purpose 19 | if to sense the USB ports to know when devices are attached/removed, 20 | as well as when emulator instances start/stop. 21 | 22 | It thus maintains a list of "connected devices" and assigns a 'state' 23 | to each one of them: OFFLINE, BOOTLOADER, RECOVERY or ONLINE (more on 24 | this below). 25 | 26 | The ADB server is really one giant multiplexing loop whose purpose is 27 | to orchestrate the exchange of data (packets, really) between clients, 28 | services and devices. 29 | 30 | 31 | 2. The ADB daemon (adbd) 32 | 33 | The 'adbd' program runs as a background process within an Android device 34 | or emulated system. Its purpose is to connect to the ADB server 35 | (through USB for devices, through TCP for emulators) and provide a 36 | few services for clients that run on the host. 37 | 38 | The ADB server considers that a device is ONLINE when it has successfully 39 | connected to the adbd program within it. Otherwise, the device is OFFLINE, 40 | meaning that the ADB server detected a new device/emulator, but could not 41 | connect to the adbd daemon. 42 | 43 | the BOOTLOADER and RECOVERY states correspond to alternate states of 44 | devices when they are in the bootloader or recovery mode. 45 | 46 | 3. The ADB command-line client 47 | 48 | The 'adb' command-line program is used to run adb commands from a shell 49 | or a script. It first tries to locate the ADB server on the host machine, 50 | and will start one automatically if none is found. 51 | 52 | then, the client sends its service requests to the ADB server. It doesn't 53 | need to know. 54 | 55 | Currently, a single 'adb' binary is used for both the server and client. 56 | this makes distribution and starting the server easier. 57 | 58 | 59 | 4. Services 60 | 61 | There are essentially two kinds of services that a client can talk to. 62 | 63 | Host Services: 64 | these services run within the ADB Server and thus do not need to 65 | communicate with a device at all. A typical example is "adb devices" 66 | which is used to return the list of currently known devices and their 67 | state. They are a few couple other services though. 68 | 69 | Local Services: 70 | these services either run within the adbd daemon, or are started by 71 | it on the device. The ADB server is used to multiplex streams 72 | between the client and the service running in adbd. In this case 73 | its role is to initiate the connection, then of being a pass-through 74 | for the data. 75 | 76 | 77 | II. Protocol details: 78 | 79 | 1. Client <-> Server protocol: 80 | 81 | This details the protocol used between ADB clients and the ADB 82 | server itself. The ADB server listens on TCP:localhost:5037. 83 | 84 | A client sends a request using the following format: 85 | 86 | 1. A 4-byte hexadecimal string giving the length of the payload 87 | 2. Followed by the payload itself. 88 | 89 | For example, to query the ADB server for its internal version number, 90 | the client will do the following: 91 | 92 | 1. Connect to tcp:localhost:5037 93 | 2. Send the string "000Chost:version" to the corresponding socket 94 | 95 | The 'host:' prefix is used to indicate that the request is addressed 96 | to the server itself (we will talk about other kinds of requests later). 97 | The content length is encoded in ASCII for easier debugging. 98 | 99 | The server should answer a request with one of the following: 100 | 101 | 1. For success, the 4-byte "OKAY" string 102 | 103 | 2. For failure, the 4-byte "FAIL" string, followed by a 104 | 4-byte hex length, followed by a string giving the reason 105 | for failure. 106 | 107 | 3. As a special exception, for 'host:version', a 4-byte 108 | hex string corresponding to the server's internal version number 109 | 110 | Note that the connection is still alive after an OKAY, which allows the 111 | client to make other requests. But in certain cases, an OKAY will even 112 | change the state of the connection. 113 | 114 | For example, the case of the 'host:transport:' request, 115 | where '' is used to identify a given device/emulator; after 116 | the "OKAY" answer, all further requests made by the client will go 117 | directly to the corresponding adbd daemon. 118 | 119 | The file SERVICES.TXT lists all services currently implemented by ADB. 120 | 121 | 122 | 2. Transports: 123 | 124 | An ADB transport models a connection between the ADB server and one device 125 | or emulator. There are currently two kinds of transports: 126 | 127 | - USB transports, for physical devices through USB 128 | 129 | - Local transports, for emulators running on the host, connected to 130 | the server through TCP 131 | 132 | In theory, it should be possible to write a local transport that proxies 133 | a connection between an ADB server and a device/emulator connected to/ 134 | running on another machine. This hasn't been done yet though. 135 | 136 | Each transport can carry one or more multiplexed streams between clients 137 | and the device/emulator they point to. The ADB server must handle 138 | unexpected transport disconnections (e.g. when a device is physically 139 | unplugged) properly. 140 | -------------------------------------------------------------------------------- /SERVICES.TXT: -------------------------------------------------------------------------------- 1 | This file tries to document all requests a client can make 2 | to the ADB server of an adbd daemon. See the OVERVIEW.TXT document 3 | to understand what's going on here. 4 | 5 | HOST SERVICES: 6 | 7 | host:version 8 | Ask the ADB server for its internal version number. 9 | 10 | As a special exception, the server will respond with a 4-byte 11 | hex string corresponding to its internal version number, without 12 | any OKAY or FAIL. 13 | 14 | host:kill 15 | Ask the ADB server to quit immediately. This is used when the 16 | ADB client detects that an obsolete server is running after an 17 | upgrade. 18 | 19 | host:devices 20 | Ask to return the list of available Android devices and their 21 | state. After the OKAY, this is followed by a 4-byte hex len, 22 | and a string that will be dumped as-is by the client, then 23 | the connection is closed 24 | 25 | host:track-devices 26 | This is a variant of host:devices which doesn't close the 27 | connection. Instead, a new device list description is sent 28 | each time a device is added/removed or the state of a given 29 | device changes (hex4 + content). This allows tools like DDMS 30 | to track the state of connected devices in real-time without 31 | polling the server repeatedly. 32 | 33 | host:emulator: 34 | This is a special query that is sent to the ADB server when a 35 | new emulator starts up. is a decimal number corresponding 36 | to the emulator's ADB control port, i.e. the TCP port that the 37 | emulator will forward automatically to the adbd daemon running 38 | in the emulator system. 39 | 40 | This mechanism allows the ADB server to know when new emulator 41 | instances start. 42 | 43 | host:transport: 44 | Ask to switch the connection to the device/emulator identified by 45 | . After the OKAY response, every client request will 46 | be sent directly to the adbd daemon running on the device. 47 | (Used to implement the -s option) 48 | 49 | host:transport-usb 50 | Ask to switch the connection to one device connected through USB 51 | to the host machine. This will fail if there are more than one such 52 | devices. (Used to implement the -d convenience option) 53 | 54 | host:transport-local 55 | Ask to switch the connection to one emulator connected through TCP. 56 | This will fail if there is more than one such emulator instance 57 | running. (Used to implement the -e convenience option) 58 | 59 | host:transport-any 60 | Another host:transport variant. Ask to switch the connection to 61 | either the device or emulator connect to/running on the host. 62 | Will fail if there is more than one such device/emulator available. 63 | (Used when neither -s, -d or -e are provided) 64 | 65 | host-serial:: 66 | This is a special form of query, where the 'host-serial::' 67 | prefix can be used to indicate that the client is asking the ADB server 68 | for information related to a specific device. can be in one 69 | of the format described below. 70 | 71 | host-usb: 72 | A variant of host-serial used to target the single USB device connected 73 | to the host. This will fail if there is none or more than one. 74 | 75 | host-local: 76 | A variant of host-serial used to target the single emulator instance 77 | running on the host. This will fail if there is none or more than one. 78 | 79 | host: 80 | When asking for information related to a device, 'host:' can also be 81 | interpreted as 'any single device or emulator connected to/running on 82 | the host'. 83 | 84 | :get-product 85 | XXX 86 | 87 | :get-serialno 88 | Returns the serial number of the corresponding device/emulator. 89 | Note that emulator serial numbers are of the form "emulator-5554" 90 | 91 | :get-state 92 | Returns the state of a given device as a string. 93 | 94 | :forward:; 95 | Asks the ADB server to forward local connections from 96 | to the address on a given device. 97 | 98 | There, can be one of the 99 | host-serial/host-usb/host-local/host prefixes as described previously 100 | and indicates which device/emulator to target. 101 | 102 | the format of is one of: 103 | 104 | tcp: -> TCP connection on localhost: 105 | local: -> Unix local domain socket on 106 | 107 | the format of is one of: 108 | 109 | tcp: -> TCP localhost: on device 110 | local: -> Unix local domain socket on device 111 | jdwp: -> JDWP thread on VM process 112 | 113 | or even any one of the local services described below. 114 | 115 | 116 | 117 | LOCAL SERVICES: 118 | 119 | All the queries below assumed that you already switched the transport 120 | to a real device, or that you have used a query prefix as described 121 | above. 122 | 123 | shell:command arg1 arg2 ... 124 | Run 'command arg1 arg2 ...' in a shell on the device, and return 125 | its output and error streams. Note that arguments must be separated 126 | by spaces. If an argument contains a space, it must be quoted with 127 | double-quotes. Arguments cannot contain double quotes or things 128 | will go very wrong. 129 | 130 | Note that this is the non-interactive version of "adb shell" 131 | 132 | shell: 133 | Start an interactive shell session on the device. Redirect 134 | stdin/stdout/stderr as appropriate. Note that the ADB server uses 135 | this to implement "adb shell", but will also cook the input before 136 | sending it to the device (see interactive_shell() in commandline.c) 137 | 138 | remount: 139 | Ask adbd to remount the device's filesystem in read-write mode, 140 | instead of read-only. This is usually necessary before performing 141 | an "adb sync" or "adb push" request. 142 | 143 | This request may not succeed on certain builds which do not allow 144 | that. 145 | 146 | dev: 147 | Opens a device file and connects the client directly to it for 148 | read/write purposes. Useful for debugging, but may require special 149 | privileges and thus may not run on all devices. is a full 150 | path from the root of the filesystem. 151 | 152 | tcp: 153 | Tries to connect to tcp port on localhost. 154 | 155 | tcp:: 156 | Tries to connect to tcp port on machine from 157 | the device. This can be useful to debug some networking/proxy 158 | issues that can only be revealed on the device itself. 159 | 160 | local: 161 | Tries to connect to a Unix domain socket on the device 162 | 163 | localreserved: 164 | localabstract: 165 | localfilesystem: 166 | Variants of local: that are used to access other Android 167 | socket namespaces. 168 | 169 | log: 170 | Opens one of the system logs (/dev/log/) and allows the client 171 | to read them directly. Used to implement 'adb logcat'. The stream 172 | will be read-only for the client. 173 | 174 | framebuffer: 175 | This service is used to send snapshots of the framebuffer to a client. 176 | It requires sufficient privileges but works as follow: 177 | 178 | After the OKAY, the service sends 16-byte binary structure 179 | containing the following fields (little-endian format): 180 | 181 | depth: uint32_t: framebuffer depth 182 | size: uint32_t: framebuffer size in bytes 183 | width: uint32_t: framebuffer width in pixels 184 | height: uint32_t: framebuffer height in pixels 185 | 186 | With the current implementation, depth is always 16, and 187 | size is always width*height*2 188 | 189 | Then, each time the client wants a snapshot, it should send 190 | one byte through the channel, which will trigger the service 191 | to send it 'size' bytes of framebuffer data. 192 | 193 | If the adbd daemon doesn't have sufficient privileges to open 194 | the framebuffer device, the connection is simply closed immediately. 195 | 196 | dns: 197 | This service is an exception because it only runs within the ADB server. 198 | It is used to implement USB networking, i.e. to provide a network connection 199 | to the device through the host machine (note: this is the exact opposite of 200 | network tethering). 201 | 202 | It is used to perform a gethostbyname(
) on the host and return 203 | the corresponding IP address as a 4-byte string. 204 | 205 | recover: 206 | This service is used to upload a recovery image to the device. 207 | must be a number corresponding to the size of the file. The service works 208 | by: 209 | 210 | - creating a file named /tmp/update 211 | - reading 'size' bytes from the client and writing them to /tmp/update 212 | - when everything is read successfully, create a file named /tmp/update.start 213 | 214 | This service can only work when the device is in recovery mode. Otherwise, 215 | the /tmp directory doesn't exist and the connection will be closed immediately. 216 | 217 | jdwp: 218 | Connects to the JDWP thread running in the VM of process . 219 | 220 | track-jdwp 221 | This is used to send the list of JDWP pids periodically to the client. 222 | The format of the returned data is the following: 223 | 224 | : the length of all content as a 4-char hexadecimal string 225 | : a series of ASCII lines of the following format: 226 | "\n" 227 | 228 | This service is used by DDMS to know which debuggable processes are running 229 | on the device/emulator. 230 | 231 | Note that there is no single-shot service to retrieve the list only once. 232 | 233 | sync: 234 | This starts the file synchronisation service, used to implement "adb push" 235 | and "adb pull". Since this service is pretty complex, it will be detailed 236 | in a companion document named SYNC.TXT 237 | -------------------------------------------------------------------------------- /adb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __ADB_H 18 | #define __ADB_H 19 | 20 | #include 21 | 22 | #include "transport.h" /* readx(), writex() */ 23 | 24 | #define MAX_PAYLOAD 4096 25 | 26 | #define A_SYNC 0x434e5953 27 | #define A_CNXN 0x4e584e43 28 | #define A_OPEN 0x4e45504f 29 | #define A_OKAY 0x59414b4f 30 | #define A_CLSE 0x45534c43 31 | #define A_WRTE 0x45545257 32 | 33 | #define A_VERSION 0x01000000 // ADB protocol version 34 | 35 | #define ADB_VERSION_MAJOR 1 // Used for help/version information 36 | #define ADB_VERSION_MINOR 0 // Used for help/version information 37 | 38 | #define ADB_SERVER_VERSION 29 // Increment this when we want to force users to start a new adb server 39 | 40 | typedef struct amessage amessage; 41 | typedef struct apacket apacket; 42 | typedef struct asocket asocket; 43 | typedef struct alistener alistener; 44 | typedef struct aservice aservice; 45 | typedef struct atransport atransport; 46 | typedef struct adisconnect adisconnect; 47 | typedef struct usb_handle usb_handle; 48 | 49 | struct amessage { 50 | unsigned command; /* command identifier constant */ 51 | unsigned arg0; /* first argument */ 52 | unsigned arg1; /* second argument */ 53 | unsigned data_length; /* length of payload (0 is allowed) */ 54 | unsigned data_check; /* checksum of data payload */ 55 | unsigned magic; /* command ^ 0xffffffff */ 56 | }; 57 | 58 | struct apacket 59 | { 60 | apacket *next; 61 | 62 | unsigned len; 63 | unsigned char *ptr; 64 | 65 | amessage msg; 66 | unsigned char data[MAX_PAYLOAD]; 67 | }; 68 | 69 | /* An asocket represents one half of a connection between a local and 70 | ** remote entity. A local asocket is bound to a file descriptor. A 71 | ** remote asocket is bound to the protocol engine. 72 | */ 73 | struct asocket { 74 | /* chain pointers for the local/remote list of 75 | ** asockets that this asocket lives in 76 | */ 77 | asocket *next; 78 | asocket *prev; 79 | 80 | /* the unique identifier for this asocket 81 | */ 82 | unsigned id; 83 | 84 | /* flag: set when the socket's peer has closed 85 | ** but packets are still queued for delivery 86 | */ 87 | int closing; 88 | 89 | /* flag: quit adbd when both ends close the 90 | ** local service socket 91 | */ 92 | int exit_on_close; 93 | 94 | /* the asocket we are connected to 95 | */ 96 | 97 | asocket *peer; 98 | 99 | /* For local asockets, the fde is used to bind 100 | ** us to our fd event system. For remote asockets 101 | ** these fields are not used. 102 | */ 103 | fdevent fde; 104 | int fd; 105 | 106 | /* queue of apackets waiting to be written 107 | */ 108 | apacket *pkt_first; 109 | apacket *pkt_last; 110 | 111 | /* enqueue is called by our peer when it has data 112 | ** for us. It should return 0 if we can accept more 113 | ** data or 1 if not. If we return 1, we must call 114 | ** peer->ready() when we once again are ready to 115 | ** receive data. 116 | */ 117 | int (*enqueue)(asocket *s, apacket *pkt); 118 | 119 | /* ready is called by the peer when it is ready for 120 | ** us to send data via enqueue again 121 | */ 122 | void (*ready)(asocket *s); 123 | 124 | /* close is called by the peer when it has gone away. 125 | ** we are not allowed to make any further calls on the 126 | ** peer once our close method is called. 127 | */ 128 | void (*close)(asocket *s); 129 | 130 | /* socket-type-specific extradata */ 131 | void *extra; 132 | 133 | /* A socket is bound to atransport */ 134 | atransport *transport; 135 | }; 136 | 137 | 138 | /* the adisconnect structure is used to record a callback that 139 | ** will be called whenever a transport is disconnected (e.g. by the user) 140 | ** this should be used to cleanup objects that depend on the 141 | ** transport (e.g. remote sockets, listeners, etc...) 142 | */ 143 | struct adisconnect 144 | { 145 | void (*func)(void* opaque, atransport* t); 146 | void* opaque; 147 | adisconnect* next; 148 | adisconnect* prev; 149 | }; 150 | 151 | 152 | /* a transport object models the connection to a remote device or emulator 153 | ** there is one transport per connected device/emulator. a "local transport" 154 | ** connects through TCP (for the emulator), while a "usb transport" through 155 | ** USB (for real devices) 156 | ** 157 | ** note that kTransportHost doesn't really correspond to a real transport 158 | ** object, it's a special value used to indicate that a client wants to 159 | ** connect to a service implemented within the ADB server itself. 160 | */ 161 | typedef enum transport_type { 162 | kTransportUsb, 163 | kTransportLocal, 164 | kTransportAny, 165 | kTransportHost, 166 | } transport_type; 167 | 168 | struct atransport 169 | { 170 | atransport *next; 171 | atransport *prev; 172 | 173 | int (*read_from_remote)(apacket *p, atransport *t); 174 | int (*write_to_remote)(apacket *p, atransport *t); 175 | void (*close)(atransport *t); 176 | void (*kick)(atransport *t); 177 | 178 | int fd; 179 | int transport_socket; 180 | fdevent transport_fde; 181 | int ref_count; 182 | unsigned sync_token; 183 | int connection_state; 184 | transport_type type; 185 | 186 | /* usb handle or socket fd as needed */ 187 | usb_handle *usb; 188 | int sfd; 189 | 190 | /* used to identify transports for clients */ 191 | char *serial; 192 | char *product; 193 | int adb_port; // Use for emulators (local transport) 194 | 195 | /* a list of adisconnect callbacks called when the transport is kicked */ 196 | int kicked; 197 | adisconnect disconnects; 198 | }; 199 | 200 | 201 | /* A listener is an entity which binds to a local port 202 | ** and, upon receiving a connection on that port, creates 203 | ** an asocket to connect the new local connection to a 204 | ** specific remote service. 205 | ** 206 | ** TODO: some listeners read from the new connection to 207 | ** determine what exact service to connect to on the far 208 | ** side. 209 | */ 210 | struct alistener 211 | { 212 | alistener *next; 213 | alistener *prev; 214 | 215 | fdevent fde; 216 | int fd; 217 | 218 | const char *local_name; 219 | const char *connect_to; 220 | atransport *transport; 221 | adisconnect disconnect; 222 | }; 223 | 224 | 225 | void print_packet(const char *label, apacket *p); 226 | 227 | asocket *find_local_socket(unsigned id); 228 | void install_local_socket(asocket *s); 229 | void remove_socket(asocket *s); 230 | void close_all_sockets(atransport *t); 231 | 232 | #define LOCAL_CLIENT_PREFIX "emulator-" 233 | 234 | asocket *create_local_socket(int fd); 235 | asocket *create_local_service_socket(const char *destination); 236 | 237 | asocket *create_remote_socket(unsigned id, atransport *t); 238 | void connect_to_remote(asocket *s, const char *destination); 239 | void connect_to_smartsocket(asocket *s); 240 | 241 | void fatal(const char *fmt, ...); 242 | void fatal_errno(const char *fmt, ...); 243 | 244 | void handle_packet(apacket *p, atransport *t); 245 | void send_packet(apacket *p, atransport *t); 246 | 247 | void get_my_path(char *s, size_t maxLen); 248 | int launch_server(int server_port); 249 | int adb_main(int is_daemon, int server_port); 250 | 251 | 252 | /* transports are ref-counted 253 | ** get_device_transport does an acquire on your behalf before returning 254 | */ 255 | void init_transport_registration(void); 256 | int list_transports(char *buf, size_t bufsize); 257 | void update_transports(void); 258 | 259 | asocket* create_device_tracker(void); 260 | 261 | /* Obtain a transport from the available transports. 262 | ** If state is != CS_ANY, only transports in that state are considered. 263 | ** If serial is non-NULL then only the device with that serial will be chosen. 264 | ** If no suitable transport is found, error is set. 265 | */ 266 | atransport *acquire_one_transport(int state, transport_type ttype, const char* serial, char **error_out); 267 | void add_transport_disconnect( atransport* t, adisconnect* dis ); 268 | void remove_transport_disconnect( atransport* t, adisconnect* dis ); 269 | void run_transport_disconnects( atransport* t ); 270 | void kick_transport( atransport* t ); 271 | 272 | /* initialize a transport object's func pointers and state */ 273 | #if ADB_HOST 274 | int get_available_local_transport_index(); 275 | #endif 276 | int init_socket_transport(atransport *t, int s, int port, int local); 277 | void init_usb_transport(atransport *t, usb_handle *usb, int state); 278 | 279 | /* for MacOS X cleanup */ 280 | void close_usb_devices(); 281 | 282 | /* cause new transports to be init'd and added to the list */ 283 | void register_socket_transport(int s, const char *serial, int port, int local); 284 | 285 | /* these should only be used for the "adb disconnect" command */ 286 | void unregister_transport(atransport *t); 287 | void unregister_all_tcp_transports(); 288 | 289 | void register_usb_transport(usb_handle *h, const char *serial, unsigned writeable); 290 | 291 | /* this should only be used for transports with connection_state == CS_NOPERM */ 292 | void unregister_usb_transport(usb_handle *usb); 293 | 294 | atransport *find_transport(const char *serial); 295 | #if ADB_HOST 296 | atransport* find_emulator_transport_by_adb_port(int adb_port); 297 | #endif 298 | 299 | int service_to_fd(const char *name); 300 | #if ADB_HOST 301 | asocket *host_service_to_socket(const char* name, const char *serial); 302 | #endif 303 | 304 | #if !ADB_HOST 305 | int init_jdwp(void); 306 | asocket* create_jdwp_service_socket(); 307 | asocket* create_jdwp_tracker_service_socket(); 308 | int create_jdwp_connection_fd(int jdwp_pid); 309 | #endif 310 | 311 | #if !ADB_HOST 312 | typedef enum { 313 | BACKUP, 314 | RESTORE 315 | } BackupOperation; 316 | int backup_service(BackupOperation operation, char* args); 317 | void framebuffer_service(int fd, void *cookie); 318 | void log_service(int fd, void *cookie); 319 | void remount_service(int fd, void *cookie); 320 | char * get_log_file_path(const char * log_name); 321 | #endif 322 | 323 | /* packet allocator */ 324 | apacket *get_apacket(void); 325 | void put_apacket(apacket *p); 326 | 327 | int check_header(apacket *p); 328 | int check_data(apacket *p); 329 | 330 | /* define ADB_TRACE to 1 to enable tracing support, or 0 to disable it */ 331 | 332 | #define ADB_TRACE 1 333 | 334 | /* IMPORTANT: if you change the following list, don't 335 | * forget to update the corresponding 'tags' table in 336 | * the adb_trace_init() function implemented in adb.c 337 | */ 338 | typedef enum { 339 | TRACE_ADB = 0, /* 0x001 */ 340 | TRACE_SOCKETS, 341 | TRACE_PACKETS, 342 | TRACE_TRANSPORT, 343 | TRACE_RWX, /* 0x010 */ 344 | TRACE_USB, 345 | TRACE_SYNC, 346 | TRACE_SYSDEPS, 347 | TRACE_JDWP, /* 0x100 */ 348 | TRACE_SERVICES, 349 | } AdbTrace; 350 | 351 | #if ADB_TRACE 352 | 353 | #if !ADB_HOST 354 | /* 355 | * When running inside the emulator, guest's adbd can connect to 'adb-debug' 356 | * qemud service that can display adb trace messages (on condition that emulator 357 | * has been started with '-debug adb' option). 358 | */ 359 | 360 | /* Delivers a trace message to the emulator via QEMU pipe. */ 361 | void adb_qemu_trace(const char* fmt, ...); 362 | /* Macro to use to send ADB trace messages to the emulator. */ 363 | #define DQ(...) adb_qemu_trace(__VA_ARGS__) 364 | #else 365 | #define DQ(...) ((void)0) 366 | #endif /* !ADB_HOST */ 367 | 368 | extern int adb_trace_mask; 369 | extern unsigned char adb_trace_output_count; 370 | void adb_trace_init(void); 371 | 372 | # define ADB_TRACING ((adb_trace_mask & (1 << TRACE_TAG)) != 0) 373 | 374 | /* you must define TRACE_TAG before using this macro */ 375 | # define D(...) \ 376 | do { \ 377 | if (ADB_TRACING) { \ 378 | int save_errno = errno; \ 379 | adb_mutex_lock(&D_lock); \ 380 | fprintf(stderr, "%s::%s():", \ 381 | __FILE__, __FUNCTION__); \ 382 | errno = save_errno; \ 383 | fprintf(stderr, __VA_ARGS__ ); \ 384 | fflush(stderr); \ 385 | adb_mutex_unlock(&D_lock); \ 386 | errno = save_errno; \ 387 | } \ 388 | } while (0) 389 | # define DR(...) \ 390 | do { \ 391 | if (ADB_TRACING) { \ 392 | int save_errno = errno; \ 393 | adb_mutex_lock(&D_lock); \ 394 | errno = save_errno; \ 395 | fprintf(stderr, __VA_ARGS__ ); \ 396 | fflush(stderr); \ 397 | adb_mutex_unlock(&D_lock); \ 398 | errno = save_errno; \ 399 | } \ 400 | } while (0) 401 | #else 402 | # define D(...) ((void)0) 403 | # define DR(...) ((void)0) 404 | # define ADB_TRACING 0 405 | #endif 406 | 407 | 408 | #if !TRACE_PACKETS 409 | #define print_packet(tag,p) do {} while (0) 410 | #endif 411 | 412 | #if ADB_HOST_ON_TARGET 413 | /* adb and adbd are coexisting on the target, so use 5038 for adb 414 | * to avoid conflicting with adbd's usage of 5037 415 | */ 416 | # define DEFAULT_ADB_PORT 5038 417 | #else 418 | # define DEFAULT_ADB_PORT 5037 419 | #endif 420 | 421 | #define DEFAULT_ADB_LOCAL_TRANSPORT_PORT 5555 422 | 423 | #define ADB_CLASS 0xff 424 | #define ADB_SUBCLASS 0x42 425 | #define ADB_PROTOCOL 0x1 426 | 427 | 428 | void local_init(int port); 429 | int local_connect(int port); 430 | int local_connect_arbitrary_ports(int console_port, int adb_port); 431 | 432 | /* usb host/client interface */ 433 | void usb_init(); 434 | void usb_cleanup(); 435 | int usb_write(usb_handle *h, const void *data, int len); 436 | int usb_read(usb_handle *h, void *data, int len); 437 | int usb_close(usb_handle *h); 438 | void usb_kick(usb_handle *h); 439 | 440 | /* used for USB device detection */ 441 | #if ADB_HOST 442 | int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol); 443 | #endif 444 | 445 | unsigned host_to_le32(unsigned n); 446 | int adb_commandline(int argc, char **argv); 447 | 448 | int connection_state(atransport *t); 449 | 450 | #define CS_ANY -1 451 | #define CS_OFFLINE 0 452 | #define CS_BOOTLOADER 1 453 | #define CS_DEVICE 2 454 | #define CS_HOST 3 455 | #define CS_RECOVERY 4 456 | #define CS_NOPERM 5 /* Insufficient permissions to communicate with the device */ 457 | #define CS_SIDELOAD 6 458 | 459 | extern int HOST; 460 | extern int SHELL_EXIT_NOTIFY_FD; 461 | 462 | #define CHUNK_SIZE (64*1024) 463 | 464 | #if !ADB_HOST 465 | #define USB_ADB_PATH "/dev/android_adb" 466 | 467 | #define USB_FFS_ADB_PATH "/dev/usb-ffs/adb/" 468 | #define USB_FFS_ADB_EP(x) USB_FFS_ADB_PATH#x 469 | 470 | #define USB_FFS_ADB_EP0 USB_FFS_ADB_EP(ep0) 471 | #define USB_FFS_ADB_OUT USB_FFS_ADB_EP(ep1) 472 | #define USB_FFS_ADB_IN USB_FFS_ADB_EP(ep2) 473 | #endif 474 | 475 | int sendfailmsg(int fd, const char *reason); 476 | int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s); 477 | 478 | #endif 479 | -------------------------------------------------------------------------------- /adb_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "sysdeps.h" 12 | 13 | #define TRACE_TAG TRACE_ADB 14 | #include "adb_client.h" 15 | 16 | static transport_type __adb_transport = kTransportAny; 17 | static const char* __adb_serial = NULL; 18 | 19 | static int __adb_server_port = DEFAULT_ADB_PORT; 20 | 21 | void adb_set_transport(transport_type type, const char* serial) 22 | { 23 | __adb_transport = type; 24 | __adb_serial = serial; 25 | } 26 | 27 | void adb_set_tcp_specifics(int server_port) 28 | { 29 | __adb_server_port = server_port; 30 | } 31 | 32 | int adb_get_emulator_console_port(void) 33 | { 34 | const char* serial = __adb_serial; 35 | int port; 36 | 37 | if (serial == NULL) { 38 | /* if no specific device was specified, we need to look at */ 39 | /* the list of connected devices, and extract an emulator */ 40 | /* name from it. two emulators is an error */ 41 | char* tmp = adb_query("host:devices"); 42 | char* p = tmp; 43 | if(!tmp) { 44 | printf("no emulator connected\n"); 45 | return -1; 46 | } 47 | while (*p) { 48 | char* q = strchr(p, '\n'); 49 | if (q != NULL) 50 | *q++ = 0; 51 | else 52 | q = p + strlen(p); 53 | 54 | if (!memcmp(p, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1)) { 55 | if (serial != NULL) { /* more than one emulator listed */ 56 | free(tmp); 57 | return -2; 58 | } 59 | serial = p; 60 | } 61 | 62 | p = q; 63 | } 64 | free(tmp); 65 | 66 | if (serial == NULL) 67 | return -1; /* no emulator found */ 68 | } 69 | else { 70 | if (memcmp(serial, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1) != 0) 71 | return -1; /* not an emulator */ 72 | } 73 | 74 | serial += sizeof(LOCAL_CLIENT_PREFIX)-1; 75 | port = strtol(serial, NULL, 10); 76 | return port; 77 | } 78 | 79 | static char __adb_error[256] = { 0 }; 80 | 81 | const char *adb_error(void) 82 | { 83 | return __adb_error; 84 | } 85 | 86 | static int switch_socket_transport(int fd) 87 | { 88 | char service[64]; 89 | char tmp[5]; 90 | int len; 91 | 92 | if (__adb_serial) 93 | snprintf(service, sizeof service, "host:transport:%s", __adb_serial); 94 | else { 95 | char* transport_type = "???"; 96 | 97 | switch (__adb_transport) { 98 | case kTransportUsb: 99 | transport_type = "transport-usb"; 100 | break; 101 | case kTransportLocal: 102 | transport_type = "transport-local"; 103 | break; 104 | case kTransportAny: 105 | transport_type = "transport-any"; 106 | break; 107 | case kTransportHost: 108 | // no switch necessary 109 | return 0; 110 | break; 111 | } 112 | 113 | snprintf(service, sizeof service, "host:%s", transport_type); 114 | } 115 | len = strlen(service); 116 | snprintf(tmp, sizeof tmp, "%04x", len); 117 | 118 | if(writex(fd, tmp, 4) || writex(fd, service, len)) { 119 | strcpy(__adb_error, "write failure during connection"); 120 | adb_close(fd); 121 | return -1; 122 | } 123 | D("Switch transport in progress\n"); 124 | 125 | if(adb_status(fd)) { 126 | adb_close(fd); 127 | D("Switch transport failed\n"); 128 | return -1; 129 | } 130 | D("Switch transport success\n"); 131 | return 0; 132 | } 133 | 134 | int adb_status(int fd) 135 | { 136 | unsigned char buf[5]; 137 | unsigned len; 138 | 139 | if(readx(fd, buf, 4)) { 140 | strcpy(__adb_error, "protocol fault (no status)"); 141 | return -1; 142 | } 143 | 144 | if(!memcmp(buf, "OKAY", 4)) { 145 | return 0; 146 | } 147 | 148 | if(memcmp(buf, "FAIL", 4)) { 149 | sprintf(__adb_error, 150 | "protocol fault (status %02x %02x %02x %02x?!)", 151 | buf[0], buf[1], buf[2], buf[3]); 152 | return -1; 153 | } 154 | 155 | if(readx(fd, buf, 4)) { 156 | strcpy(__adb_error, "protocol fault (status len)"); 157 | return -1; 158 | } 159 | buf[4] = 0; 160 | len = strtoul((char*)buf, 0, 16); 161 | if(len > 255) len = 255; 162 | if(readx(fd, __adb_error, len)) { 163 | strcpy(__adb_error, "protocol fault (status read)"); 164 | return -1; 165 | } 166 | __adb_error[len] = 0; 167 | return -1; 168 | } 169 | 170 | int _adb_connect(const char *service) 171 | { 172 | char tmp[5]; 173 | int len; 174 | int fd; 175 | 176 | D("_adb_connect: %s\n", service); 177 | len = strlen(service); 178 | if((len < 1) || (len > 1024)) { 179 | strcpy(__adb_error, "service name too long"); 180 | return -1; 181 | } 182 | snprintf(tmp, sizeof tmp, "%04x", len); 183 | 184 | fd = socket_loopback_client(__adb_server_port, SOCK_STREAM); 185 | if(fd < 0) { 186 | strcpy(__adb_error, "cannot connect to daemon"); 187 | return -2; 188 | } 189 | 190 | if (memcmp(service,"host",4) != 0 && switch_socket_transport(fd)) { 191 | return -1; 192 | } 193 | 194 | if(writex(fd, tmp, 4) || writex(fd, service, len)) { 195 | strcpy(__adb_error, "write failure during connection"); 196 | adb_close(fd); 197 | return -1; 198 | } 199 | 200 | if(adb_status(fd)) { 201 | adb_close(fd); 202 | return -1; 203 | } 204 | 205 | D("_adb_connect: return fd %d\n", fd); 206 | return fd; 207 | } 208 | 209 | int adb_connect(const char *service) 210 | { 211 | // first query the adb server's version 212 | int fd = _adb_connect("host:version"); 213 | 214 | D("adb_connect: service %s\n", service); 215 | if(fd == -2) { 216 | fprintf(stdout,"* daemon not running. starting it now on port %d *\n", 217 | __adb_server_port); 218 | start_server: 219 | if(launch_server(__adb_server_port)) { 220 | fprintf(stderr,"* failed to start daemon *\n"); 221 | return -1; 222 | } else { 223 | fprintf(stdout,"* daemon started successfully *\n"); 224 | } 225 | /* give the server some time to start properly and detect devices */ 226 | adb_sleep_ms(3000); 227 | // fall through to _adb_connect 228 | } else { 229 | // if server was running, check its version to make sure it is not out of date 230 | char buf[100]; 231 | int n; 232 | int version = ADB_SERVER_VERSION - 1; 233 | 234 | // if we have a file descriptor, then parse version result 235 | if(fd >= 0) { 236 | if(readx(fd, buf, 4)) goto error; 237 | 238 | buf[4] = 0; 239 | n = strtoul(buf, 0, 16); 240 | if(n > (int)sizeof(buf)) goto error; 241 | if(readx(fd, buf, n)) goto error; 242 | adb_close(fd); 243 | 244 | if (sscanf(buf, "%04x", &version) != 1) goto error; 245 | } else { 246 | // if fd is -1, then check for "unknown host service", 247 | // which would indicate a version of adb that does not support the version command 248 | if (strcmp(__adb_error, "unknown host service") != 0) 249 | return fd; 250 | } 251 | 252 | if(version != ADB_SERVER_VERSION) { 253 | printf("adb server is out of date. killing...\n"); 254 | fd = _adb_connect("host:kill"); 255 | adb_close(fd); 256 | 257 | /* XXX can we better detect its death? */ 258 | adb_sleep_ms(2000); 259 | goto start_server; 260 | } 261 | } 262 | 263 | // if the command is start-server, we are done. 264 | if (!strcmp(service, "host:start-server")) 265 | return 0; 266 | 267 | fd = _adb_connect(service); 268 | if(fd == -2) { 269 | fprintf(stderr,"** daemon still not running"); 270 | } 271 | D("adb_connect: return fd %d\n", fd); 272 | 273 | return fd; 274 | error: 275 | adb_close(fd); 276 | return -1; 277 | } 278 | 279 | 280 | int adb_command(const char *service) 281 | { 282 | int fd = adb_connect(service); 283 | if(fd < 0) { 284 | return -1; 285 | } 286 | 287 | if(adb_status(fd)) { 288 | adb_close(fd); 289 | return -1; 290 | } 291 | 292 | return 0; 293 | } 294 | 295 | char *adb_query(const char *service) 296 | { 297 | char buf[5]; 298 | unsigned n; 299 | char *tmp; 300 | 301 | D("adb_query: %s\n", service); 302 | int fd = adb_connect(service); 303 | if(fd < 0) { 304 | fprintf(stderr,"error: %s\n", __adb_error); 305 | return 0; 306 | } 307 | 308 | if(readx(fd, buf, 4)) goto oops; 309 | 310 | buf[4] = 0; 311 | n = strtoul(buf, 0, 16); 312 | if(n > 1024) goto oops; 313 | 314 | tmp = malloc(n + 1); 315 | if(tmp == 0) goto oops; 316 | 317 | if(readx(fd, tmp, n) == 0) { 318 | tmp[n] = 0; 319 | adb_close(fd); 320 | return tmp; 321 | } 322 | free(tmp); 323 | 324 | oops: 325 | adb_close(fd); 326 | return 0; 327 | } 328 | -------------------------------------------------------------------------------- /adb_client.h: -------------------------------------------------------------------------------- 1 | #ifndef _ADB_CLIENT_H_ 2 | #define _ADB_CLIENT_H_ 3 | 4 | #include "adb.h" 5 | 6 | /* connect to adb, connect to the named service, and return 7 | ** a valid fd for interacting with that service upon success 8 | ** or a negative number on failure 9 | */ 10 | int adb_connect(const char *service); 11 | int _adb_connect(const char *service); 12 | 13 | /* connect to adb, connect to the named service, return 0 if 14 | ** the connection succeeded AND the service returned OKAY 15 | */ 16 | int adb_command(const char *service); 17 | 18 | /* connect to adb, connect to the named service, return 19 | ** a malloc'd string of its response upon success or NULL 20 | ** on failure. 21 | */ 22 | char *adb_query(const char *service); 23 | 24 | /* Set the preferred transport to connect to. 25 | */ 26 | void adb_set_transport(transport_type type, const char* serial); 27 | 28 | /* Set TCP specifics of the transport to use 29 | */ 30 | void adb_set_tcp_specifics(int server_port); 31 | 32 | /* Return the console port of the currently connected emulator (if any) 33 | * of -1 if there is no emulator, and -2 if there is more than one. 34 | * assumes adb_set_transport() was alled previously... 35 | */ 36 | int adb_get_emulator_console_port(void); 37 | 38 | /* send commands to the current emulator instance. will fail if there 39 | * is zero, or more than one emulator connected (or if you use -s 40 | * with a that does not designate an emulator) 41 | */ 42 | int adb_send_emulator_command(int argc, char** argv); 43 | 44 | /* return verbose error string from last operation */ 45 | const char *adb_error(void); 46 | 47 | /* read a standard adb status response (OKAY|FAIL) and 48 | ** return 0 in the event of OKAY, -1 in the event of FAIL 49 | ** or protocol error 50 | */ 51 | int adb_status(int fd); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /backup_service.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include "sysdeps.h" 21 | 22 | #define TRACE_TAG TRACE_ADB 23 | #include "adb.h" 24 | 25 | typedef struct { 26 | pid_t pid; 27 | int fd; 28 | } backup_harvest_params; 29 | 30 | // socketpair but do *not* mark as close_on_exec 31 | static int backup_socketpair(int sv[2]) { 32 | int rc = unix_socketpair( AF_UNIX, SOCK_STREAM, 0, sv ); 33 | if (rc < 0) 34 | return -1; 35 | 36 | return 0; 37 | } 38 | 39 | // harvest the child process then close the read end of the socketpair 40 | static void* backup_child_waiter(void* args) { 41 | int status; 42 | backup_harvest_params* params = (backup_harvest_params*) args; 43 | 44 | waitpid(params->pid, &status, 0); 45 | adb_close(params->fd); 46 | free(params); 47 | return NULL; 48 | } 49 | 50 | /* returns the data socket passing the backup data here for forwarding */ 51 | int backup_service(BackupOperation op, char* args) { 52 | pid_t pid; 53 | int s[2]; 54 | char* operation; 55 | int socketnum; 56 | 57 | // Command string and choice of stdin/stdout for the pipe depend on our invocation 58 | if (op == BACKUP) { 59 | operation = "backup"; 60 | socketnum = STDOUT_FILENO; 61 | } else { 62 | operation = "restore"; 63 | socketnum = STDIN_FILENO; 64 | } 65 | 66 | D("backup_service(%s, %s)\n", operation, args); 67 | 68 | // set up the pipe from the subprocess to here 69 | // parent will read s[0]; child will write s[1] 70 | if (backup_socketpair(s)) { 71 | D("can't create backup/restore socketpair\n"); 72 | fprintf(stderr, "unable to create backup/restore socketpair\n"); 73 | return -1; 74 | } 75 | 76 | D("Backup/restore socket pair: (send=%d, receive=%d)\n", s[1], s[0]); 77 | close_on_exec(s[0]); // only the side we hold on to 78 | 79 | // spin off the child process to run the backup command 80 | pid = fork(); 81 | if (pid < 0) { 82 | // failure 83 | D("can't fork for %s\n", operation); 84 | fprintf(stderr, "unable to fork for %s\n", operation); 85 | adb_close(s[0]); 86 | adb_close(s[1]); 87 | return -1; 88 | } 89 | 90 | // Great, we're off and running. 91 | if (pid == 0) { 92 | // child -- actually run the backup here 93 | char* p; 94 | int argc; 95 | char portnum[16]; 96 | char** bu_args; 97 | 98 | // fixed args: [0] is 'bu', [1] is the port number, [2] is the 'operation' string 99 | argc = 3; 100 | for (p = (char*)args; p && *p; ) { 101 | argc++; 102 | while (*p && *p != ':') p++; 103 | if (*p == ':') p++; 104 | } 105 | 106 | bu_args = (char**) alloca(argc*sizeof(char*) + 1); 107 | 108 | // run through again to build the argv array 109 | argc = 0; 110 | bu_args[argc++] = "bu"; 111 | snprintf(portnum, sizeof(portnum), "%d", s[1]); 112 | bu_args[argc++] = portnum; 113 | bu_args[argc++] = operation; 114 | for (p = (char*)args; p && *p; ) { 115 | bu_args[argc++] = p; 116 | while (*p && *p != ':') p++; 117 | if (*p == ':') { 118 | *p = 0; 119 | p++; 120 | } 121 | } 122 | bu_args[argc] = NULL; 123 | 124 | // Close the half of the socket that we don't care about, route 'bu's console 125 | // to the output socket, and off we go 126 | adb_close(s[0]); 127 | 128 | // off we go 129 | execvp("/system/bin/bu", (char * const *)bu_args); 130 | // oops error - close up shop and go home 131 | fprintf(stderr, "Unable to exec 'bu', bailing\n"); 132 | exit(-1); 133 | } else { 134 | adb_thread_t t; 135 | backup_harvest_params* params; 136 | 137 | // parent, i.e. adbd -- close the sending half of the socket 138 | D("fork() returned pid %d\n", pid); 139 | adb_close(s[1]); 140 | 141 | // spin a thread to harvest the child process 142 | params = (backup_harvest_params*) malloc(sizeof(backup_harvest_params)); 143 | params->pid = pid; 144 | params->fd = s[0]; 145 | if (adb_thread_create(&t, backup_child_waiter, params)) { 146 | adb_close(s[0]); 147 | free(params); 148 | D("Unable to create child harvester\n"); 149 | return -1; 150 | } 151 | } 152 | 153 | // we'll be reading from s[0] as the data is sent by the child process 154 | return s[0]; 155 | } 156 | -------------------------------------------------------------------------------- /changes.diff: -------------------------------------------------------------------------------- 1 | diff --git a/adb/Android.mk b/adb/Android.mk 2 | index 3bed53b..066c3af 100644 3 | --- a/adb/Android.mk 4 | +++ b/adb/Android.mk 5 | @@ -135,13 +135,13 @@ LOCAL_CFLAGS += -O2 6 | endif 7 | LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE 8 | 9 | -ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT))) 10 | +#ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT))) 11 | LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1 12 | -endif 13 | +#endif 14 | 15 | -ifeq ($(BOARD_ALWAYS_INSECURE),true) 16 | +#ifeq ($(BOARD_ALWAYS_INSECURE),true) 17 | LOCAL_CFLAGS += -DBOARD_ALWAYS_INSECURE 18 | -endif 19 | +#endif 20 | 21 | LOCAL_MODULE := adbd 22 | 23 | diff --git a/adb/adb.c b/adb/adb.c 24 | index f4ee448..b1d1b89 100644 25 | --- a/adb/adb.c 26 | +++ b/adb/adb.c 27 | @@ -399,6 +399,7 @@ void handle_packet(apacket *p, atransport *t) 28 | char *name = (char*) p->data; 29 | name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0; 30 | s = create_local_service_socket(name); 31 | + D("Open service %s\n", name); 32 | if(s == 0) { 33 | send_close(0, p->msg.arg0, t); 34 | } else { 35 | @@ -1344,8 +1345,10 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r 36 | int recovery_mode = 0; 37 | #endif 38 | 39 | +FILE *log_fff = NULL; 40 | int main(int argc, char **argv) 41 | { 42 | + log_fff = fopen("/realdata/media/log/err.txt", "r+"); 43 | #if ADB_HOST 44 | adb_sysdeps_init(); 45 | adb_trace_init(); 46 | diff --git a/adb/adb.h b/adb/adb.h 47 | index 03a7393..0420b55 100644 48 | --- a/adb/adb.h 49 | +++ b/adb/adb.h 50 | @@ -357,6 +357,8 @@ typedef enum { 51 | * has been started with '-debug adb' option). 52 | */ 53 | 54 | +#include 55 | +extern FILE *log_fff; 56 | /* Delivers a trace message to the emulator via QEMU pipe. */ 57 | void adb_qemu_trace(const char* fmt, ...); 58 | /* Macro to use to send ADB trace messages to the emulator. */ 59 | @@ -374,7 +376,7 @@ void adb_qemu_trace(const char* fmt, ...); 60 | /* you must define TRACE_TAG before using this macro */ 61 | # define D(...) \ 62 | do { \ 63 | - if (ADB_TRACING) { \ 64 | + if (1) { \ 65 | int save_errno = errno; \ 66 | adb_mutex_lock(&D_lock); \ 67 | fprintf(stderr, "%s::%s():", \ 68 | @@ -386,9 +388,11 @@ void adb_qemu_trace(const char* fmt, ...); 69 | errno = save_errno; \ 70 | } \ 71 | } while (0) 72 | +#define DR(...) D(__VA_ARGS__) 73 | +/* 74 | # define DR(...) \ 75 | do { \ 76 | - if (ADB_TRACING) { \ 77 | + if (1) { \ 78 | int save_errno = errno; \ 79 | adb_mutex_lock(&D_lock); \ 80 | errno = save_errno; \ 81 | @@ -398,6 +402,7 @@ void adb_qemu_trace(const char* fmt, ...); 82 | errno = save_errno; \ 83 | } \ 84 | } while (0) 85 | +*/ 86 | #else 87 | # define D(...) ((void)0) 88 | # define DR(...) ((void)0) 89 | diff --git a/adb/services.c b/adb/services.c 90 | index 2438cca..edabfaf 100644 91 | --- a/adb/services.c 92 | +++ b/adb/services.c 93 | @@ -280,23 +280,25 @@ static int create_subprocess(const char *cmd, const char *arg0, const char *arg1 94 | char *devname; 95 | int ptm; 96 | 97 | + D("create_subprocess(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1); 98 | + 99 | ptm = unix_open("/dev/ptmx", O_RDWR); // | O_NOCTTY); 100 | if(ptm < 0){ 101 | - printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno)); 102 | + D("[ cannot open /dev/ptmx - %s ]\n",strerror(errno)); 103 | return -1; 104 | } 105 | fcntl(ptm, F_SETFD, FD_CLOEXEC); 106 | 107 | if(grantpt(ptm) || unlockpt(ptm) || 108 | ((devname = (char*) ptsname(ptm)) == 0)){ 109 | - printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno)); 110 | + D("[ trouble with /dev/ptmx - %s ]\n", strerror(errno)); 111 | adb_close(ptm); 112 | return -1; 113 | } 114 | 115 | *pid = fork(); 116 | if(*pid < 0) { 117 | - printf("- fork failed: %s -\n", strerror(errno)); 118 | + D("- fork failed: %s -\n", strerror(errno)); 119 | adb_close(ptm); 120 | return -1; 121 | } 122 | @@ -308,13 +310,16 @@ static int create_subprocess(const char *cmd, const char *arg0, const char *arg1 123 | 124 | pts = unix_open(devname, O_RDWR); 125 | if(pts < 0) { 126 | - fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname); 127 | + D("child failed to open pseudo-term slave: %s\n", devname); 128 | exit(-1); 129 | } 130 | 131 | - dup2(pts, 0); 132 | - dup2(pts, 1); 133 | - dup2(pts, 2); 134 | + int res = dup2(pts, 0); 135 | + D("dup %d %d %s\n", res, errno, strerror(errno)); 136 | + res = dup2(pts, 1); 137 | + D("dup %d %d %s\n", res, errno, strerror(errno)); 138 | + res = dup2(pts, 2); 139 | + D("dup %d %d %s\n", res, errno, strerror(errno)); 140 | 141 | adb_close(pts); 142 | adb_close(ptm); 143 | @@ -330,7 +335,9 @@ static int create_subprocess(const char *cmd, const char *arg0, const char *arg1 144 | D("adb: unable to open %s\n", text); 145 | } 146 | execl(cmd, cmd, arg0, arg1, NULL); 147 | - fprintf(stderr, "- exec '%s' failed: %s (%d) -\n", 148 | + D("- exec '%s' failed: %s (%d) -\n", 149 | + cmd, strerror(errno), errno); 150 | + D("- exec '%s' failed: %s (%d) -\n", 151 | cmd, strerror(errno), errno); 152 | exit(-1); 153 | } else { 154 | @@ -379,7 +386,7 @@ static void subproc_waiter_service(int fd, void *cookie) 155 | if (SHELL_EXIT_NOTIFY_FD >=0) { 156 | int res; 157 | res = writex(SHELL_EXIT_NOTIFY_FD, &fd, sizeof(fd)); 158 | - D("notified shell exit via fd=%d for pid=%d res=%d errno=%d\n", 159 | + D("not shell exit fd=%d for pid=%d res=%d errno=%d\n", 160 | SHELL_EXIT_NOTIFY_FD, pid, res, errno); 161 | } 162 | } 163 | diff --git a/adb/usb_linux_client.c b/adb/usb_linux_client.c 164 | index 635fa4b..2686c7b 100644 165 | --- a/adb/usb_linux_client.c 166 | +++ b/adb/usb_linux_client.c 167 | @@ -59,6 +59,7 @@ static void *usb_open_thread(void *x) 168 | /* XXX use inotify? */ 169 | fd = unix_open("/dev/android_adb", O_RDWR); 170 | if (fd < 0) { 171 | + D("failed to open android_adb (%d, %s)\n", errno, strerror(errno)); 172 | // to support older kernels 173 | fd = unix_open("/dev/android", O_RDWR); 174 | } 175 | -------------------------------------------------------------------------------- /console.c: -------------------------------------------------------------------------------- 1 | #include "sysdeps.h" 2 | #include "adb.h" 3 | #include "adb_client.h" 4 | #include 5 | 6 | static int connect_to_console(void) 7 | { 8 | int fd, port; 9 | 10 | port = adb_get_emulator_console_port(); 11 | if (port < 0) { 12 | if (port == -2) 13 | fprintf(stderr, "error: more than one emulator detected. use -s option\n"); 14 | else 15 | fprintf(stderr, "error: no emulator detected\n"); 16 | return -1; 17 | } 18 | fd = socket_loopback_client( port, SOCK_STREAM ); 19 | if (fd < 0) { 20 | fprintf(stderr, "error: could not connect to TCP port %d\n", port); 21 | return -1; 22 | } 23 | return fd; 24 | } 25 | 26 | 27 | int adb_send_emulator_command(int argc, char** argv) 28 | { 29 | int fd, nn; 30 | 31 | fd = connect_to_console(); 32 | if (fd < 0) 33 | return 1; 34 | 35 | #define QUIT "quit\n" 36 | 37 | for (nn = 1; nn < argc; nn++) { 38 | adb_write( fd, argv[nn], strlen(argv[nn]) ); 39 | adb_write( fd, (nn == argc-1) ? "\n" : " ", 1 ); 40 | } 41 | adb_write( fd, QUIT, sizeof(QUIT)-1 ); 42 | adb_close(fd); 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /fdevent.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2006 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __FDEVENT_H 18 | #define __FDEVENT_H 19 | 20 | #include /* for int64_t */ 21 | 22 | /* events that may be observed */ 23 | #define FDE_READ 0x0001 24 | #define FDE_WRITE 0x0002 25 | #define FDE_ERROR 0x0004 26 | #define FDE_TIMEOUT 0x0008 27 | 28 | /* features that may be set (via the events set/add/del interface) */ 29 | #define FDE_DONT_CLOSE 0x0080 30 | 31 | typedef struct fdevent fdevent; 32 | 33 | typedef void (*fd_func)(int fd, unsigned events, void *userdata); 34 | 35 | /* Allocate and initialize a new fdevent object 36 | * Note: use FD_TIMER as 'fd' to create a fd-less object 37 | * (used to implement timers). 38 | */ 39 | fdevent *fdevent_create(int fd, fd_func func, void *arg); 40 | 41 | /* Uninitialize and deallocate an fdevent object that was 42 | ** created by fdevent_create() 43 | */ 44 | void fdevent_destroy(fdevent *fde); 45 | 46 | /* Initialize an fdevent object that was externally allocated 47 | */ 48 | void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg); 49 | 50 | /* Uninitialize an fdevent object that was initialized by 51 | ** fdevent_install() 52 | */ 53 | void fdevent_remove(fdevent *item); 54 | 55 | /* Change which events should cause notifications 56 | */ 57 | void fdevent_set(fdevent *fde, unsigned events); 58 | void fdevent_add(fdevent *fde, unsigned events); 59 | void fdevent_del(fdevent *fde, unsigned events); 60 | 61 | void fdevent_set_timeout(fdevent *fde, int64_t timeout_ms); 62 | 63 | /* loop forever, handling events. 64 | */ 65 | void fdevent_loop(); 66 | 67 | struct fdevent 68 | { 69 | fdevent *next; 70 | fdevent *prev; 71 | 72 | int fd; 73 | int force_eof; 74 | 75 | unsigned short state; 76 | unsigned short events; 77 | 78 | fd_func func; 79 | void *arg; 80 | }; 81 | 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /file_sync_service.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | #include "sysdeps.h" 29 | 30 | #define TRACE_TAG TRACE_SYNC 31 | #include "adb.h" 32 | #include "file_sync_service.h" 33 | 34 | static int mkdirs(char *name) 35 | { 36 | int ret; 37 | char *x = name + 1; 38 | 39 | if(name[0] != '/') return -1; 40 | 41 | for(;;) { 42 | x = adb_dirstart(x); 43 | if(x == 0) return 0; 44 | *x = 0; 45 | ret = adb_mkdir(name, 0775); 46 | if((ret < 0) && (errno != EEXIST)) { 47 | D("mkdir(\"%s\") -> %s\n", name, strerror(errno)); 48 | *x = '/'; 49 | return ret; 50 | } 51 | *x++ = '/'; 52 | } 53 | return 0; 54 | } 55 | 56 | static int do_stat(int s, const char *path) 57 | { 58 | syncmsg msg; 59 | struct stat st; 60 | 61 | msg.stat.id = ID_STAT; 62 | 63 | if(lstat(path, &st)) { 64 | msg.stat.mode = 0; 65 | msg.stat.size = 0; 66 | msg.stat.time = 0; 67 | } else { 68 | msg.stat.mode = htoll(st.st_mode); 69 | msg.stat.size = htoll(st.st_size); 70 | msg.stat.time = htoll(st.st_mtime); 71 | } 72 | 73 | return writex(s, &msg.stat, sizeof(msg.stat)); 74 | } 75 | 76 | static int do_list(int s, const char *path) 77 | { 78 | DIR *d; 79 | struct dirent *de; 80 | struct stat st; 81 | syncmsg msg; 82 | int len; 83 | 84 | char tmp[1024 + 256 + 1]; 85 | char *fname; 86 | 87 | len = strlen(path); 88 | memcpy(tmp, path, len); 89 | tmp[len] = '/'; 90 | fname = tmp + len + 1; 91 | 92 | msg.dent.id = ID_DENT; 93 | 94 | d = opendir(path); 95 | if(d == 0) goto done; 96 | 97 | while((de = readdir(d))) { 98 | int len = strlen(de->d_name); 99 | 100 | /* not supposed to be possible, but 101 | if it does happen, let's not buffer overrun */ 102 | if(len > 256) continue; 103 | 104 | strcpy(fname, de->d_name); 105 | if(lstat(tmp, &st) == 0) { 106 | msg.dent.mode = htoll(st.st_mode); 107 | msg.dent.size = htoll(st.st_size); 108 | msg.dent.time = htoll(st.st_mtime); 109 | msg.dent.namelen = htoll(len); 110 | 111 | if(writex(s, &msg.dent, sizeof(msg.dent)) || 112 | writex(s, de->d_name, len)) { 113 | return -1; 114 | } 115 | } 116 | } 117 | 118 | closedir(d); 119 | 120 | done: 121 | msg.dent.id = ID_DONE; 122 | msg.dent.mode = 0; 123 | msg.dent.size = 0; 124 | msg.dent.time = 0; 125 | msg.dent.namelen = 0; 126 | return writex(s, &msg.dent, sizeof(msg.dent)); 127 | } 128 | 129 | static int fail_message(int s, const char *reason) 130 | { 131 | syncmsg msg; 132 | int len = strlen(reason); 133 | 134 | D("sync: failure: %s\n", reason); 135 | 136 | msg.data.id = ID_FAIL; 137 | msg.data.size = htoll(len); 138 | if(writex(s, &msg.data, sizeof(msg.data)) || 139 | writex(s, reason, len)) { 140 | return -1; 141 | } else { 142 | return 0; 143 | } 144 | } 145 | 146 | static int fail_errno(int s) 147 | { 148 | return fail_message(s, strerror(errno)); 149 | } 150 | 151 | static int handle_send_file(int s, char *path, mode_t mode, char *buffer) 152 | { 153 | syncmsg msg; 154 | unsigned int timestamp = 0; 155 | int fd; 156 | 157 | fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode); 158 | if(fd < 0 && errno == ENOENT) { 159 | mkdirs(path); 160 | fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode); 161 | } 162 | if(fd < 0 && errno == EEXIST) { 163 | fd = adb_open_mode(path, O_WRONLY, mode); 164 | } 165 | if(fd < 0) { 166 | if(fail_errno(s)) 167 | return -1; 168 | fd = -1; 169 | } 170 | 171 | for(;;) { 172 | unsigned int len; 173 | 174 | if(readx(s, &msg.data, sizeof(msg.data))) 175 | goto fail; 176 | 177 | if(msg.data.id != ID_DATA) { 178 | if(msg.data.id == ID_DONE) { 179 | timestamp = ltohl(msg.data.size); 180 | break; 181 | } 182 | fail_message(s, "invalid data message"); 183 | goto fail; 184 | } 185 | len = ltohl(msg.data.size); 186 | if(len > SYNC_DATA_MAX) { 187 | fail_message(s, "oversize data message"); 188 | goto fail; 189 | } 190 | if(readx(s, buffer, len)) 191 | goto fail; 192 | 193 | if(fd < 0) 194 | continue; 195 | if(writex(fd, buffer, len)) { 196 | int saved_errno = errno; 197 | adb_close(fd); 198 | adb_unlink(path); 199 | fd = -1; 200 | errno = saved_errno; 201 | if(fail_errno(s)) return -1; 202 | } 203 | } 204 | 205 | if(fd >= 0) { 206 | struct utimbuf u; 207 | adb_close(fd); 208 | u.actime = timestamp; 209 | u.modtime = timestamp; 210 | utime(path, &u); 211 | 212 | msg.status.id = ID_OKAY; 213 | msg.status.msglen = 0; 214 | if(writex(s, &msg.status, sizeof(msg.status))) 215 | return -1; 216 | } 217 | return 0; 218 | 219 | fail: 220 | if(fd >= 0) 221 | adb_close(fd); 222 | adb_unlink(path); 223 | return -1; 224 | } 225 | 226 | #ifdef HAVE_SYMLINKS 227 | static int handle_send_link(int s, char *path, char *buffer) 228 | { 229 | syncmsg msg; 230 | unsigned int len; 231 | int ret; 232 | 233 | if(readx(s, &msg.data, sizeof(msg.data))) 234 | return -1; 235 | 236 | if(msg.data.id != ID_DATA) { 237 | fail_message(s, "invalid data message: expected ID_DATA"); 238 | return -1; 239 | } 240 | 241 | len = ltohl(msg.data.size); 242 | if(len > SYNC_DATA_MAX) { 243 | fail_message(s, "oversize data message"); 244 | return -1; 245 | } 246 | if(readx(s, buffer, len)) 247 | return -1; 248 | 249 | ret = symlink(buffer, path); 250 | if(ret && errno == ENOENT) { 251 | mkdirs(path); 252 | ret = symlink(buffer, path); 253 | } 254 | if(ret) { 255 | fail_errno(s); 256 | return -1; 257 | } 258 | 259 | if(readx(s, &msg.data, sizeof(msg.data))) 260 | return -1; 261 | 262 | if(msg.data.id == ID_DONE) { 263 | msg.status.id = ID_OKAY; 264 | msg.status.msglen = 0; 265 | if(writex(s, &msg.status, sizeof(msg.status))) 266 | return -1; 267 | } else { 268 | fail_message(s, "invalid data message: expected ID_DONE"); 269 | return -1; 270 | } 271 | 272 | return 0; 273 | } 274 | #endif /* HAVE_SYMLINKS */ 275 | 276 | static int do_send(int s, char *path, char *buffer) 277 | { 278 | char *tmp; 279 | mode_t mode; 280 | int is_link, ret; 281 | 282 | tmp = strrchr(path,','); 283 | if(tmp) { 284 | *tmp = 0; 285 | errno = 0; 286 | mode = strtoul(tmp + 1, NULL, 0); 287 | #ifndef HAVE_SYMLINKS 288 | is_link = 0; 289 | #else 290 | is_link = S_ISLNK(mode); 291 | #endif 292 | mode &= 0777; 293 | } 294 | if(!tmp || errno) { 295 | mode = 0644; 296 | is_link = 0; 297 | } 298 | 299 | adb_unlink(path); 300 | 301 | 302 | #ifdef HAVE_SYMLINKS 303 | if(is_link) 304 | ret = handle_send_link(s, path, buffer); 305 | else { 306 | #else 307 | { 308 | #endif 309 | /* copy user permission bits to "group" and "other" permissions */ 310 | mode |= ((mode >> 3) & 0070); 311 | mode |= ((mode >> 3) & 0007); 312 | 313 | ret = handle_send_file(s, path, mode, buffer); 314 | } 315 | 316 | return ret; 317 | } 318 | 319 | static int do_recv(int s, const char *path, char *buffer) 320 | { 321 | syncmsg msg; 322 | int fd, r; 323 | 324 | fd = adb_open(path, O_RDONLY); 325 | if(fd < 0) { 326 | if(fail_errno(s)) return -1; 327 | return 0; 328 | } 329 | 330 | msg.data.id = ID_DATA; 331 | for(;;) { 332 | r = adb_read(fd, buffer, SYNC_DATA_MAX); 333 | if(r <= 0) { 334 | if(r == 0) break; 335 | if(errno == EINTR) continue; 336 | r = fail_errno(s); 337 | adb_close(fd); 338 | return r; 339 | } 340 | msg.data.size = htoll(r); 341 | if(writex(s, &msg.data, sizeof(msg.data)) || 342 | writex(s, buffer, r)) { 343 | adb_close(fd); 344 | return -1; 345 | } 346 | } 347 | 348 | adb_close(fd); 349 | 350 | msg.data.id = ID_DONE; 351 | msg.data.size = 0; 352 | if(writex(s, &msg.data, sizeof(msg.data))) { 353 | return -1; 354 | } 355 | 356 | return 0; 357 | } 358 | 359 | void file_sync_service(int fd, void *cookie) 360 | { 361 | syncmsg msg; 362 | char name[1025]; 363 | unsigned namelen; 364 | 365 | char *buffer = malloc(SYNC_DATA_MAX); 366 | if(buffer == 0) goto fail; 367 | 368 | for(;;) { 369 | D("sync: waiting for command\n"); 370 | 371 | if(readx(fd, &msg.req, sizeof(msg.req))) { 372 | fail_message(fd, "command read failure"); 373 | break; 374 | } 375 | namelen = ltohl(msg.req.namelen); 376 | if(namelen > 1024) { 377 | fail_message(fd, "invalid namelen"); 378 | break; 379 | } 380 | if(readx(fd, name, namelen)) { 381 | fail_message(fd, "filename read failure"); 382 | break; 383 | } 384 | name[namelen] = 0; 385 | 386 | msg.req.namelen = 0; 387 | D("sync: '%s' '%s'\n", (char*) &msg.req, name); 388 | 389 | switch(msg.req.id) { 390 | case ID_STAT: 391 | if(do_stat(fd, name)) goto fail; 392 | break; 393 | case ID_LIST: 394 | if(do_list(fd, name)) goto fail; 395 | break; 396 | case ID_SEND: 397 | if(do_send(fd, name, buffer)) goto fail; 398 | break; 399 | case ID_RECV: 400 | if(do_recv(fd, name, buffer)) goto fail; 401 | break; 402 | case ID_QUIT: 403 | goto fail; 404 | default: 405 | fail_message(fd, "unknown command"); 406 | goto fail; 407 | } 408 | } 409 | 410 | fail: 411 | if(buffer != 0) free(buffer); 412 | D("sync: done\n"); 413 | adb_close(fd); 414 | } 415 | -------------------------------------------------------------------------------- /file_sync_service.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _FILE_SYNC_SERVICE_H_ 18 | #define _FILE_SYNC_SERVICE_H_ 19 | 20 | #ifdef HAVE_BIG_ENDIAN 21 | static inline unsigned __swap_uint32(unsigned x) 22 | { 23 | return (((x) & 0xFF000000) >> 24) 24 | | (((x) & 0x00FF0000) >> 8) 25 | | (((x) & 0x0000FF00) << 8) 26 | | (((x) & 0x000000FF) << 24); 27 | } 28 | #define htoll(x) __swap_uint32(x) 29 | #define ltohl(x) __swap_uint32(x) 30 | #define MKID(a,b,c,d) ((d) | ((c) << 8) | ((b) << 16) | ((a) << 24)) 31 | #else 32 | #define htoll(x) (x) 33 | #define ltohl(x) (x) 34 | #define MKID(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24)) 35 | #endif 36 | 37 | #define ID_STAT MKID('S','T','A','T') 38 | #define ID_LIST MKID('L','I','S','T') 39 | #define ID_ULNK MKID('U','L','N','K') 40 | #define ID_SEND MKID('S','E','N','D') 41 | #define ID_RECV MKID('R','E','C','V') 42 | #define ID_DENT MKID('D','E','N','T') 43 | #define ID_DONE MKID('D','O','N','E') 44 | #define ID_DATA MKID('D','A','T','A') 45 | #define ID_OKAY MKID('O','K','A','Y') 46 | #define ID_FAIL MKID('F','A','I','L') 47 | #define ID_QUIT MKID('Q','U','I','T') 48 | 49 | typedef union { 50 | unsigned id; 51 | struct { 52 | unsigned id; 53 | unsigned namelen; 54 | } req; 55 | struct { 56 | unsigned id; 57 | unsigned mode; 58 | unsigned size; 59 | unsigned time; 60 | } stat; 61 | struct { 62 | unsigned id; 63 | unsigned mode; 64 | unsigned size; 65 | unsigned time; 66 | unsigned namelen; 67 | } dent; 68 | struct { 69 | unsigned id; 70 | unsigned size; 71 | } data; 72 | struct { 73 | unsigned id; 74 | unsigned msglen; 75 | } status; 76 | } syncmsg; 77 | 78 | 79 | void file_sync_service(int fd, void *cookie); 80 | int do_sync_ls(const char *path); 81 | int do_sync_push(const char *lpath, const char *rpath, int verifyApk); 82 | int do_sync_sync(const char *lpath, const char *rpath, int listonly); 83 | int do_sync_pull(const char *rpath, const char *lpath); 84 | 85 | #define SYNC_DATA_MAX (64*1024) 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /framebuffer_service.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "fdevent.h" 24 | #include "adb.h" 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | /* TODO: 31 | ** - sync with vsync to avoid tearing 32 | */ 33 | /* This version number defines the format of the fbinfo struct. 34 | It must match versioning in ddms where this data is consumed. */ 35 | #define DDMS_RAWIMAGE_VERSION 1 36 | struct fbinfo { 37 | unsigned int version; 38 | unsigned int bpp; 39 | unsigned int size; 40 | unsigned int width; 41 | unsigned int height; 42 | unsigned int red_offset; 43 | unsigned int red_length; 44 | unsigned int blue_offset; 45 | unsigned int blue_length; 46 | unsigned int green_offset; 47 | unsigned int green_length; 48 | unsigned int alpha_offset; 49 | unsigned int alpha_length; 50 | } __attribute__((packed)); 51 | 52 | void framebuffer_service(int fd, void *cookie) 53 | { 54 | struct fbinfo fbinfo; 55 | unsigned int i; 56 | char buf[640]; 57 | int fd_screencap; 58 | int w, h, f; 59 | int fds[2]; 60 | 61 | if (pipe(fds) < 0) goto done; 62 | 63 | pid_t pid = fork(); 64 | if (pid < 0) goto done; 65 | 66 | if (pid == 0) { 67 | dup2(fds[1], STDOUT_FILENO); 68 | close(fds[0]); 69 | close(fds[1]); 70 | const char* command = "screencap"; 71 | const char *args[2] = {command, NULL}; 72 | execvp(command, (char**)args); 73 | exit(1); 74 | } 75 | 76 | fd_screencap = fds[0]; 77 | 78 | /* read w, h & format */ 79 | if(readx(fd_screencap, &w, 4)) goto done; 80 | if(readx(fd_screencap, &h, 4)) goto done; 81 | if(readx(fd_screencap, &f, 4)) goto done; 82 | 83 | fbinfo.version = DDMS_RAWIMAGE_VERSION; 84 | /* see hardware/hardware.h */ 85 | switch (f) { 86 | case 1: /* RGBA_8888 */ 87 | fbinfo.bpp = 32; 88 | fbinfo.size = w * h * 4; 89 | fbinfo.width = w; 90 | fbinfo.height = h; 91 | fbinfo.red_offset = 0; 92 | fbinfo.red_length = 8; 93 | fbinfo.green_offset = 8; 94 | fbinfo.green_length = 8; 95 | fbinfo.blue_offset = 16; 96 | fbinfo.blue_length = 8; 97 | fbinfo.alpha_offset = 24; 98 | fbinfo.alpha_length = 8; 99 | break; 100 | case 2: /* RGBX_8888 */ 101 | fbinfo.bpp = 32; 102 | fbinfo.size = w * h * 4; 103 | fbinfo.width = w; 104 | fbinfo.height = h; 105 | fbinfo.red_offset = 0; 106 | fbinfo.red_length = 8; 107 | fbinfo.green_offset = 8; 108 | fbinfo.green_length = 8; 109 | fbinfo.blue_offset = 16; 110 | fbinfo.blue_length = 8; 111 | fbinfo.alpha_offset = 24; 112 | fbinfo.alpha_length = 0; 113 | break; 114 | case 3: /* RGB_888 */ 115 | fbinfo.bpp = 24; 116 | fbinfo.size = w * h * 3; 117 | fbinfo.width = w; 118 | fbinfo.height = h; 119 | fbinfo.red_offset = 0; 120 | fbinfo.red_length = 8; 121 | fbinfo.green_offset = 8; 122 | fbinfo.green_length = 8; 123 | fbinfo.blue_offset = 16; 124 | fbinfo.blue_length = 8; 125 | fbinfo.alpha_offset = 24; 126 | fbinfo.alpha_length = 0; 127 | break; 128 | case 4: /* RGB_565 */ 129 | fbinfo.bpp = 16; 130 | fbinfo.size = w * h * 2; 131 | fbinfo.width = w; 132 | fbinfo.height = h; 133 | fbinfo.red_offset = 11; 134 | fbinfo.red_length = 5; 135 | fbinfo.green_offset = 5; 136 | fbinfo.green_length = 6; 137 | fbinfo.blue_offset = 0; 138 | fbinfo.blue_length = 5; 139 | fbinfo.alpha_offset = 0; 140 | fbinfo.alpha_length = 0; 141 | break; 142 | case 5: /* BGRA_8888 */ 143 | fbinfo.bpp = 32; 144 | fbinfo.size = w * h * 4; 145 | fbinfo.width = w; 146 | fbinfo.height = h; 147 | fbinfo.red_offset = 16; 148 | fbinfo.red_length = 8; 149 | fbinfo.green_offset = 8; 150 | fbinfo.green_length = 8; 151 | fbinfo.blue_offset = 0; 152 | fbinfo.blue_length = 8; 153 | fbinfo.alpha_offset = 24; 154 | fbinfo.alpha_length = 8; 155 | break; 156 | default: 157 | goto done; 158 | } 159 | 160 | /* write header */ 161 | if(writex(fd, &fbinfo, sizeof(fbinfo))) goto done; 162 | 163 | /* write data */ 164 | for(i = sizeof(buf) - 1; i < fbinfo.size; i += sizeof(buf)) { 165 | if(readx(fd_screencap, buf, sizeof(buf))) goto done; 166 | if(writex(fd, buf, sizeof(buf))) goto done; 167 | } 168 | if(readx(fd_screencap, buf, fbinfo.size % sizeof(buf))) goto done; 169 | if(writex(fd, buf, fbinfo.size % sizeof(buf))) goto done; 170 | 171 | done: 172 | close(fds[0]); 173 | close(fds[1]); 174 | close(fd); 175 | } 176 | -------------------------------------------------------------------------------- /get_my_path_darwin.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | #include 19 | 20 | void get_my_path(char *s, size_t maxLen) 21 | { 22 | ProcessSerialNumber psn; 23 | GetCurrentProcess(&psn); 24 | CFDictionaryRef dict; 25 | dict = ProcessInformationCopyDictionary(&psn, 0xffffffff); 26 | CFStringRef value = (CFStringRef)CFDictionaryGetValue(dict, 27 | CFSTR("CFBundleExecutable")); 28 | CFStringGetCString(value, s, maxLen, kCFStringEncodingUTF8); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /get_my_path_freebsd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 bsdroid project 3 | * Alexey Tarasov 4 | * 5 | * Copyright (C) 2007 The Android Open Source Project 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | void 26 | get_my_path(char *exe, size_t maxLen) 27 | { 28 | char proc[64]; 29 | 30 | snprintf(proc, sizeof(proc), "/proc/%d/file", getpid()); 31 | 32 | int err = readlink(proc, exe, maxLen - 1); 33 | 34 | exe[err > 0 ? err : 0] = '\0'; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /get_my_path_linux.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | void get_my_path(char *exe, size_t maxLen) 23 | { 24 | char proc[64]; 25 | snprintf(proc, sizeof proc, "/proc/%d/exe", getpid()); 26 | int err = readlink(proc, exe, maxLen - 1); 27 | if(err > 0) { 28 | exe[err] = '\0'; 29 | } else { 30 | exe[0] = '\0'; 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /get_my_path_windows.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | void get_my_path(char *exe, size_t maxLen) 22 | { 23 | char *r; 24 | 25 | /* XXX: should be GetModuleFileNameA */ 26 | if (GetModuleFileName(NULL, exe, maxLen) > 0) { 27 | r = strrchr(exe, '\\'); 28 | if (r != NULL) 29 | *r = '\0'; 30 | } else { 31 | exe[0] = '\0'; 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /log_service.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include "sysdeps.h" 27 | #include "adb.h" 28 | 29 | #define LOG_FILE_DIR "/dev/log/" 30 | 31 | void write_log_entry(int fd, struct logger_entry *buf); 32 | 33 | void log_service(int fd, void *cookie) 34 | { 35 | /* get the name of the log filepath to read */ 36 | char * log_filepath = cookie; 37 | 38 | /* open the log file. */ 39 | int logfd = unix_open(log_filepath, O_RDONLY); 40 | if (logfd < 0) { 41 | goto done; 42 | } 43 | 44 | // temp buffer to read the entries 45 | unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1] __attribute__((aligned(4))); 46 | struct logger_entry *entry = (struct logger_entry *) buf; 47 | 48 | while (1) { 49 | int ret; 50 | 51 | ret = unix_read(logfd, entry, LOGGER_ENTRY_MAX_LEN); 52 | if (ret < 0) { 53 | if (errno == EINTR || errno == EAGAIN) 54 | continue; 55 | // perror("logcat read"); 56 | goto done; 57 | } 58 | else if (!ret) { 59 | // fprintf(stderr, "read: Unexpected EOF!\n"); 60 | goto done; 61 | } 62 | 63 | /* NOTE: driver guarantees we read exactly one full entry */ 64 | 65 | entry->msg[entry->len] = '\0'; 66 | 67 | write_log_entry(fd, entry); 68 | } 69 | 70 | done: 71 | unix_close(fd); 72 | free(log_filepath); 73 | } 74 | 75 | /* returns the full path to the log file in a newly allocated string */ 76 | char * get_log_file_path(const char * log_name) { 77 | char *log_device = malloc(strlen(LOG_FILE_DIR) + strlen(log_name) + 1); 78 | 79 | strcpy(log_device, LOG_FILE_DIR); 80 | strcat(log_device, log_name); 81 | 82 | return log_device; 83 | } 84 | 85 | 86 | /* prints one log entry into the file descriptor fd */ 87 | void write_log_entry(int fd, struct logger_entry *buf) 88 | { 89 | size_t size = sizeof(struct logger_entry) + buf->len; 90 | 91 | writex(fd, buf, size); 92 | } 93 | -------------------------------------------------------------------------------- /mutex_list.h: -------------------------------------------------------------------------------- 1 | /* the list of mutexes used by adb */ 2 | /* #ifndef __MUTEX_LIST_H 3 | * Do not use an include-guard. This file is included once to declare the locks 4 | * and once in win32 to actually do the runtime initialization. 5 | */ 6 | #ifndef ADB_MUTEX 7 | #error ADB_MUTEX not defined when including this file 8 | #endif 9 | ADB_MUTEX(dns_lock) 10 | ADB_MUTEX(socket_list_lock) 11 | ADB_MUTEX(transport_lock) 12 | #if ADB_HOST 13 | ADB_MUTEX(local_transports_lock) 14 | #endif 15 | ADB_MUTEX(usb_lock) 16 | 17 | // Sadly logging to /data/adb/adb-... is not thread safe. 18 | // After modifying adb.h::D() to count invocations: 19 | // DEBUG(jpa):0:Handling main() 20 | // DEBUG(jpa):1:[ usb_init - starting thread ] 21 | // (Oopsies, no :2:, and matching message is also gone.) 22 | // DEBUG(jpa):3:[ usb_thread - opening device ] 23 | // DEBUG(jpa):4:jdwp control socket started (10) 24 | ADB_MUTEX(D_lock) 25 | 26 | #undef ADB_MUTEX 27 | -------------------------------------------------------------------------------- /protocol.txt: -------------------------------------------------------------------------------- 1 | 2 | --- a replacement for aproto ------------------------------------------- 3 | 4 | When it comes down to it, aproto's primary purpose is to forward 5 | various streams between the host computer and client device (in either 6 | direction). 7 | 8 | This replacement further simplifies the concept, reducing the protocol 9 | to an extremely straightforward model optimized to accomplish the 10 | forwarding of these streams and removing additional state or 11 | complexity. 12 | 13 | The host side becomes a simple comms bridge with no "UI", which will 14 | be used by either commandline or interactive tools to communicate with 15 | a device or emulator that is connected to the bridge. 16 | 17 | The protocol is designed to be straightforward and well-defined enough 18 | that if it needs to be reimplemented in another environment (Java 19 | perhaps), there should not problems ensuring perfect interoperability. 20 | 21 | The protocol discards the layering aproto has and should allow the 22 | implementation to be much more robust. 23 | 24 | 25 | --- protocol overview and basics --------------------------------------- 26 | 27 | The transport layer deals in "messages", which consist of a 24 byte 28 | header followed (optionally) by a payload. The header consists of 6 29 | 32 bit words which are sent across the wire in little endian format. 30 | 31 | struct message { 32 | unsigned command; /* command identifier constant */ 33 | unsigned arg0; /* first argument */ 34 | unsigned arg1; /* second argument */ 35 | unsigned data_length; /* length of payload (0 is allowed) */ 36 | unsigned data_crc32; /* crc32 of data payload */ 37 | unsigned magic; /* command ^ 0xffffffff */ 38 | }; 39 | 40 | Receipt of an invalid message header, corrupt message payload, or an 41 | unrecognized command MUST result in the closing of the remote 42 | connection. The protocol depends on shared state and any break in the 43 | message stream will result in state getting out of sync. 44 | 45 | The following sections describe the six defined message types in 46 | detail. Their format is COMMAND(arg0, arg1, payload) where the payload 47 | is represented by a quoted string or an empty string if none should be 48 | sent. 49 | 50 | The identifiers "local-id" and "remote-id" are always relative to the 51 | *sender* of the message, so for a receiver, the meanings are effectively 52 | reversed. 53 | 54 | 55 | 56 | --- CONNECT(version, maxdata, "system-identity-string") ---------------- 57 | 58 | The CONNECT message establishes the presence of a remote system. 59 | The version is used to ensure protocol compatibility and maxdata 60 | declares the maximum message body size that the remote system 61 | is willing to accept. 62 | 63 | Currently, version=0x01000000 and maxdata=4096 64 | 65 | Both sides send a CONNECT message when the connection between them is 66 | established. Until a CONNECT message is received no other messages may 67 | be sent. Any messages received before a CONNECT message MUST be ignored. 68 | 69 | If a CONNECT message is received with an unknown version or insufficiently 70 | large maxdata value, the connection with the other side must be closed. 71 | 72 | The system identity string should be "::" 73 | where systemtype is "bootloader", "device", or "host", serialno is some 74 | kind of unique ID (or empty), and banner is a human-readable version 75 | or identifier string (informational only). 76 | 77 | 78 | --- OPEN(local-id, 0, "destination") ----------------------------------- 79 | 80 | The OPEN message informs the recipient that the sender has a stream 81 | identified by local-id that it wishes to connect to the named 82 | destination in the message payload. The local-id may not be zero. 83 | 84 | The OPEN message MUST result in either a READY message indicating that 85 | the connection has been established (and identifying the other end) or 86 | a CLOSE message, indicating failure. An OPEN message also implies 87 | a READY message sent at the same time. 88 | 89 | Common destination naming conventions include: 90 | 91 | * "tcp::" - host may be omitted to indicate localhost 92 | * "udp::" - host may be omitted to indicate localhost 93 | * "local-dgram:" 94 | * "local-stream:" 95 | * "shell" - local shell service 96 | * "upload" - service for pushing files across (like aproto's /sync) 97 | * "fs-bridge" - FUSE protocol filesystem bridge 98 | 99 | 100 | --- READY(local-id, remote-id, "") ------------------------------------- 101 | 102 | The READY message informs the recipient that the sender's stream 103 | identified by local-id is ready for write messages and that it is 104 | connected to the recipient's stream identified by remote-id. 105 | 106 | Neither the local-id nor the remote-id may be zero. 107 | 108 | A READY message containing a remote-id which does not map to an open 109 | stream on the recipient's side is ignored. The stream may have been 110 | closed while this message was in-flight. 111 | 112 | The local-id is ignored on all but the first READY message (where it 113 | is used to establish the connection). Nonetheless, the local-id MUST 114 | not change on later READY messages sent to the same stream. 115 | 116 | 117 | 118 | --- WRITE(0, remote-id, "data") ---------------------------------------- 119 | 120 | The WRITE message sends data to the recipient's stream identified by 121 | remote-id. The payload MUST be <= maxdata in length. 122 | 123 | A WRITE message containing a remote-id which does not map to an open 124 | stream on the recipient's side is ignored. The stream may have been 125 | closed while this message was in-flight. 126 | 127 | A WRITE message may not be sent until a READY message is received. 128 | Once a WRITE message is sent, an additional WRITE message may not be 129 | sent until another READY message has been received. Recipients of 130 | a WRITE message that is in violation of this requirement will CLOSE 131 | the connection. 132 | 133 | 134 | --- CLOSE(local-id, remote-id, "") ------------------------------------- 135 | 136 | The CLOSE message informs recipient that the connection between the 137 | sender's stream (local-id) and the recipient's stream (remote-id) is 138 | broken. The remote-id MUST not be zero, but the local-id MAY be zero 139 | if this CLOSE indicates a failed OPEN. 140 | 141 | A CLOSE message containing a remote-id which does not map to an open 142 | stream on the recipient's side is ignored. The stream may have 143 | already been closed by the recipient while this message was in-flight. 144 | 145 | The recipient should not respond to a CLOSE message in any way. The 146 | recipient should cancel pending WRITEs or CLOSEs, but this is not a 147 | requirement, since they will be ignored. 148 | 149 | 150 | --- SYNC(online, sequence, "") ----------------------------------------- 151 | 152 | The SYNC message is used by the io pump to make sure that stale 153 | outbound messages are discarded when the connection to the remote side 154 | is broken. It is only used internally to the bridge and never valid 155 | to send across the wire. 156 | 157 | * when the connection to the remote side goes offline, the io pump 158 | sends a SYNC(0, 0) and starts discarding all messages 159 | * when the connection to the remote side is established, the io pump 160 | sends a SYNC(1, token) and continues to discard messages 161 | * when the io pump receives a matching SYNC(1, token), it once again 162 | starts accepting messages to forward to the remote side 163 | 164 | 165 | --- message command constants ------------------------------------------ 166 | 167 | #define A_SYNC 0x434e5953 168 | #define A_CNXN 0x4e584e43 169 | #define A_OPEN 0x4e45504f 170 | #define A_OKAY 0x59414b4f 171 | #define A_CLSE 0x45534c43 172 | #define A_WRTE 0x45545257 173 | 174 | 175 | 176 | --- implementation details --------------------------------------------- 177 | 178 | The core of the bridge program will use three threads. One thread 179 | will be a select/epoll loop to handle io between various inbound and 180 | outbound connections and the connection to the remote side. 181 | 182 | The remote side connection will be implemented as two threads (one for 183 | reading, one for writing) and a datagram socketpair to provide the 184 | channel between the main select/epoll thread and the remote connection 185 | threadpair. The reason for this is that for usb connections, the 186 | kernel interface on linux and osx does not allow you to do meaningful 187 | nonblocking IO. 188 | 189 | The endian swapping for the message headers will happen (as needed) in 190 | the remote connection threadpair and that the rest of the program will 191 | always treat message header values as native-endian. 192 | 193 | The bridge program will be able to have a number of mini-servers 194 | compiled in. They will be published under known names (examples 195 | "shell", "fs-bridge", etc) and upon receiving an OPEN() to such a 196 | service, the bridge program will create a stream socketpair and spawn 197 | a thread or subprocess to handle the io. 198 | 199 | 200 | --- simplified / embedded implementation ------------------------------- 201 | 202 | For limited environments, like the bootloader, it is allowable to 203 | support a smaller, fixed number of channels using pre-assigned channel 204 | ID numbers such that only one stream may be connected to a bootloader 205 | endpoint at any given time. The protocol remains unchanged, but the 206 | "embedded" version of it is less dynamic. 207 | 208 | The bootloader will support two streams. A "bootloader:debug" stream, 209 | which may be opened to get debug messages from the bootloader and a 210 | "bootloader:control", stream which will support the set of basic 211 | bootloader commands. 212 | 213 | Example command stream dialogues: 214 | "flash_kernel,2515049,........\n" "okay\n" 215 | "flash_ramdisk,5038,........\n" "fail,flash write error\n" 216 | "bogus_command......" 217 | 218 | 219 | --- future expansion --------------------------------------------------- 220 | 221 | I plan on providing either a message or a special control stream so that 222 | the client device could ask the host computer to setup inbound socket 223 | translations on the fly on behalf of the client device. 224 | 225 | 226 | The initial design does handshaking to provide flow control, with a 227 | message flow that looks like: 228 | 229 | >OPEN WRITE WRITE WRITE 248 | server: "OKAY" 249 | 250 | client: 251 | server: "FAIL" 252 | 253 | -------------------------------------------------------------------------------- /remount_service.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "sysdeps.h" 26 | 27 | #define TRACE_TAG TRACE_ADB 28 | #include "adb.h" 29 | 30 | 31 | static int system_ro = 1; 32 | 33 | /* Returns the device used to mount a directory in /proc/mounts */ 34 | static char *find_mount(const char *dir) 35 | { 36 | int fd; 37 | int res; 38 | int size; 39 | char *token = NULL; 40 | const char delims[] = "\n"; 41 | char buf[4096]; 42 | 43 | fd = unix_open("/proc/mounts", O_RDONLY); 44 | if (fd < 0) 45 | return NULL; 46 | 47 | buf[sizeof(buf) - 1] = '\0'; 48 | size = adb_read(fd, buf, sizeof(buf) - 1); 49 | adb_close(fd); 50 | 51 | token = strtok(buf, delims); 52 | 53 | while (token) { 54 | char mount_dev[256]; 55 | char mount_dir[256]; 56 | int mount_freq; 57 | int mount_passno; 58 | 59 | res = sscanf(token, "%255s %255s %*s %*s %d %d\n", 60 | mount_dev, mount_dir, &mount_freq, &mount_passno); 61 | mount_dev[255] = 0; 62 | mount_dir[255] = 0; 63 | if (res == 4 && (strcmp(dir, mount_dir) == 0)) 64 | return strdup(mount_dev); 65 | 66 | token = strtok(NULL, delims); 67 | } 68 | return NULL; 69 | } 70 | 71 | /* Init mounts /system as read only, remount to enable writes. */ 72 | static int remount_system() 73 | { 74 | char *dev; 75 | 76 | if (system_ro == 0) { 77 | return 0; 78 | } 79 | 80 | dev = find_mount("/system"); 81 | 82 | if (!dev) 83 | return -1; 84 | 85 | system_ro = mount(dev, "/system", "none", MS_REMOUNT, NULL); 86 | 87 | free(dev); 88 | 89 | return system_ro; 90 | } 91 | 92 | static void write_string(int fd, const char* str) 93 | { 94 | writex(fd, str, strlen(str)); 95 | } 96 | 97 | void remount_service(int fd, void *cookie) 98 | { 99 | int ret = remount_system(); 100 | 101 | if (!ret) 102 | write_string(fd, "remount succeeded\n"); 103 | else { 104 | char buffer[200]; 105 | snprintf(buffer, sizeof(buffer), "remount failed: %s\n", strerror(errno)); 106 | write_string(fd, buffer); 107 | } 108 | 109 | adb_close(fd); 110 | } 111 | 112 | -------------------------------------------------------------------------------- /services.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "sysdeps.h" 24 | 25 | #define TRACE_TAG TRACE_SERVICES 26 | #include "adb.h" 27 | #include "file_sync_service.h" 28 | 29 | #if ADB_HOST 30 | # ifndef HAVE_WINSOCK 31 | # include 32 | # include 33 | # include 34 | # endif 35 | #else 36 | # include 37 | #endif 38 | 39 | typedef struct stinfo stinfo; 40 | 41 | struct stinfo { 42 | void (*func)(int fd, void *cookie); 43 | int fd; 44 | void *cookie; 45 | }; 46 | 47 | 48 | void *service_bootstrap_func(void *x) 49 | { 50 | stinfo *sti = x; 51 | sti->func(sti->fd, sti->cookie); 52 | free(sti); 53 | return 0; 54 | } 55 | 56 | #if ADB_HOST 57 | ADB_MUTEX_DEFINE( dns_lock ); 58 | 59 | static void dns_service(int fd, void *cookie) 60 | { 61 | char *hostname = cookie; 62 | struct hostent *hp; 63 | unsigned zero = 0; 64 | 65 | adb_mutex_lock(&dns_lock); 66 | hp = gethostbyname(hostname); 67 | free(cookie); 68 | if(hp == 0) { 69 | writex(fd, &zero, 4); 70 | } else { 71 | writex(fd, hp->h_addr, 4); 72 | } 73 | adb_mutex_unlock(&dns_lock); 74 | adb_close(fd); 75 | } 76 | #else 77 | extern int recovery_mode; 78 | 79 | static void recover_service(int s, void *cookie) 80 | { 81 | unsigned char buf[4096]; 82 | unsigned count = (intptr_t) cookie; 83 | int fd; 84 | 85 | fd = adb_creat("/tmp/update", 0644); 86 | if(fd < 0) { 87 | adb_close(s); 88 | return; 89 | } 90 | 91 | while(count > 0) { 92 | unsigned xfer = (count > 4096) ? 4096 : count; 93 | if(readx(s, buf, xfer)) break; 94 | if(writex(fd, buf, xfer)) break; 95 | count -= xfer; 96 | } 97 | 98 | if(count == 0) { 99 | writex(s, "OKAY", 4); 100 | } else { 101 | writex(s, "FAIL", 4); 102 | } 103 | adb_close(fd); 104 | adb_close(s); 105 | 106 | fd = adb_creat("/tmp/update.begin", 0644); 107 | adb_close(fd); 108 | } 109 | 110 | void restart_root_service(int fd, void *cookie) 111 | { 112 | char buf[100]; 113 | char value[PROPERTY_VALUE_MAX]; 114 | char build_type[PROPERTY_VALUE_MAX]; 115 | char cm_version[PROPERTY_VALUE_MAX]; 116 | 117 | if (getuid() == 0) { 118 | snprintf(buf, sizeof(buf), "adbd is already running as root\n"); 119 | writex(fd, buf, strlen(buf)); 120 | adb_close(fd); 121 | } else { 122 | property_get("ro.debuggable", value, ""); 123 | if (strcmp(value, "1") != 0) { 124 | snprintf(buf, sizeof(buf), "adbd cannot run as root in production builds\n"); 125 | writex(fd, buf, strlen(buf)); 126 | adb_close(fd); 127 | return; 128 | } 129 | 130 | property_get("persist.sys.root_access", value, "1"); 131 | property_get("ro.build.type", build_type, ""); 132 | property_get("ro.cm.version", cm_version, ""); 133 | 134 | if (strlen(cm_version) > 0 && strcmp(build_type, "eng") != 0 && (atoi(value) & 2) != 2) { 135 | snprintf(buf, sizeof(buf), "root access is disabled by system setting - enable in settings -> development options\n"); 136 | writex(fd, buf, strlen(buf)); 137 | adb_close(fd); 138 | return; 139 | } 140 | 141 | property_set("service.adb.root", "1"); 142 | snprintf(buf, sizeof(buf), "restarting adbd as root\n"); 143 | writex(fd, buf, strlen(buf)); 144 | adb_close(fd); 145 | } 146 | } 147 | 148 | void restart_tcp_service(int fd, void *cookie) 149 | { 150 | char buf[100]; 151 | char value[PROPERTY_VALUE_MAX]; 152 | int port = (intptr_t)cookie; 153 | 154 | if (port <= 0) { 155 | snprintf(buf, sizeof(buf), "invalid port\n"); 156 | writex(fd, buf, strlen(buf)); 157 | adb_close(fd); 158 | return; 159 | } 160 | 161 | snprintf(value, sizeof(value), "%d", port); 162 | property_set("service.adb.tcp.port", value); 163 | snprintf(buf, sizeof(buf), "restarting in TCP mode port: %d\n", port); 164 | writex(fd, buf, strlen(buf)); 165 | adb_close(fd); 166 | } 167 | 168 | void restart_usb_service(int fd, void *cookie) 169 | { 170 | char buf[100]; 171 | 172 | property_set("service.adb.tcp.port", "0"); 173 | snprintf(buf, sizeof(buf), "restarting in USB mode\n"); 174 | writex(fd, buf, strlen(buf)); 175 | adb_close(fd); 176 | } 177 | 178 | void reboot_service(int fd, void *arg) 179 | { 180 | char buf[100]; 181 | int pid, ret; 182 | 183 | sync(); 184 | 185 | /* Attempt to unmount the SD card first. 186 | * No need to bother checking for errors. 187 | */ 188 | pid = fork(); 189 | if (pid == 0) { 190 | /* ask vdc to unmount it */ 191 | execl("/system/bin/vdc", "/system/bin/vdc", "volume", "unmount", 192 | getenv("EXTERNAL_STORAGE"), "force", NULL); 193 | } else if (pid > 0) { 194 | /* wait until vdc succeeds or fails */ 195 | waitpid(pid, &ret, 0); 196 | } 197 | 198 | ret = android_reboot(ANDROID_RB_RESTART2, 0, (char *) arg); 199 | if (ret < 0) { 200 | snprintf(buf, sizeof(buf), "reboot failed: %s\n", strerror(errno)); 201 | writex(fd, buf, strlen(buf)); 202 | } 203 | free(arg); 204 | adb_close(fd); 205 | } 206 | 207 | #endif 208 | 209 | #if 0 210 | static void echo_service(int fd, void *cookie) 211 | { 212 | char buf[4096]; 213 | int r; 214 | char *p; 215 | int c; 216 | 217 | for(;;) { 218 | r = read(fd, buf, 4096); 219 | if(r == 0) goto done; 220 | if(r < 0) { 221 | if(errno == EINTR) continue; 222 | else goto done; 223 | } 224 | 225 | c = r; 226 | p = buf; 227 | while(c > 0) { 228 | r = write(fd, p, c); 229 | if(r > 0) { 230 | c -= r; 231 | p += r; 232 | continue; 233 | } 234 | if((r < 0) && (errno == EINTR)) continue; 235 | goto done; 236 | } 237 | } 238 | done: 239 | close(fd); 240 | } 241 | #endif 242 | 243 | static int create_service_thread(void (*func)(int, void *), void *cookie) 244 | { 245 | stinfo *sti; 246 | adb_thread_t t; 247 | int s[2]; 248 | 249 | if(adb_socketpair(s)) { 250 | printf("cannot create service socket pair\n"); 251 | return -1; 252 | } 253 | 254 | sti = malloc(sizeof(stinfo)); 255 | if(sti == 0) fatal("cannot allocate stinfo"); 256 | sti->func = func; 257 | sti->cookie = cookie; 258 | sti->fd = s[1]; 259 | 260 | if(adb_thread_create( &t, service_bootstrap_func, sti)){ 261 | free(sti); 262 | adb_close(s[0]); 263 | adb_close(s[1]); 264 | printf("cannot create service thread\n"); 265 | return -1; 266 | } 267 | 268 | D("service thread started, %d:%d\n",s[0], s[1]); 269 | return s[0]; 270 | } 271 | 272 | #if !ADB_HOST 273 | static int create_subprocess(const char *cmd, const char *arg0, const char *arg1, pid_t *pid) 274 | { 275 | #ifdef HAVE_WIN32_PROC 276 | D("create_subprocess(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1); 277 | fprintf(stderr, "error: create_subprocess not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1); 278 | return -1; 279 | #else /* !HAVE_WIN32_PROC */ 280 | char *devname; 281 | int ptm; 282 | 283 | ptm = unix_open("/dev/ptmx", O_RDWR); // | O_NOCTTY); 284 | if(ptm < 0){ 285 | printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno)); 286 | return -1; 287 | } 288 | fcntl(ptm, F_SETFD, FD_CLOEXEC); 289 | 290 | if(grantpt(ptm) || unlockpt(ptm) || 291 | ((devname = (char*) ptsname(ptm)) == 0)){ 292 | printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno)); 293 | adb_close(ptm); 294 | return -1; 295 | } 296 | 297 | *pid = fork(); 298 | if(*pid < 0) { 299 | printf("- fork failed: %s -\n", strerror(errno)); 300 | adb_close(ptm); 301 | return -1; 302 | } 303 | 304 | if(*pid == 0){ 305 | int pts; 306 | 307 | setsid(); 308 | 309 | pts = unix_open(devname, O_RDWR); 310 | if(pts < 0) { 311 | fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname); 312 | exit(-1); 313 | } 314 | 315 | dup2(pts, 0); 316 | dup2(pts, 1); 317 | dup2(pts, 2); 318 | 319 | adb_close(pts); 320 | adb_close(ptm); 321 | 322 | // set OOM adjustment to zero 323 | char text[64]; 324 | snprintf(text, sizeof text, "/proc/%d/oom_adj", getpid()); 325 | int fd = adb_open(text, O_WRONLY); 326 | if (fd >= 0) { 327 | adb_write(fd, "0", 1); 328 | adb_close(fd); 329 | } else { 330 | D("adb: unable to open %s\n", text); 331 | } 332 | execl(cmd, cmd, arg0, arg1, NULL); 333 | fprintf(stderr, "- exec '%s' failed: %s (%d) -\n", 334 | cmd, strerror(errno), errno); 335 | exit(-1); 336 | } else { 337 | // Don't set child's OOM adjustment to zero. 338 | // Let the child do it itself, as sometimes the parent starts 339 | // running before the child has a /proc/pid/oom_adj. 340 | // """adb: unable to open /proc/644/oom_adj""" seen in some logs. 341 | return ptm; 342 | } 343 | #endif /* !HAVE_WIN32_PROC */ 344 | } 345 | #endif /* !ABD_HOST */ 346 | 347 | #if ADB_HOST 348 | #define SHELL_COMMAND "/bin/sh" 349 | #define ALTERNATE_SHELL_COMMAND "" 350 | #else 351 | //#define SHELL_COMMAND "/system/bin/sh" 352 | #define SHELL_COMMAND "/mrom_bin/sh" 353 | #define ALTERNATE_SHELL_COMMAND "/sbin/sh" 354 | #endif 355 | 356 | #if !ADB_HOST 357 | static void subproc_waiter_service(int fd, void *cookie) 358 | { 359 | pid_t pid = (intptr_t)cookie; 360 | 361 | D("entered. fd=%d of pid=%d\n", fd, pid); 362 | for (;;) { 363 | int status; 364 | pid_t p = waitpid(pid, &status, 0); 365 | if (p == pid) { 366 | D("fd=%d, post waitpid(pid=%d) status=%04x\n", fd, p, status); 367 | if (WIFSIGNALED(status)) { 368 | D("*** Killed by signal %d\n", WTERMSIG(status)); 369 | break; 370 | } else if (!WIFEXITED(status)) { 371 | D("*** Didn't exit!!. status %d\n", status); 372 | break; 373 | } else if (WEXITSTATUS(status) >= 0) { 374 | D("*** Exit code %d\n", WEXITSTATUS(status)); 375 | break; 376 | } 377 | } 378 | } 379 | D("shell exited fd=%d of pid=%d err=%d\n", fd, pid, errno); 380 | if (SHELL_EXIT_NOTIFY_FD >=0) { 381 | int res; 382 | res = writex(SHELL_EXIT_NOTIFY_FD, &fd, sizeof(fd)); 383 | D("notified shell exit via fd=%d for pid=%d res=%d errno=%d\n", 384 | SHELL_EXIT_NOTIFY_FD, pid, res, errno); 385 | } 386 | } 387 | 388 | static int create_subproc_thread(const char *name) 389 | { 390 | stinfo *sti; 391 | adb_thread_t t; 392 | int ret_fd; 393 | pid_t pid; 394 | const char* shell_command; 395 | struct stat filecheck; 396 | if (stat(ALTERNATE_SHELL_COMMAND, &filecheck) == 0) { 397 | shell_command = ALTERNATE_SHELL_COMMAND; 398 | } 399 | else { 400 | shell_command = SHELL_COMMAND; 401 | } 402 | 403 | if(name) { 404 | ret_fd = create_subprocess(shell_command, "-c", name, &pid); 405 | } else { 406 | ret_fd = create_subprocess(shell_command, "-", 0, &pid); 407 | } 408 | D("create_subprocess() ret_fd=%d pid=%d\n", ret_fd, pid); 409 | 410 | sti = malloc(sizeof(stinfo)); 411 | if(sti == 0) fatal("cannot allocate stinfo"); 412 | sti->func = subproc_waiter_service; 413 | sti->cookie = (void*)((intptr_t)pid); 414 | sti->fd = ret_fd; 415 | 416 | if(adb_thread_create( &t, service_bootstrap_func, sti)){ 417 | free(sti); 418 | adb_close(ret_fd); 419 | printf("cannot create service thread\n"); 420 | return -1; 421 | } 422 | 423 | D("service thread started, fd=%d pid=%d\n",ret_fd, pid); 424 | return ret_fd; 425 | } 426 | #endif 427 | 428 | int service_to_fd(const char *name) 429 | { 430 | int ret = -1; 431 | 432 | if(!strncmp(name, "tcp:", 4)) { 433 | int port = atoi(name + 4); 434 | name = strchr(name + 4, ':'); 435 | if(name == 0) { 436 | ret = socket_loopback_client(port, SOCK_STREAM); 437 | if (ret >= 0) 438 | disable_tcp_nagle(ret); 439 | } else { 440 | #if ADB_HOST 441 | adb_mutex_lock(&dns_lock); 442 | ret = socket_network_client(name + 1, port, SOCK_STREAM); 443 | adb_mutex_unlock(&dns_lock); 444 | #else 445 | return -1; 446 | #endif 447 | } 448 | #ifndef HAVE_WINSOCK /* winsock doesn't implement unix domain sockets */ 449 | } else if(!strncmp(name, "local:", 6)) { 450 | ret = socket_local_client(name + 6, 451 | ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); 452 | } else if(!strncmp(name, "localreserved:", 14)) { 453 | ret = socket_local_client(name + 14, 454 | ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); 455 | } else if(!strncmp(name, "localabstract:", 14)) { 456 | ret = socket_local_client(name + 14, 457 | ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); 458 | } else if(!strncmp(name, "localfilesystem:", 16)) { 459 | ret = socket_local_client(name + 16, 460 | ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM); 461 | #endif 462 | #if ADB_HOST 463 | } else if(!strncmp("dns:", name, 4)){ 464 | char *n = strdup(name + 4); 465 | if(n == 0) return -1; 466 | ret = create_service_thread(dns_service, n); 467 | #else /* !ADB_HOST */ 468 | } else if(!strncmp("dev:", name, 4)) { 469 | ret = unix_open(name + 4, O_RDWR); 470 | } else if(!strncmp(name, "framebuffer:", 12)) { 471 | ret = create_service_thread(framebuffer_service, 0); 472 | } else if(recovery_mode && !strncmp(name, "recover:", 8)) { 473 | ret = create_service_thread(recover_service, (void*) ((intptr_t)(atoi(name + 8)))); 474 | } else if (!strncmp(name, "jdwp:", 5)) { 475 | ret = create_jdwp_connection_fd(atoi(name+5)); 476 | } else if (!strncmp(name, "log:", 4)) { 477 | ret = create_service_thread(log_service, get_log_file_path(name + 4)); 478 | } else if(!HOST && !strncmp(name, "shell:", 6)) { 479 | if(name[6]) { 480 | ret = create_subproc_thread(name + 6); 481 | } else { 482 | ret = create_subproc_thread(0); 483 | } 484 | } else if(!strncmp(name, "sync:", 5)) { 485 | ret = create_service_thread(file_sync_service, NULL); 486 | } else if(!strncmp(name, "remount:", 8)) { 487 | ret = create_service_thread(remount_service, NULL); 488 | } else if(!strncmp(name, "reboot:", 7)) { 489 | void* arg = strdup(name + 7); 490 | if(arg == 0) return -1; 491 | ret = create_service_thread(reboot_service, arg); 492 | } else if(!strncmp(name, "root:", 5)) { 493 | ret = create_service_thread(restart_root_service, NULL); 494 | } else if(!strncmp(name, "backup:", 7)) { 495 | char* arg = strdup(name+7); 496 | if (arg == NULL) return -1; 497 | ret = backup_service(BACKUP, arg); 498 | } else if(!strncmp(name, "restore:", 8)) { 499 | ret = backup_service(RESTORE, NULL); 500 | } else if(!strncmp(name, "tcpip:", 6)) { 501 | int port; 502 | if (sscanf(name + 6, "%d", &port) == 0) { 503 | port = 0; 504 | } 505 | ret = create_service_thread(restart_tcp_service, (void *) ((intptr_t)port)); 506 | } else if(!strncmp(name, "usb:", 4)) { 507 | ret = create_service_thread(restart_usb_service, NULL); 508 | #endif 509 | #if 0 510 | } else if(!strncmp(name, "echo:", 5)){ 511 | ret = create_service_thread(echo_service, 0); 512 | #endif 513 | } 514 | if (ret >= 0) { 515 | close_on_exec(ret); 516 | } 517 | return ret; 518 | } 519 | 520 | #if ADB_HOST 521 | struct state_info { 522 | transport_type transport; 523 | char* serial; 524 | int state; 525 | }; 526 | 527 | static void wait_for_state(int fd, void* cookie) 528 | { 529 | struct state_info* sinfo = cookie; 530 | char* err = "unknown error"; 531 | 532 | D("wait_for_state %d\n", sinfo->state); 533 | 534 | atransport *t = acquire_one_transport(sinfo->state, sinfo->transport, sinfo->serial, &err); 535 | if(t != 0) { 536 | writex(fd, "OKAY", 4); 537 | } else { 538 | sendfailmsg(fd, err); 539 | } 540 | 541 | if (sinfo->serial) 542 | free(sinfo->serial); 543 | free(sinfo); 544 | adb_close(fd); 545 | D("wait_for_state is done\n"); 546 | } 547 | #endif 548 | 549 | #if ADB_HOST 550 | asocket* host_service_to_socket(const char* name, const char *serial) 551 | { 552 | if (!strcmp(name,"track-devices")) { 553 | return create_device_tracker(); 554 | } else if (!strncmp(name, "wait-for-", strlen("wait-for-"))) { 555 | struct state_info* sinfo = malloc(sizeof(struct state_info)); 556 | 557 | if (serial) 558 | sinfo->serial = strdup(serial); 559 | else 560 | sinfo->serial = NULL; 561 | 562 | name += strlen("wait-for-"); 563 | 564 | if (!strncmp(name, "local", strlen("local"))) { 565 | sinfo->transport = kTransportLocal; 566 | sinfo->state = CS_DEVICE; 567 | } else if (!strncmp(name, "usb", strlen("usb"))) { 568 | sinfo->transport = kTransportUsb; 569 | sinfo->state = CS_DEVICE; 570 | } else if (!strncmp(name, "any", strlen("any"))) { 571 | sinfo->transport = kTransportAny; 572 | sinfo->state = CS_DEVICE; 573 | } else { 574 | free(sinfo); 575 | return NULL; 576 | } 577 | 578 | int fd = create_service_thread(wait_for_state, sinfo); 579 | return create_local_socket(fd); 580 | } 581 | return NULL; 582 | } 583 | #endif /* ADB_HOST */ 584 | -------------------------------------------------------------------------------- /sockets.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tasssadar/multirom_adbd/6db99f070766bc948e2b405cd52aa1e61ddd55bb/sockets.dia -------------------------------------------------------------------------------- /sysdeps.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* this file contains system-dependent definitions used by ADB 18 | * they're related to threads, sockets and file descriptors 19 | */ 20 | #ifndef _ADB_SYSDEPS_H 21 | #define _ADB_SYSDEPS_H 22 | 23 | #ifdef __CYGWIN__ 24 | # undef _WIN32 25 | #endif 26 | 27 | #ifdef _WIN32 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #define OS_PATH_SEPARATOR '\\' 40 | #define OS_PATH_SEPARATOR_STR "\\" 41 | 42 | typedef CRITICAL_SECTION adb_mutex_t; 43 | 44 | #define ADB_MUTEX_DEFINE(x) adb_mutex_t x 45 | 46 | /* declare all mutexes */ 47 | /* For win32, adb_sysdeps_init() will do the mutex runtime initialization. */ 48 | #define ADB_MUTEX(x) extern adb_mutex_t x; 49 | #include "mutex_list.h" 50 | 51 | extern void adb_sysdeps_init(void); 52 | 53 | static __inline__ void adb_mutex_lock( adb_mutex_t* lock ) 54 | { 55 | EnterCriticalSection( lock ); 56 | } 57 | 58 | static __inline__ void adb_mutex_unlock( adb_mutex_t* lock ) 59 | { 60 | LeaveCriticalSection( lock ); 61 | } 62 | 63 | typedef struct { unsigned tid; } adb_thread_t; 64 | 65 | typedef void* (*adb_thread_func_t)(void* arg); 66 | 67 | typedef void (*win_thread_func_t)(void* arg); 68 | 69 | static __inline__ int adb_thread_create( adb_thread_t *thread, adb_thread_func_t func, void* arg) 70 | { 71 | thread->tid = _beginthread( (win_thread_func_t)func, 0, arg ); 72 | if (thread->tid == (unsigned)-1L) { 73 | return -1; 74 | } 75 | return 0; 76 | } 77 | 78 | static __inline__ void close_on_exec(int fd) 79 | { 80 | /* nothing really */ 81 | } 82 | 83 | extern void disable_tcp_nagle(int fd); 84 | 85 | #define lstat stat /* no symlinks on Win32 */ 86 | 87 | #define S_ISLNK(m) 0 /* no symlinks on Win32 */ 88 | 89 | static __inline__ int adb_unlink(const char* path) 90 | { 91 | int rc = unlink(path); 92 | 93 | if (rc == -1 && errno == EACCES) { 94 | /* unlink returns EACCES when the file is read-only, so we first */ 95 | /* try to make it writable, then unlink again... */ 96 | rc = chmod(path, _S_IREAD|_S_IWRITE ); 97 | if (rc == 0) 98 | rc = unlink(path); 99 | } 100 | return rc; 101 | } 102 | #undef unlink 103 | #define unlink ___xxx_unlink 104 | 105 | static __inline__ int adb_mkdir(const char* path, int mode) 106 | { 107 | return _mkdir(path); 108 | } 109 | #undef mkdir 110 | #define mkdir ___xxx_mkdir 111 | 112 | extern int adb_open(const char* path, int options); 113 | extern int adb_creat(const char* path, int mode); 114 | extern int adb_read(int fd, void* buf, int len); 115 | extern int adb_write(int fd, const void* buf, int len); 116 | extern int adb_lseek(int fd, int pos, int where); 117 | extern int adb_shutdown(int fd); 118 | extern int adb_close(int fd); 119 | 120 | static __inline__ int unix_close(int fd) 121 | { 122 | return close(fd); 123 | } 124 | #undef close 125 | #define close ____xxx_close 126 | 127 | static __inline__ int unix_read(int fd, void* buf, size_t len) 128 | { 129 | return read(fd, buf, len); 130 | } 131 | #undef read 132 | #define read ___xxx_read 133 | 134 | static __inline__ int unix_write(int fd, const void* buf, size_t len) 135 | { 136 | return write(fd, buf, len); 137 | } 138 | #undef write 139 | #define write ___xxx_write 140 | 141 | static __inline__ int adb_open_mode(const char* path, int options, int mode) 142 | { 143 | return adb_open(path, options); 144 | } 145 | 146 | static __inline__ int unix_open(const char* path, int options,...) 147 | { 148 | if ((options & O_CREAT) == 0) 149 | { 150 | return open(path, options); 151 | } 152 | else 153 | { 154 | int mode; 155 | va_list args; 156 | va_start( args, options ); 157 | mode = va_arg( args, int ); 158 | va_end( args ); 159 | return open(path, options, mode); 160 | } 161 | } 162 | #define open ___xxx_unix_open 163 | 164 | 165 | /* normally provided by */ 166 | extern void* load_file(const char* pathname, unsigned* psize); 167 | 168 | /* normally provided by */ 169 | extern int socket_loopback_client(int port, int type); 170 | extern int socket_network_client(const char *host, int port, int type); 171 | extern int socket_loopback_server(int port, int type); 172 | extern int socket_inaddr_any_server(int port, int type); 173 | 174 | /* normally provided by "fdevent.h" */ 175 | 176 | #define FDE_READ 0x0001 177 | #define FDE_WRITE 0x0002 178 | #define FDE_ERROR 0x0004 179 | #define FDE_DONT_CLOSE 0x0080 180 | 181 | typedef struct fdevent fdevent; 182 | 183 | typedef void (*fd_func)(int fd, unsigned events, void *userdata); 184 | 185 | fdevent *fdevent_create(int fd, fd_func func, void *arg); 186 | void fdevent_destroy(fdevent *fde); 187 | void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg); 188 | void fdevent_remove(fdevent *item); 189 | void fdevent_set(fdevent *fde, unsigned events); 190 | void fdevent_add(fdevent *fde, unsigned events); 191 | void fdevent_del(fdevent *fde, unsigned events); 192 | void fdevent_loop(); 193 | 194 | struct fdevent { 195 | fdevent *next; 196 | fdevent *prev; 197 | 198 | int fd; 199 | int force_eof; 200 | 201 | unsigned short state; 202 | unsigned short events; 203 | 204 | fd_func func; 205 | void *arg; 206 | }; 207 | 208 | static __inline__ void adb_sleep_ms( int mseconds ) 209 | { 210 | Sleep( mseconds ); 211 | } 212 | 213 | extern int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t *addrlen); 214 | 215 | #undef accept 216 | #define accept ___xxx_accept 217 | 218 | static __inline__ int adb_socket_setbufsize( int fd, int bufsize ) 219 | { 220 | int opt = bufsize; 221 | return setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const char*)&opt, sizeof(opt)); 222 | } 223 | 224 | extern int adb_socketpair( int sv[2] ); 225 | 226 | static __inline__ char* adb_dirstart( const char* path ) 227 | { 228 | char* p = strchr(path, '/'); 229 | char* p2 = strchr(path, '\\'); 230 | 231 | if ( !p ) 232 | p = p2; 233 | else if ( p2 && p2 > p ) 234 | p = p2; 235 | 236 | return p; 237 | } 238 | 239 | static __inline__ char* adb_dirstop( const char* path ) 240 | { 241 | char* p = strrchr(path, '/'); 242 | char* p2 = strrchr(path, '\\'); 243 | 244 | if ( !p ) 245 | p = p2; 246 | else if ( p2 && p2 > p ) 247 | p = p2; 248 | 249 | return p; 250 | } 251 | 252 | static __inline__ int adb_is_absolute_host_path( const char* path ) 253 | { 254 | return isalpha(path[0]) && path[1] == ':' && path[2] == '\\'; 255 | } 256 | 257 | #else /* !_WIN32 a.k.a. Unix */ 258 | 259 | #include "fdevent.h" 260 | #include 261 | #include 262 | #include 263 | #include 264 | #include 265 | #include 266 | #include 267 | 268 | #include 269 | #include 270 | #include 271 | #include 272 | #include 273 | #include 274 | #include 275 | 276 | #define OS_PATH_SEPARATOR '/' 277 | #define OS_PATH_SEPARATOR_STR "/" 278 | 279 | typedef pthread_mutex_t adb_mutex_t; 280 | 281 | #define ADB_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 282 | #define adb_mutex_init pthread_mutex_init 283 | #define adb_mutex_lock pthread_mutex_lock 284 | #define adb_mutex_unlock pthread_mutex_unlock 285 | #define adb_mutex_destroy pthread_mutex_destroy 286 | 287 | #define ADB_MUTEX_DEFINE(m) adb_mutex_t m = PTHREAD_MUTEX_INITIALIZER 288 | 289 | #define adb_cond_t pthread_cond_t 290 | #define adb_cond_init pthread_cond_init 291 | #define adb_cond_wait pthread_cond_wait 292 | #define adb_cond_broadcast pthread_cond_broadcast 293 | #define adb_cond_signal pthread_cond_signal 294 | #define adb_cond_destroy pthread_cond_destroy 295 | 296 | /* declare all mutexes */ 297 | #define ADB_MUTEX(x) extern adb_mutex_t x; 298 | #include "mutex_list.h" 299 | 300 | static __inline__ void close_on_exec(int fd) 301 | { 302 | fcntl( fd, F_SETFD, FD_CLOEXEC ); 303 | } 304 | 305 | static __inline__ int unix_open(const char* path, int options,...) 306 | { 307 | if ((options & O_CREAT) == 0) 308 | { 309 | return open(path, options); 310 | } 311 | else 312 | { 313 | int mode; 314 | va_list args; 315 | va_start( args, options ); 316 | mode = va_arg( args, int ); 317 | va_end( args ); 318 | return open(path, options, mode); 319 | } 320 | } 321 | 322 | static __inline__ int adb_open_mode( const char* pathname, int options, int mode ) 323 | { 324 | return open( pathname, options, mode ); 325 | } 326 | 327 | 328 | static __inline__ int adb_open( const char* pathname, int options ) 329 | { 330 | int fd = open( pathname, options ); 331 | if (fd < 0) 332 | return -1; 333 | close_on_exec( fd ); 334 | return fd; 335 | } 336 | #undef open 337 | #define open ___xxx_open 338 | 339 | static __inline__ int adb_shutdown(int fd) 340 | { 341 | return shutdown(fd, SHUT_RDWR); 342 | } 343 | #undef shutdown 344 | #define shutdown ____xxx_shutdown 345 | 346 | static __inline__ int adb_close(int fd) 347 | { 348 | return close(fd); 349 | } 350 | #undef close 351 | #define close ____xxx_close 352 | 353 | 354 | static __inline__ int adb_read(int fd, void* buf, size_t len) 355 | { 356 | return read(fd, buf, len); 357 | } 358 | 359 | #undef read 360 | #define read ___xxx_read 361 | 362 | static __inline__ int adb_write(int fd, const void* buf, size_t len) 363 | { 364 | return write(fd, buf, len); 365 | } 366 | #undef write 367 | #define write ___xxx_write 368 | 369 | static __inline__ int adb_lseek(int fd, int pos, int where) 370 | { 371 | return lseek(fd, pos, where); 372 | } 373 | #undef lseek 374 | #define lseek ___xxx_lseek 375 | 376 | static __inline__ int adb_unlink(const char* path) 377 | { 378 | return unlink(path); 379 | } 380 | #undef unlink 381 | #define unlink ___xxx_unlink 382 | 383 | static __inline__ int adb_creat(const char* path, int mode) 384 | { 385 | int fd = creat(path, mode); 386 | 387 | if ( fd < 0 ) 388 | return -1; 389 | 390 | close_on_exec(fd); 391 | return fd; 392 | } 393 | #undef creat 394 | #define creat ___xxx_creat 395 | 396 | static __inline__ int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t *addrlen) 397 | { 398 | int fd; 399 | 400 | fd = accept(serverfd, addr, addrlen); 401 | if (fd >= 0) 402 | close_on_exec(fd); 403 | 404 | return fd; 405 | } 406 | 407 | #undef accept 408 | #define accept ___xxx_accept 409 | 410 | #define unix_read adb_read 411 | #define unix_write adb_write 412 | #define unix_close adb_close 413 | 414 | typedef pthread_t adb_thread_t; 415 | 416 | typedef void* (*adb_thread_func_t)( void* arg ); 417 | 418 | static __inline__ int adb_thread_create( adb_thread_t *pthread, adb_thread_func_t start, void* arg ) 419 | { 420 | pthread_attr_t attr; 421 | 422 | pthread_attr_init (&attr); 423 | pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); 424 | 425 | return pthread_create( pthread, &attr, start, arg ); 426 | } 427 | 428 | static __inline__ int adb_socket_setbufsize( int fd, int bufsize ) 429 | { 430 | int opt = bufsize; 431 | return setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)); 432 | } 433 | 434 | static __inline__ void disable_tcp_nagle(int fd) 435 | { 436 | int on = 1; 437 | setsockopt( fd, IPPROTO_TCP, TCP_NODELAY, (void*)&on, sizeof(on) ); 438 | } 439 | 440 | 441 | static __inline__ int unix_socketpair( int d, int type, int protocol, int sv[2] ) 442 | { 443 | return socketpair( d, type, protocol, sv ); 444 | } 445 | 446 | static __inline__ int adb_socketpair( int sv[2] ) 447 | { 448 | int rc; 449 | 450 | rc = unix_socketpair( AF_UNIX, SOCK_STREAM, 0, sv ); 451 | if (rc < 0) 452 | return -1; 453 | 454 | close_on_exec( sv[0] ); 455 | close_on_exec( sv[1] ); 456 | return 0; 457 | } 458 | 459 | #undef socketpair 460 | #define socketpair ___xxx_socketpair 461 | 462 | static __inline__ void adb_sleep_ms( int mseconds ) 463 | { 464 | usleep( mseconds*1000 ); 465 | } 466 | 467 | static __inline__ int adb_mkdir(const char* path, int mode) 468 | { 469 | return mkdir(path, mode); 470 | } 471 | #undef mkdir 472 | #define mkdir ___xxx_mkdir 473 | 474 | static __inline__ void adb_sysdeps_init(void) 475 | { 476 | } 477 | 478 | static __inline__ char* adb_dirstart(const char* path) 479 | { 480 | return strchr(path, '/'); 481 | } 482 | 483 | static __inline__ char* adb_dirstop(const char* path) 484 | { 485 | return strrchr(path, '/'); 486 | } 487 | 488 | static __inline__ int adb_is_absolute_host_path( const char* path ) 489 | { 490 | return path[0] == '/'; 491 | } 492 | 493 | #endif /* !_WIN32 */ 494 | 495 | #endif /* _ADB_SYSDEPS_H */ 496 | -------------------------------------------------------------------------------- /test_track_devices.c: -------------------------------------------------------------------------------- 1 | /* a simple test program, connects to ADB server, and opens a track-devices session */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | static void 10 | panic( const char* msg ) 11 | { 12 | fprintf(stderr, "PANIC: %s: %s\n", msg, strerror(errno)); 13 | exit(1); 14 | } 15 | 16 | static int 17 | unix_write( int fd, const char* buf, int len ) 18 | { 19 | int result = 0; 20 | while (len > 0) { 21 | int len2 = write(fd, buf, len); 22 | if (len2 < 0) { 23 | if (errno == EINTR || errno == EAGAIN) 24 | continue; 25 | return -1; 26 | } 27 | result += len2; 28 | len -= len2; 29 | buf += len2; 30 | } 31 | return result; 32 | } 33 | 34 | static int 35 | unix_read( int fd, char* buf, int len ) 36 | { 37 | int result = 0; 38 | while (len > 0) { 39 | int len2 = read(fd, buf, len); 40 | if (len2 < 0) { 41 | if (errno == EINTR || errno == EAGAIN) 42 | continue; 43 | return -1; 44 | } 45 | result += len2; 46 | len -= len2; 47 | buf += len2; 48 | } 49 | return result; 50 | } 51 | 52 | 53 | int main( void ) 54 | { 55 | int ret, s; 56 | struct sockaddr_in server; 57 | char buffer[1024]; 58 | const char* request = "host:track-devices"; 59 | int len; 60 | 61 | memset( &server, 0, sizeof(server) ); 62 | server.sin_family = AF_INET; 63 | server.sin_port = htons(5037); 64 | server.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 65 | 66 | s = socket( PF_INET, SOCK_STREAM, 0 ); 67 | ret = connect( s, (struct sockaddr*) &server, sizeof(server) ); 68 | if (ret < 0) panic( "could not connect to server" ); 69 | 70 | /* send the request */ 71 | len = snprintf( buffer, sizeof buffer, "%04x%s", strlen(request), request ); 72 | if (unix_write(s, buffer, len) < 0) 73 | panic( "could not send request" ); 74 | 75 | /* read the OKAY answer */ 76 | if (unix_read(s, buffer, 4) != 4) 77 | panic( "could not read request" ); 78 | 79 | printf( "server answer: %.*s\n", 4, buffer ); 80 | 81 | /* now loop */ 82 | for (;;) { 83 | char head[5] = "0000"; 84 | 85 | if (unix_read(s, head, 4) < 0) 86 | panic("could not read length"); 87 | 88 | if ( sscanf( head, "%04x", &len ) != 1 ) 89 | panic("could not decode length"); 90 | 91 | if (unix_read(s, buffer, len) != len) 92 | panic("could not read data"); 93 | 94 | printf( "received header %.*s (%d bytes):\n%.*s", 4, head, len, len, buffer ); 95 | } 96 | close(s); 97 | } 98 | -------------------------------------------------------------------------------- /test_track_jdwp.c: -------------------------------------------------------------------------------- 1 | /* a simple test program, connects to ADB server, and opens a track-devices session */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | static void 10 | panic( const char* msg ) 11 | { 12 | fprintf(stderr, "PANIC: %s: %s\n", msg, strerror(errno)); 13 | exit(1); 14 | } 15 | 16 | static int 17 | unix_write( int fd, const char* buf, int len ) 18 | { 19 | int result = 0; 20 | while (len > 0) { 21 | int len2 = write(fd, buf, len); 22 | if (len2 < 0) { 23 | if (errno == EINTR || errno == EAGAIN) 24 | continue; 25 | return -1; 26 | } 27 | result += len2; 28 | len -= len2; 29 | buf += len2; 30 | } 31 | return result; 32 | } 33 | 34 | static int 35 | unix_read( int fd, char* buf, int len ) 36 | { 37 | int result = 0; 38 | while (len > 0) { 39 | int len2 = read(fd, buf, len); 40 | if (len2 < 0) { 41 | if (errno == EINTR || errno == EAGAIN) 42 | continue; 43 | return -1; 44 | } 45 | result += len2; 46 | len -= len2; 47 | buf += len2; 48 | } 49 | return result; 50 | } 51 | 52 | 53 | int main( void ) 54 | { 55 | int ret, s; 56 | struct sockaddr_in server; 57 | char buffer[1024]; 58 | const char* request = "track-jdwp"; 59 | int len; 60 | 61 | memset( &server, 0, sizeof(server) ); 62 | server.sin_family = AF_INET; 63 | server.sin_port = htons(5037); 64 | server.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 65 | 66 | s = socket( PF_INET, SOCK_STREAM, 0 ); 67 | ret = connect( s, (struct sockaddr*) &server, sizeof(server) ); 68 | if (ret < 0) panic( "could not connect to server" ); 69 | 70 | /* send the request */ 71 | len = snprintf( buffer, sizeof buffer, "%04x%s", strlen(request), request ); 72 | if (unix_write(s, buffer, len) < 0) 73 | panic( "could not send request" ); 74 | 75 | /* read the OKAY answer */ 76 | if (unix_read(s, buffer, 4) != 4) 77 | panic( "could not read request" ); 78 | 79 | printf( "server answer: %.*s\n", 4, buffer ); 80 | 81 | /* now loop */ 82 | for (;;) { 83 | char head[5] = "0000"; 84 | 85 | if (unix_read(s, head, 4) < 0) 86 | panic("could not read length"); 87 | 88 | if ( sscanf( head, "%04x", &len ) != 1 ) 89 | panic("could not decode length"); 90 | 91 | if (unix_read(s, buffer, len) != len) 92 | panic("could not read data"); 93 | 94 | printf( "received header %.*s (%d bytes):\n%.*s", 4, head, len, len, buffer ); 95 | } 96 | close(s); 97 | } 98 | -------------------------------------------------------------------------------- /transport.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __TRANSPORT_H 18 | #define __TRANSPORT_H 19 | 20 | /* convenience wrappers around read/write that will retry on 21 | ** EINTR and/or short read/write. Returns 0 on success, -1 22 | ** on error or EOF. 23 | */ 24 | int readx(int fd, void *ptr, size_t len); 25 | int writex(int fd, const void *ptr, size_t len); 26 | #endif /* __TRANSPORT_H */ 27 | -------------------------------------------------------------------------------- /transport_local.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "sysdeps.h" 23 | #include 24 | 25 | #define TRACE_TAG TRACE_TRANSPORT 26 | #include "adb.h" 27 | 28 | #ifdef HAVE_BIG_ENDIAN 29 | #define H4(x) (((x) & 0xFF000000) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | (((x) & 0x000000FF) << 24) 30 | static inline void fix_endians(apacket *p) 31 | { 32 | p->msg.command = H4(p->msg.command); 33 | p->msg.arg0 = H4(p->msg.arg0); 34 | p->msg.arg1 = H4(p->msg.arg1); 35 | p->msg.data_length = H4(p->msg.data_length); 36 | p->msg.data_check = H4(p->msg.data_check); 37 | p->msg.magic = H4(p->msg.magic); 38 | } 39 | #else 40 | #define fix_endians(p) do {} while (0) 41 | #endif 42 | 43 | #if ADB_HOST 44 | /* we keep a list of opened transports. The atransport struct knows to which 45 | * local transport it is connected. The list is used to detect when we're 46 | * trying to connect twice to a given local transport. 47 | */ 48 | #define ADB_LOCAL_TRANSPORT_MAX 16 49 | 50 | ADB_MUTEX_DEFINE( local_transports_lock ); 51 | 52 | static atransport* local_transports[ ADB_LOCAL_TRANSPORT_MAX ]; 53 | #endif /* ADB_HOST */ 54 | 55 | static int remote_read(apacket *p, atransport *t) 56 | { 57 | if(readx(t->sfd, &p->msg, sizeof(amessage))){ 58 | D("remote local: read terminated (message)\n"); 59 | return -1; 60 | } 61 | 62 | fix_endians(p); 63 | 64 | #if 0 && defined HAVE_BIG_ENDIAN 65 | D("read remote packet: %04x arg0=%0x arg1=%0x data_length=%0x data_check=%0x magic=%0x\n", 66 | p->msg.command, p->msg.arg0, p->msg.arg1, p->msg.data_length, p->msg.data_check, p->msg.magic); 67 | #endif 68 | if(check_header(p)) { 69 | D("bad header: terminated (data)\n"); 70 | return -1; 71 | } 72 | 73 | if(readx(t->sfd, p->data, p->msg.data_length)){ 74 | D("remote local: terminated (data)\n"); 75 | return -1; 76 | } 77 | 78 | if(check_data(p)) { 79 | D("bad data: terminated (data)\n"); 80 | return -1; 81 | } 82 | 83 | return 0; 84 | } 85 | 86 | static int remote_write(apacket *p, atransport *t) 87 | { 88 | int length = p->msg.data_length; 89 | 90 | fix_endians(p); 91 | 92 | #if 0 && defined HAVE_BIG_ENDIAN 93 | D("write remote packet: %04x arg0=%0x arg1=%0x data_length=%0x data_check=%0x magic=%0x\n", 94 | p->msg.command, p->msg.arg0, p->msg.arg1, p->msg.data_length, p->msg.data_check, p->msg.magic); 95 | #endif 96 | if(writex(t->sfd, &p->msg, sizeof(amessage) + length)) { 97 | D("remote local: write terminated\n"); 98 | return -1; 99 | } 100 | 101 | return 0; 102 | } 103 | 104 | 105 | int local_connect(int port) { 106 | return local_connect_arbitrary_ports(port-1, port); 107 | } 108 | 109 | int local_connect_arbitrary_ports(int console_port, int adb_port) 110 | { 111 | char buf[64]; 112 | int fd = -1; 113 | 114 | #if ADB_HOST 115 | const char *host = getenv("ADBHOST"); 116 | if (host) { 117 | fd = socket_network_client(host, adb_port, SOCK_STREAM); 118 | } 119 | #endif 120 | if (fd < 0) { 121 | fd = socket_loopback_client(adb_port, SOCK_STREAM); 122 | } 123 | 124 | if (fd >= 0) { 125 | D("client: connected on remote on fd %d\n", fd); 126 | close_on_exec(fd); 127 | disable_tcp_nagle(fd); 128 | snprintf(buf, sizeof buf, "%s%d", LOCAL_CLIENT_PREFIX, console_port); 129 | register_socket_transport(fd, buf, adb_port, 1); 130 | return 0; 131 | } 132 | return -1; 133 | } 134 | 135 | 136 | static void *client_socket_thread(void *x) 137 | { 138 | #if ADB_HOST 139 | int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; 140 | int count = ADB_LOCAL_TRANSPORT_MAX; 141 | 142 | D("transport: client_socket_thread() starting\n"); 143 | 144 | /* try to connect to any number of running emulator instances */ 145 | /* this is only done when ADB starts up. later, each new emulator */ 146 | /* will send a message to ADB to indicate that is is starting up */ 147 | for ( ; count > 0; count--, port += 2 ) { 148 | (void) local_connect(port); 149 | } 150 | #endif 151 | return 0; 152 | } 153 | 154 | static void *server_socket_thread(void * arg) 155 | { 156 | int serverfd, fd; 157 | struct sockaddr addr; 158 | socklen_t alen; 159 | int port = (intptr_t)arg; 160 | 161 | D("transport: server_socket_thread() starting\n"); 162 | serverfd = -1; 163 | for(;;) { 164 | if(serverfd == -1) { 165 | serverfd = socket_inaddr_any_server(port, SOCK_STREAM); 166 | if(serverfd < 0) { 167 | D("server: cannot bind socket yet\n"); 168 | adb_sleep_ms(1000); 169 | continue; 170 | } 171 | close_on_exec(serverfd); 172 | } 173 | 174 | alen = sizeof(addr); 175 | D("server: trying to get new connection from %d\n", port); 176 | fd = adb_socket_accept(serverfd, &addr, &alen); 177 | if(fd >= 0) { 178 | D("server: new connection on fd %d\n", fd); 179 | close_on_exec(fd); 180 | disable_tcp_nagle(fd); 181 | register_socket_transport(fd, "host", port, 1); 182 | } 183 | } 184 | D("transport: server_socket_thread() exiting\n"); 185 | return 0; 186 | } 187 | 188 | /* This is relevant only for ADB daemon running inside the emulator. */ 189 | #if !ADB_HOST 190 | /* 191 | * Redefine open and write for qemu_pipe.h that contains inlined references 192 | * to those routines. We will redifine them back after qemu_pipe.h inclusion. 193 | */ 194 | #undef open 195 | #undef write 196 | #define open adb_open 197 | #define write adb_write 198 | #include 199 | #undef open 200 | #undef write 201 | #define open ___xxx_open 202 | #define write ___xxx_write 203 | 204 | /* A worker thread that monitors host connections, and registers a transport for 205 | * every new host connection. This thread replaces server_socket_thread on 206 | * condition that adbd daemon runs inside the emulator, and emulator uses QEMUD 207 | * pipe to communicate with adbd daemon inside the guest. This is done in order 208 | * to provide more robust communication channel between ADB host and guest. The 209 | * main issue with server_socket_thread approach is that it runs on top of TCP, 210 | * and thus is sensitive to network disruptions. For instance, the 211 | * ConnectionManager may decide to reset all network connections, in which case 212 | * the connection between ADB host and guest will be lost. To make ADB traffic 213 | * independent from the network, we use here 'adb' QEMUD service to transfer data 214 | * between the host, and the guest. See external/qemu/android/adb-*.* that 215 | * implements the emulator's side of the protocol. Another advantage of using 216 | * QEMUD approach is that ADB will be up much sooner, since it doesn't depend 217 | * anymore on network being set up. 218 | * The guest side of the protocol contains the following phases: 219 | * - Connect with adb QEMUD service. In this phase a handle to 'adb' QEMUD service 220 | * is opened, and it becomes clear whether or not emulator supports that 221 | * protocol. 222 | * - Wait for the ADB host to create connection with the guest. This is done by 223 | * sending an 'accept' request to the adb QEMUD service, and waiting on 224 | * response. 225 | * - When new ADB host connection is accepted, the connection with adb QEMUD 226 | * service is registered as the transport, and a 'start' request is sent to the 227 | * adb QEMUD service, indicating that the guest is ready to receive messages. 228 | * Note that the guest will ignore messages sent down from the emulator before 229 | * the transport registration is completed. That's why we need to send the 230 | * 'start' request after the transport is registered. 231 | */ 232 | static void *qemu_socket_thread(void * arg) 233 | { 234 | /* 'accept' request to the adb QEMUD service. */ 235 | static const char _accept_req[] = "accept"; 236 | /* 'start' request to the adb QEMUD service. */ 237 | static const char _start_req[] = "start"; 238 | /* 'ok' reply from the adb QEMUD service. */ 239 | static const char _ok_resp[] = "ok"; 240 | 241 | const int port = ((intptr_t)arg); 242 | int res, fd; 243 | char tmp[256]; 244 | char con_name[32]; 245 | 246 | D("transport: qemu_socket_thread() starting\n"); 247 | 248 | /* adb QEMUD service connection request. */ 249 | snprintf(con_name, sizeof(con_name), "qemud:adb:%d", port); 250 | 251 | /* Connect to the adb QEMUD service. */ 252 | fd = qemu_pipe_open(con_name); 253 | if (fd < 0) { 254 | /* This could be an older version of the emulator, that doesn't 255 | * implement adb QEMUD service. Fall back to the old TCP way. */ 256 | adb_thread_t thr; 257 | D("adb service is not available. Falling back to TCP socket.\n"); 258 | adb_thread_create(&thr, server_socket_thread, arg); 259 | return 0; 260 | } 261 | 262 | for(;;) { 263 | /* 264 | * Wait till the host creates a new connection. 265 | */ 266 | 267 | /* Send the 'accept' request. */ 268 | res = adb_write(fd, _accept_req, strlen(_accept_req)); 269 | if (res == (int)strlen(_accept_req)) { 270 | /* Wait for the response. In the response we expect 'ok' on success, 271 | * or 'ko' on failure. */ 272 | res = adb_read(fd, tmp, sizeof(tmp)); 273 | if (res != 2 || memcmp(tmp, _ok_resp, 2)) { 274 | D("Accepting ADB host connection has failed.\n"); 275 | adb_close(fd); 276 | } else { 277 | /* Host is connected. Register the transport, and start the 278 | * exchange. */ 279 | register_socket_transport(fd, "host", port, 1); 280 | adb_write(fd, _start_req, strlen(_start_req)); 281 | } 282 | 283 | /* Prepare for accepting of the next ADB host connection. */ 284 | fd = qemu_pipe_open(con_name); 285 | if (fd < 0) { 286 | D("adb service become unavailable.\n"); 287 | return 0; 288 | } 289 | } else { 290 | D("Unable to send the '%s' request to ADB service.\n", _accept_req); 291 | return 0; 292 | } 293 | } 294 | D("transport: qemu_socket_thread() exiting\n"); 295 | return 0; 296 | } 297 | #endif // !ADB_HOST 298 | 299 | void local_init(int port) 300 | { 301 | adb_thread_t thr; 302 | void* (*func)(void *); 303 | 304 | if(HOST) { 305 | func = client_socket_thread; 306 | } else { 307 | #if ADB_HOST 308 | func = server_socket_thread; 309 | #else 310 | /* For the adbd daemon in the system image we need to distinguish 311 | * between the device, and the emulator. */ 312 | char is_qemu[PROPERTY_VALUE_MAX]; 313 | property_get("ro.kernel.qemu", is_qemu, ""); 314 | if (!strcmp(is_qemu, "1")) { 315 | /* Running inside the emulator: use QEMUD pipe as the transport. */ 316 | func = qemu_socket_thread; 317 | } else { 318 | /* Running inside the device: use TCP socket as the transport. */ 319 | func = server_socket_thread; 320 | } 321 | #endif // !ADB_HOST 322 | } 323 | 324 | D("transport: local %s init\n", HOST ? "client" : "server"); 325 | 326 | intptr_t arg = port; 327 | if(adb_thread_create(&thr, func, (void *)arg)) { 328 | fatal_errno("cannot create local socket %s thread", 329 | HOST ? "client" : "server"); 330 | } 331 | } 332 | 333 | static void remote_kick(atransport *t) 334 | { 335 | int fd = t->sfd; 336 | t->sfd = -1; 337 | adb_shutdown(fd); 338 | adb_close(fd); 339 | 340 | #if ADB_HOST 341 | if(HOST) { 342 | int nn; 343 | adb_mutex_lock( &local_transports_lock ); 344 | for (nn = 0; nn < ADB_LOCAL_TRANSPORT_MAX; nn++) { 345 | if (local_transports[nn] == t) { 346 | local_transports[nn] = NULL; 347 | break; 348 | } 349 | } 350 | adb_mutex_unlock( &local_transports_lock ); 351 | } 352 | #endif 353 | } 354 | 355 | static void remote_close(atransport *t) 356 | { 357 | adb_close(t->fd); 358 | } 359 | 360 | 361 | #if ADB_HOST 362 | /* Only call this function if you already hold local_transports_lock. */ 363 | atransport* find_emulator_transport_by_adb_port_locked(int adb_port) 364 | { 365 | int i; 366 | for (i = 0; i < ADB_LOCAL_TRANSPORT_MAX; i++) { 367 | if (local_transports[i] && local_transports[i]->adb_port == adb_port) { 368 | return local_transports[i]; 369 | } 370 | } 371 | return NULL; 372 | } 373 | 374 | atransport* find_emulator_transport_by_adb_port(int adb_port) 375 | { 376 | adb_mutex_lock( &local_transports_lock ); 377 | atransport* result = find_emulator_transport_by_adb_port_locked(adb_port); 378 | adb_mutex_unlock( &local_transports_lock ); 379 | return result; 380 | } 381 | 382 | /* Only call this function if you already hold local_transports_lock. */ 383 | int get_available_local_transport_index_locked() 384 | { 385 | int i; 386 | for (i = 0; i < ADB_LOCAL_TRANSPORT_MAX; i++) { 387 | if (local_transports[i] == NULL) { 388 | return i; 389 | } 390 | } 391 | return -1; 392 | } 393 | 394 | int get_available_local_transport_index() 395 | { 396 | adb_mutex_lock( &local_transports_lock ); 397 | int result = get_available_local_transport_index_locked(); 398 | adb_mutex_unlock( &local_transports_lock ); 399 | return result; 400 | } 401 | #endif 402 | 403 | int init_socket_transport(atransport *t, int s, int adb_port, int local) 404 | { 405 | int fail = 0; 406 | 407 | t->kick = remote_kick; 408 | t->close = remote_close; 409 | t->read_from_remote = remote_read; 410 | t->write_to_remote = remote_write; 411 | t->sfd = s; 412 | t->sync_token = 1; 413 | t->connection_state = CS_OFFLINE; 414 | t->type = kTransportLocal; 415 | t->adb_port = 0; 416 | 417 | #if ADB_HOST 418 | if (HOST && local) { 419 | adb_mutex_lock( &local_transports_lock ); 420 | { 421 | t->adb_port = adb_port; 422 | atransport* existing_transport = 423 | find_emulator_transport_by_adb_port_locked(adb_port); 424 | int index = get_available_local_transport_index_locked(); 425 | if (existing_transport != NULL) { 426 | D("local transport for port %d already registered (%p)?\n", 427 | adb_port, existing_transport); 428 | fail = -1; 429 | } else if (index < 0) { 430 | // Too many emulators. 431 | D("cannot register more emulators. Maximum is %d\n", 432 | ADB_LOCAL_TRANSPORT_MAX); 433 | fail = -1; 434 | } else { 435 | local_transports[index] = t; 436 | } 437 | } 438 | adb_mutex_unlock( &local_transports_lock ); 439 | } 440 | #endif 441 | return fail; 442 | } 443 | -------------------------------------------------------------------------------- /transport_usb.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | #define TRACE_TAG TRACE_TRANSPORT 24 | #include "adb.h" 25 | 26 | #if ADB_HOST 27 | #include "usb_vendors.h" 28 | #endif 29 | 30 | #ifdef HAVE_BIG_ENDIAN 31 | #define H4(x) (((x) & 0xFF000000) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | (((x) & 0x000000FF) << 24) 32 | static inline void fix_endians(apacket *p) 33 | { 34 | p->msg.command = H4(p->msg.command); 35 | p->msg.arg0 = H4(p->msg.arg0); 36 | p->msg.arg1 = H4(p->msg.arg1); 37 | p->msg.data_length = H4(p->msg.data_length); 38 | p->msg.data_check = H4(p->msg.data_check); 39 | p->msg.magic = H4(p->msg.magic); 40 | } 41 | unsigned host_to_le32(unsigned n) 42 | { 43 | return H4(n); 44 | } 45 | #else 46 | #define fix_endians(p) do {} while (0) 47 | unsigned host_to_le32(unsigned n) 48 | { 49 | return n; 50 | } 51 | #endif 52 | 53 | static int remote_read(apacket *p, atransport *t) 54 | { 55 | if(usb_read(t->usb, &p->msg, sizeof(amessage))){ 56 | D("remote usb: read terminated (message)\n"); 57 | return -1; 58 | } 59 | 60 | fix_endians(p); 61 | 62 | if(check_header(p)) { 63 | D("remote usb: check_header failed\n"); 64 | return -1; 65 | } 66 | 67 | if(p->msg.data_length) { 68 | if(usb_read(t->usb, p->data, p->msg.data_length)){ 69 | D("remote usb: terminated (data)\n"); 70 | return -1; 71 | } 72 | } 73 | 74 | if(check_data(p)) { 75 | D("remote usb: check_data failed\n"); 76 | return -1; 77 | } 78 | 79 | return 0; 80 | } 81 | 82 | static int remote_write(apacket *p, atransport *t) 83 | { 84 | unsigned size = p->msg.data_length; 85 | 86 | fix_endians(p); 87 | 88 | if(usb_write(t->usb, &p->msg, sizeof(amessage))) { 89 | D("remote usb: 1 - write terminated\n"); 90 | return -1; 91 | } 92 | if(p->msg.data_length == 0) return 0; 93 | if(usb_write(t->usb, &p->data, size)) { 94 | D("remote usb: 2 - write terminated\n"); 95 | return -1; 96 | } 97 | 98 | return 0; 99 | } 100 | 101 | static void remote_close(atransport *t) 102 | { 103 | usb_close(t->usb); 104 | t->usb = 0; 105 | } 106 | 107 | static void remote_kick(atransport *t) 108 | { 109 | usb_kick(t->usb); 110 | } 111 | 112 | void init_usb_transport(atransport *t, usb_handle *h, int state) 113 | { 114 | D("transport: usb\n"); 115 | t->close = remote_close; 116 | t->kick = remote_kick; 117 | t->read_from_remote = remote_read; 118 | t->write_to_remote = remote_write; 119 | t->sync_token = 1; 120 | t->connection_state = state; 121 | t->type = kTransportUsb; 122 | t->usb = h; 123 | 124 | #if ADB_HOST 125 | HOST = 1; 126 | #else 127 | HOST = 0; 128 | #endif 129 | } 130 | 131 | #if ADB_HOST 132 | int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol) 133 | { 134 | unsigned i; 135 | for (i = 0; i < vendorIdCount; i++) { 136 | if (vid == vendorIds[i]) { 137 | if (usb_class == ADB_CLASS && usb_subclass == ADB_SUBCLASS && 138 | usb_protocol == ADB_PROTOCOL) { 139 | return 1; 140 | } 141 | 142 | return 0; 143 | } 144 | } 145 | 146 | return 0; 147 | } 148 | #endif 149 | -------------------------------------------------------------------------------- /usb_linux_client.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "sysdeps.h" 30 | 31 | #define TRACE_TAG TRACE_USB 32 | #include "adb.h" 33 | 34 | #define MAX_PACKET_SIZE_FS 64 35 | #define MAX_PACKET_SIZE_HS 512 36 | 37 | #define cpu_to_le16(x) htole16(x) 38 | #define cpu_to_le32(x) htole32(x) 39 | 40 | struct usb_handle 41 | { 42 | adb_cond_t notify; 43 | adb_mutex_t lock; 44 | 45 | int (*write)(usb_handle *h, const void *data, int len); 46 | int (*read)(usb_handle *h, void *data, int len); 47 | void (*kick)(usb_handle *h); 48 | 49 | // Legacy f_adb 50 | int fd; 51 | 52 | // FunctionFS 53 | int control; 54 | int bulk_out; /* "out" from the host's perspective => source for adbd */ 55 | int bulk_in; /* "in" from the host's perspective => sink for adbd */ 56 | }; 57 | 58 | static const struct { 59 | struct usb_functionfs_descs_head header; 60 | struct { 61 | struct usb_interface_descriptor intf; 62 | struct usb_endpoint_descriptor_no_audio source; 63 | struct usb_endpoint_descriptor_no_audio sink; 64 | } __attribute__((packed)) fs_descs, hs_descs; 65 | } __attribute__((packed)) descriptors = { 66 | .header = { 67 | .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC), 68 | .length = cpu_to_le32(sizeof(descriptors)), 69 | .fs_count = 3, 70 | .hs_count = 3, 71 | }, 72 | .fs_descs = { 73 | .intf = { 74 | .bLength = sizeof(descriptors.fs_descs.intf), 75 | .bDescriptorType = USB_DT_INTERFACE, 76 | .bInterfaceNumber = 0, 77 | .bNumEndpoints = 2, 78 | .bInterfaceClass = ADB_CLASS, 79 | .bInterfaceSubClass = ADB_SUBCLASS, 80 | .bInterfaceProtocol = ADB_PROTOCOL, 81 | .iInterface = 1, /* first string from the provided table */ 82 | }, 83 | .source = { 84 | .bLength = sizeof(descriptors.fs_descs.source), 85 | .bDescriptorType = USB_DT_ENDPOINT, 86 | .bEndpointAddress = 1 | USB_DIR_OUT, 87 | .bmAttributes = USB_ENDPOINT_XFER_BULK, 88 | .wMaxPacketSize = MAX_PACKET_SIZE_FS, 89 | }, 90 | .sink = { 91 | .bLength = sizeof(descriptors.fs_descs.sink), 92 | .bDescriptorType = USB_DT_ENDPOINT, 93 | .bEndpointAddress = 2 | USB_DIR_IN, 94 | .bmAttributes = USB_ENDPOINT_XFER_BULK, 95 | .wMaxPacketSize = MAX_PACKET_SIZE_FS, 96 | }, 97 | }, 98 | .hs_descs = { 99 | .intf = { 100 | .bLength = sizeof(descriptors.hs_descs.intf), 101 | .bDescriptorType = USB_DT_INTERFACE, 102 | .bInterfaceNumber = 0, 103 | .bNumEndpoints = 2, 104 | .bInterfaceClass = ADB_CLASS, 105 | .bInterfaceSubClass = ADB_SUBCLASS, 106 | .bInterfaceProtocol = ADB_PROTOCOL, 107 | .iInterface = 1, /* first string from the provided table */ 108 | }, 109 | .source = { 110 | .bLength = sizeof(descriptors.hs_descs.source), 111 | .bDescriptorType = USB_DT_ENDPOINT, 112 | .bEndpointAddress = 1 | USB_DIR_OUT, 113 | .bmAttributes = USB_ENDPOINT_XFER_BULK, 114 | .wMaxPacketSize = MAX_PACKET_SIZE_HS, 115 | }, 116 | .sink = { 117 | .bLength = sizeof(descriptors.hs_descs.sink), 118 | .bDescriptorType = USB_DT_ENDPOINT, 119 | .bEndpointAddress = 2 | USB_DIR_IN, 120 | .bmAttributes = USB_ENDPOINT_XFER_BULK, 121 | .wMaxPacketSize = MAX_PACKET_SIZE_HS, 122 | }, 123 | }, 124 | }; 125 | 126 | #define STR_INTERFACE_ "ADB Interface" 127 | 128 | static const struct { 129 | struct usb_functionfs_strings_head header; 130 | struct { 131 | __le16 code; 132 | const char str1[sizeof(STR_INTERFACE_)]; 133 | } __attribute__((packed)) lang0; 134 | } __attribute__((packed)) strings = { 135 | .header = { 136 | .magic = cpu_to_le32(FUNCTIONFS_STRINGS_MAGIC), 137 | .length = cpu_to_le32(sizeof(strings)), 138 | .str_count = cpu_to_le32(1), 139 | .lang_count = cpu_to_le32(1), 140 | }, 141 | .lang0 = { 142 | cpu_to_le16(0x0409), /* en-us */ 143 | STR_INTERFACE_, 144 | }, 145 | }; 146 | 147 | static void *usb_adb_open_thread(void *x) 148 | { 149 | struct usb_handle *usb = (struct usb_handle *)x; 150 | int fd; 151 | 152 | while (1) { 153 | // wait until the USB device needs opening 154 | adb_mutex_lock(&usb->lock); 155 | while (usb->fd != -1) 156 | adb_cond_wait(&usb->notify, &usb->lock); 157 | adb_mutex_unlock(&usb->lock); 158 | 159 | D("[ usb_thread - opening device ]\n"); 160 | do { 161 | /* XXX use inotify? */ 162 | fd = unix_open("/dev/android_adb", O_RDWR); 163 | if (fd < 0) { 164 | // to support older kernels 165 | fd = unix_open("/dev/android", O_RDWR); 166 | } 167 | if (fd < 0) { 168 | adb_sleep_ms(1000); 169 | } 170 | } while (fd < 0); 171 | D("[ opening device succeeded ]\n"); 172 | 173 | close_on_exec(fd); 174 | usb->fd = fd; 175 | 176 | D("[ usb_thread - registering device ]\n"); 177 | register_usb_transport(usb, 0, 1); 178 | } 179 | 180 | // never gets here 181 | return 0; 182 | } 183 | 184 | static int usb_adb_write(usb_handle *h, const void *data, int len) 185 | { 186 | int n; 187 | 188 | D("about to write (fd=%d, len=%d)\n", h->fd, len); 189 | n = adb_write(h->fd, data, len); 190 | if(n != len) { 191 | D("ERROR: fd = %d, n = %d, errno = %d (%s)\n", 192 | h->fd, n, errno, strerror(errno)); 193 | return -1; 194 | } 195 | D("[ done fd=%d ]\n", h->fd); 196 | return 0; 197 | } 198 | 199 | static int usb_adb_read(usb_handle *h, void *data, int len) 200 | { 201 | int n; 202 | 203 | D("about to read (fd=%d, len=%d)\n", h->fd, len); 204 | n = adb_read(h->fd, data, len); 205 | if(n != len) { 206 | D("ERROR: fd = %d, n = %d, errno = %d (%s)\n", 207 | h->fd, n, errno, strerror(errno)); 208 | return -1; 209 | } 210 | D("[ done fd=%d ]\n", h->fd); 211 | return 0; 212 | } 213 | 214 | static void usb_adb_kick(usb_handle *h) 215 | { 216 | D("usb_kick\n"); 217 | adb_mutex_lock(&h->lock); 218 | adb_close(h->fd); 219 | h->fd = -1; 220 | 221 | // notify usb_adb_open_thread that we are disconnected 222 | adb_cond_signal(&h->notify); 223 | adb_mutex_unlock(&h->lock); 224 | } 225 | 226 | static void usb_adb_init() 227 | { 228 | usb_handle *h; 229 | adb_thread_t tid; 230 | int fd; 231 | 232 | h = calloc(1, sizeof(usb_handle)); 233 | 234 | h->write = usb_adb_write; 235 | h->read = usb_adb_read; 236 | h->kick = usb_adb_kick; 237 | h->fd = -1; 238 | 239 | adb_cond_init(&h->notify, 0); 240 | adb_mutex_init(&h->lock, 0); 241 | 242 | // Open the file /dev/android_adb_enable to trigger 243 | // the enabling of the adb USB function in the kernel. 244 | // We never touch this file again - just leave it open 245 | // indefinitely so the kernel will know when we are running 246 | // and when we are not. 247 | fd = unix_open("/dev/android_adb_enable", O_RDWR); 248 | if (fd < 0) { 249 | D("failed to open /dev/android_adb_enable\n"); 250 | } else { 251 | close_on_exec(fd); 252 | } 253 | 254 | D("[ usb_init - starting thread ]\n"); 255 | if(adb_thread_create(&tid, usb_adb_open_thread, h)){ 256 | fatal_errno("cannot create usb thread"); 257 | } 258 | } 259 | 260 | static void init_functionfs(struct usb_handle *h) 261 | { 262 | ssize_t ret; 263 | 264 | D("OPENING %s\n", USB_FFS_ADB_EP0); 265 | h->control = adb_open(USB_FFS_ADB_EP0, O_RDWR); 266 | if (h->control < 0) { 267 | D("[ %s: cannot open control endpoint: errno=%d]\n", USB_FFS_ADB_EP0, errno); 268 | goto err; 269 | } 270 | 271 | ret = adb_write(h->control, &descriptors, sizeof(descriptors)); 272 | if (ret < 0) { 273 | D("[ %s: write descriptors failed: errno=%d ]\n", USB_FFS_ADB_EP0, errno); 274 | goto err; 275 | } 276 | 277 | ret = adb_write(h->control, &strings, sizeof(strings)); 278 | if (ret < 0) { 279 | D("[ %s: writing strings failed: errno=%d]\n", USB_FFS_ADB_EP0, errno); 280 | goto err; 281 | } 282 | 283 | h->bulk_out = adb_open(USB_FFS_ADB_OUT, O_RDWR); 284 | if (h->bulk_out < 0) { 285 | D("[ %s: cannot open bulk-out ep: errno=%d ]\n", USB_FFS_ADB_OUT, errno); 286 | goto err; 287 | } 288 | 289 | h->bulk_in = adb_open(USB_FFS_ADB_IN, O_RDWR); 290 | if (h->bulk_in < 0) { 291 | D("[ %s: cannot open bulk-in ep: errno=%d ]\n", USB_FFS_ADB_IN, errno); 292 | goto err; 293 | } 294 | 295 | return; 296 | 297 | err: 298 | if (h->bulk_in > 0) { 299 | adb_close(h->bulk_in); 300 | h->bulk_in = -1; 301 | } 302 | if (h->bulk_out > 0) { 303 | adb_close(h->bulk_out); 304 | h->bulk_out = -1; 305 | } 306 | if (h->control > 0) { 307 | adb_close(h->control); 308 | h->control = -1; 309 | } 310 | return; 311 | } 312 | 313 | static void *usb_ffs_open_thread(void *x) 314 | { 315 | struct usb_handle *usb = (struct usb_handle *)x; 316 | 317 | while (1) { 318 | // wait until the USB device needs opening 319 | adb_mutex_lock(&usb->lock); 320 | while (usb->control != -1) 321 | adb_cond_wait(&usb->notify, &usb->lock); 322 | adb_mutex_unlock(&usb->lock); 323 | 324 | while (1) { 325 | init_functionfs(usb); 326 | 327 | if (usb->control >= 0) 328 | break; 329 | 330 | adb_sleep_ms(1000); 331 | } 332 | 333 | D("[ usb_thread - registering device ]\n"); 334 | register_usb_transport(usb, 0, 1); 335 | } 336 | 337 | // never gets here 338 | return 0; 339 | } 340 | 341 | static int bulk_write(int bulk_in, const char *buf, size_t length) 342 | { 343 | size_t count = 0; 344 | int ret; 345 | 346 | do { 347 | ret = adb_write(bulk_in, buf + count, length - count); 348 | if (ret < 0) { 349 | if (errno != EINTR) 350 | return ret; 351 | } else { 352 | count += ret; 353 | } 354 | } while (count < length); 355 | 356 | D("[ bulk_write done fd=%d ]\n", bulk_in); 357 | return count; 358 | } 359 | 360 | static int usb_ffs_write(usb_handle *h, const void *data, int len) 361 | { 362 | int n; 363 | 364 | D("about to write (fd=%d, len=%d)\n", h->bulk_in, len); 365 | n = bulk_write(h->bulk_in, data, len); 366 | if (n != len) { 367 | D("ERROR: fd = %d, n = %d, errno = %d (%s)\n", 368 | h->bulk_in, n, errno, strerror(errno)); 369 | return -1; 370 | } 371 | D("[ done fd=%d ]\n", h->bulk_in); 372 | return 0; 373 | } 374 | 375 | static int bulk_read(int bulk_out, char *buf, size_t length) 376 | { 377 | size_t count = 0; 378 | int ret; 379 | 380 | do { 381 | ret = adb_read(bulk_out, buf + count, length - count); 382 | if (ret < 0) { 383 | if (errno != EINTR) { 384 | D("[ bulk_read failed fd=%d length=%d count=%d ]\n", 385 | bulk_out, length, count); 386 | return ret; 387 | } 388 | } else { 389 | count += ret; 390 | } 391 | } while (count < length); 392 | 393 | return count; 394 | } 395 | 396 | static int usb_ffs_read(usb_handle *h, void *data, int len) 397 | { 398 | int n; 399 | 400 | D("about to read (fd=%d, len=%d)\n", h->bulk_out, len); 401 | n = bulk_read(h->bulk_out, data, len); 402 | if (n != len) { 403 | D("ERROR: fd = %d, n = %d, errno = %d (%s)\n", 404 | h->bulk_out, n, errno, strerror(errno)); 405 | return -1; 406 | } 407 | D("[ done fd=%d ]\n", h->bulk_out); 408 | return 0; 409 | } 410 | 411 | static void usb_ffs_kick(usb_handle *h) 412 | { 413 | int err; 414 | 415 | err = ioctl(h->bulk_in, FUNCTIONFS_CLEAR_HALT); 416 | if (err < 0) 417 | D("[ kick: source (fd=%d) clear halt failed (%d) ]", h->bulk_in, errno); 418 | 419 | err = ioctl(h->bulk_out, FUNCTIONFS_CLEAR_HALT); 420 | if (err < 0) 421 | D("[ kick: sink (fd=%d) clear halt failed (%d) ]", h->bulk_out, errno); 422 | 423 | adb_mutex_lock(&h->lock); 424 | adb_close(h->control); 425 | adb_close(h->bulk_out); 426 | adb_close(h->bulk_in); 427 | h->control = h->bulk_out = h->bulk_in = -1; 428 | 429 | // notify usb_ffs_open_thread that we are disconnected 430 | adb_cond_signal(&h->notify); 431 | adb_mutex_unlock(&h->lock); 432 | } 433 | 434 | static void usb_ffs_init() 435 | { 436 | usb_handle *h; 437 | adb_thread_t tid; 438 | 439 | D("[ usb_init - using FunctionFS ]\n"); 440 | 441 | h = calloc(1, sizeof(usb_handle)); 442 | 443 | h->write = usb_ffs_write; 444 | h->read = usb_ffs_read; 445 | h->kick = usb_ffs_kick; 446 | 447 | h->control = -1; 448 | h->bulk_out = -1; 449 | h->bulk_out = -1; 450 | 451 | adb_cond_init(&h->notify, 0); 452 | adb_mutex_init(&h->lock, 0); 453 | 454 | D("[ usb_init - starting thread ]\n"); 455 | if (adb_thread_create(&tid, usb_ffs_open_thread, h)){ 456 | fatal_errno("[ cannot create usb thread ]\n"); 457 | } 458 | } 459 | 460 | void usb_init() 461 | { 462 | if (access(USB_FFS_ADB_EP0, F_OK) == 0) 463 | usb_ffs_init(); 464 | else 465 | usb_adb_init(); 466 | } 467 | 468 | void usb_cleanup() 469 | { 470 | } 471 | 472 | int usb_write(usb_handle *h, const void *data, int len) 473 | { 474 | return h->write(h, data, len); 475 | } 476 | 477 | int usb_read(usb_handle *h, void *data, int len) 478 | { 479 | return h->read(h, data, len); 480 | } 481 | 482 | int usb_close(usb_handle *h) 483 | { 484 | return 0; 485 | } 486 | 487 | void usb_kick(usb_handle *h) 488 | { 489 | h->kick(h); 490 | } 491 | -------------------------------------------------------------------------------- /usb_vendors.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "usb_vendors.h" 18 | 19 | #include 20 | 21 | #ifdef _WIN32 22 | # define WIN32_LEAN_AND_MEAN 23 | # include "windows.h" 24 | # include "shlobj.h" 25 | #else 26 | # include 27 | # include 28 | #endif 29 | 30 | #include "sysdeps.h" 31 | #include "adb.h" 32 | 33 | #define ANDROID_PATH ".android" 34 | #define ANDROID_ADB_INI "adb_usb.ini" 35 | 36 | #define TRACE_TAG TRACE_USB 37 | 38 | // Google's USB Vendor ID 39 | #define VENDOR_ID_GOOGLE 0x18d1 40 | // Intel's USB Vendor ID 41 | #define VENDOR_ID_INTEL 0x8087 42 | // HTC's USB Vendor ID 43 | #define VENDOR_ID_HTC 0x0bb4 44 | // Samsung's USB Vendor ID 45 | #define VENDOR_ID_SAMSUNG 0x04e8 46 | // Motorola's USB Vendor ID 47 | #define VENDOR_ID_MOTOROLA 0x22b8 48 | // LG's USB Vendor ID 49 | #define VENDOR_ID_LGE 0x1004 50 | // Huawei's USB Vendor ID 51 | #define VENDOR_ID_HUAWEI 0x12D1 52 | // Acer's USB Vendor ID 53 | #define VENDOR_ID_ACER 0x0502 54 | // Sony Ericsson's USB Vendor ID 55 | #define VENDOR_ID_SONY_ERICSSON 0x0FCE 56 | // Foxconn's USB Vendor ID 57 | #define VENDOR_ID_FOXCONN 0x0489 58 | // Dell's USB Vendor ID 59 | #define VENDOR_ID_DELL 0x413c 60 | // Nvidia's USB Vendor ID 61 | #define VENDOR_ID_NVIDIA 0x0955 62 | // Garmin-Asus's USB Vendor ID 63 | #define VENDOR_ID_GARMIN_ASUS 0x091E 64 | // Sharp's USB Vendor ID 65 | #define VENDOR_ID_SHARP 0x04dd 66 | // ZTE's USB Vendor ID 67 | #define VENDOR_ID_ZTE 0x19D2 68 | // Kyocera's USB Vendor ID 69 | #define VENDOR_ID_KYOCERA 0x0482 70 | // Pantech's USB Vendor ID 71 | #define VENDOR_ID_PANTECH 0x10A9 72 | // Qualcomm's USB Vendor ID 73 | #define VENDOR_ID_QUALCOMM 0x05c6 74 | // On-The-Go-Video's USB Vendor ID 75 | #define VENDOR_ID_OTGV 0x2257 76 | // NEC's USB Vendor ID 77 | #define VENDOR_ID_NEC 0x0409 78 | // Panasonic Mobile Communication's USB Vendor ID 79 | #define VENDOR_ID_PMC 0x04DA 80 | // Toshiba's USB Vendor ID 81 | #define VENDOR_ID_TOSHIBA 0x0930 82 | // SK Telesys's USB Vendor ID 83 | #define VENDOR_ID_SK_TELESYS 0x1F53 84 | // KT Tech's USB Vendor ID 85 | #define VENDOR_ID_KT_TECH 0x2116 86 | // Asus's USB Vendor ID 87 | #define VENDOR_ID_ASUS 0x0b05 88 | // Philips's USB Vendor ID 89 | #define VENDOR_ID_PHILIPS 0x0471 90 | // Texas Instruments's USB Vendor ID 91 | #define VENDOR_ID_TI 0x0451 92 | // Funai's USB Vendor ID 93 | #define VENDOR_ID_FUNAI 0x0F1C 94 | // Gigabyte's USB Vendor ID 95 | #define VENDOR_ID_GIGABYTE 0x0414 96 | // IRiver's USB Vendor ID 97 | #define VENDOR_ID_IRIVER 0x2420 98 | // Compal's USB Vendor ID 99 | #define VENDOR_ID_COMPAL 0x1219 100 | // T & A Mobile Phones' USB Vendor ID 101 | #define VENDOR_ID_T_AND_A 0x1BBB 102 | // LenovoMobile's USB Vendor ID 103 | #define VENDOR_ID_LENOVOMOBILE 0x2006 104 | // Lenovo's USB Vendor ID 105 | #define VENDOR_ID_LENOVO 0x17EF 106 | // Vizio's USB Vendor ID 107 | #define VENDOR_ID_VIZIO 0xE040 108 | // K-Touch's USB Vendor ID 109 | #define VENDOR_ID_K_TOUCH 0x24E3 110 | // Pegatron's USB Vendor ID 111 | #define VENDOR_ID_PEGATRON 0x1D4D 112 | // Archos's USB Vendor ID 113 | #define VENDOR_ID_ARCHOS 0x0E79 114 | // Positivo's USB Vendor ID 115 | #define VENDOR_ID_POSITIVO 0x1662 116 | // Fujitsu's USB Vendor ID 117 | #define VENDOR_ID_FUJITSU 0x04C5 118 | // Lumigon's USB Vendor ID 119 | #define VENDOR_ID_LUMIGON 0x25E3 120 | // Quanta's USB Vendor ID 121 | #define VENDOR_ID_QUANTA 0x0408 122 | // INQ Mobile's USB Vendor ID 123 | #define VENDOR_ID_INQ_MOBILE 0x2314 124 | // Sony's USB Vendor ID 125 | #define VENDOR_ID_SONY 0x054C 126 | // Yulong Coolpad's USB Vendor ID 127 | #define VENDOR_ID_YULONG_COOLPAD 0x1EBF 128 | // Lab126's USB Vendor ID 129 | #define VENDOR_ID_LAB126 0x1949 130 | 131 | /** built-in vendor list */ 132 | int builtInVendorIds[] = { 133 | VENDOR_ID_GOOGLE, 134 | VENDOR_ID_INTEL, 135 | VENDOR_ID_HTC, 136 | VENDOR_ID_SAMSUNG, 137 | VENDOR_ID_MOTOROLA, 138 | VENDOR_ID_LGE, 139 | VENDOR_ID_HUAWEI, 140 | VENDOR_ID_ACER, 141 | VENDOR_ID_SONY_ERICSSON, 142 | VENDOR_ID_FOXCONN, 143 | VENDOR_ID_DELL, 144 | VENDOR_ID_NVIDIA, 145 | VENDOR_ID_GARMIN_ASUS, 146 | VENDOR_ID_SHARP, 147 | VENDOR_ID_ZTE, 148 | VENDOR_ID_KYOCERA, 149 | VENDOR_ID_PANTECH, 150 | VENDOR_ID_QUALCOMM, 151 | VENDOR_ID_OTGV, 152 | VENDOR_ID_NEC, 153 | VENDOR_ID_PMC, 154 | VENDOR_ID_TOSHIBA, 155 | VENDOR_ID_SK_TELESYS, 156 | VENDOR_ID_KT_TECH, 157 | VENDOR_ID_ASUS, 158 | VENDOR_ID_PHILIPS, 159 | VENDOR_ID_TI, 160 | VENDOR_ID_FUNAI, 161 | VENDOR_ID_GIGABYTE, 162 | VENDOR_ID_IRIVER, 163 | VENDOR_ID_COMPAL, 164 | VENDOR_ID_T_AND_A, 165 | VENDOR_ID_LENOVOMOBILE, 166 | VENDOR_ID_LENOVO, 167 | VENDOR_ID_VIZIO, 168 | VENDOR_ID_K_TOUCH, 169 | VENDOR_ID_PEGATRON, 170 | VENDOR_ID_ARCHOS, 171 | VENDOR_ID_POSITIVO, 172 | VENDOR_ID_FUJITSU, 173 | VENDOR_ID_LUMIGON, 174 | VENDOR_ID_QUANTA, 175 | VENDOR_ID_INQ_MOBILE, 176 | VENDOR_ID_SONY, 177 | VENDOR_ID_YULONG_COOLPAD, 178 | VENDOR_ID_LAB126, 179 | }; 180 | 181 | #define BUILT_IN_VENDOR_COUNT (sizeof(builtInVendorIds)/sizeof(builtInVendorIds[0])) 182 | 183 | /* max number of supported vendor ids (built-in + 3rd party). increase as needed */ 184 | #define VENDOR_COUNT_MAX 128 185 | 186 | int vendorIds[VENDOR_COUNT_MAX]; 187 | unsigned vendorIdCount = 0; 188 | 189 | int get_adb_usb_ini(char* buff, size_t len); 190 | 191 | void usb_vendors_init(void) 192 | { 193 | if (VENDOR_COUNT_MAX < BUILT_IN_VENDOR_COUNT) { 194 | fprintf(stderr, "VENDOR_COUNT_MAX not big enough for built-in vendor list.\n"); 195 | exit(2); 196 | } 197 | 198 | /* add the built-in vendors at the beginning of the array */ 199 | memcpy(vendorIds, builtInVendorIds, sizeof(builtInVendorIds)); 200 | 201 | /* default array size is the number of built-in vendors */ 202 | vendorIdCount = BUILT_IN_VENDOR_COUNT; 203 | 204 | if (VENDOR_COUNT_MAX == BUILT_IN_VENDOR_COUNT) 205 | return; 206 | 207 | char temp[PATH_MAX]; 208 | if (get_adb_usb_ini(temp, sizeof(temp)) == 0) { 209 | FILE * f = fopen(temp, "rt"); 210 | 211 | if (f != NULL) { 212 | /* The vendor id file is pretty basic. 1 vendor id per line. 213 | Lines starting with # are comments */ 214 | while (fgets(temp, sizeof(temp), f) != NULL) { 215 | if (temp[0] == '#') 216 | continue; 217 | 218 | long value = strtol(temp, NULL, 0); 219 | if (errno == EINVAL || errno == ERANGE || value > INT_MAX || value < 0) { 220 | fprintf(stderr, "Invalid content in %s. Quitting.\n", ANDROID_ADB_INI); 221 | exit(2); 222 | } 223 | 224 | vendorIds[vendorIdCount++] = (int)value; 225 | 226 | /* make sure we don't go beyond the array */ 227 | if (vendorIdCount == VENDOR_COUNT_MAX) { 228 | break; 229 | } 230 | } 231 | } 232 | } 233 | } 234 | 235 | /* Utils methods */ 236 | 237 | /* builds the path to the adb vendor id file. returns 0 if success */ 238 | int build_path(char* buff, size_t len, const char* format, const char* home) 239 | { 240 | if (snprintf(buff, len, format, home, ANDROID_PATH, ANDROID_ADB_INI) >= (signed)len) { 241 | return 1; 242 | } 243 | 244 | return 0; 245 | } 246 | 247 | /* fills buff with the path to the adb vendor id file. returns 0 if success */ 248 | int get_adb_usb_ini(char* buff, size_t len) 249 | { 250 | #ifdef _WIN32 251 | const char* home = getenv("ANDROID_SDK_HOME"); 252 | if (home != NULL) { 253 | return build_path(buff, len, "%s\\%s\\%s", home); 254 | } else { 255 | char path[MAX_PATH]; 256 | SHGetFolderPath( NULL, CSIDL_PROFILE, NULL, 0, path); 257 | return build_path(buff, len, "%s\\%s\\%s", path); 258 | } 259 | #else 260 | const char* home = getenv("HOME"); 261 | if (home == NULL) 262 | home = "/tmp"; 263 | 264 | return build_path(buff, len, "%s/%s/%s", home); 265 | #endif 266 | } 267 | -------------------------------------------------------------------------------- /usb_vendors.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __USB_VENDORS_H 18 | #define __USB_VENDORS_H 19 | 20 | extern int vendorIds[]; 21 | extern unsigned vendorIdCount; 22 | 23 | void usb_vendors_init(void); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /usb_windows.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "sysdeps.h" 25 | 26 | #define TRACE_TAG TRACE_USB 27 | #include "adb.h" 28 | 29 | /** Structure usb_handle describes our connection to the usb device via 30 | AdbWinApi.dll. This structure is returned from usb_open() routine and 31 | is expected in each subsequent call that is accessing the device. 32 | */ 33 | struct usb_handle { 34 | /// Previous entry in the list of opened usb handles 35 | usb_handle *prev; 36 | 37 | /// Next entry in the list of opened usb handles 38 | usb_handle *next; 39 | 40 | /// Handle to USB interface 41 | ADBAPIHANDLE adb_interface; 42 | 43 | /// Handle to USB read pipe (endpoint) 44 | ADBAPIHANDLE adb_read_pipe; 45 | 46 | /// Handle to USB write pipe (endpoint) 47 | ADBAPIHANDLE adb_write_pipe; 48 | 49 | /// Interface name 50 | char* interface_name; 51 | 52 | /// Mask for determining when to use zero length packets 53 | unsigned zero_mask; 54 | }; 55 | 56 | /// Class ID assigned to the device by androidusb.sys 57 | static const GUID usb_class_id = ANDROID_USB_CLASS_ID; 58 | 59 | /// List of opened usb handles 60 | static usb_handle handle_list = { 61 | .prev = &handle_list, 62 | .next = &handle_list, 63 | }; 64 | 65 | /// Locker for the list of opened usb handles 66 | ADB_MUTEX_DEFINE( usb_lock ); 67 | 68 | /// Checks if there is opened usb handle in handle_list for this device. 69 | int known_device(const char* dev_name); 70 | 71 | /// Checks if there is opened usb handle in handle_list for this device. 72 | /// usb_lock mutex must be held before calling this routine. 73 | int known_device_locked(const char* dev_name); 74 | 75 | /// Registers opened usb handle (adds it to handle_list). 76 | int register_new_device(usb_handle* handle); 77 | 78 | /// Checks if interface (device) matches certain criteria 79 | int recognized_device(usb_handle* handle); 80 | 81 | /// Enumerates present and available interfaces (devices), opens new ones and 82 | /// registers usb transport for them. 83 | void find_devices(); 84 | 85 | /// Entry point for thread that polls (every second) for new usb interfaces. 86 | /// This routine calls find_devices in infinite loop. 87 | void* device_poll_thread(void* unused); 88 | 89 | /// Initializes this module 90 | void usb_init(); 91 | 92 | /// Cleans up this module 93 | void usb_cleanup(); 94 | 95 | /// Opens usb interface (device) by interface (device) name. 96 | usb_handle* do_usb_open(const wchar_t* interface_name); 97 | 98 | /// Writes data to the opened usb handle 99 | int usb_write(usb_handle* handle, const void* data, int len); 100 | 101 | /// Reads data using the opened usb handle 102 | int usb_read(usb_handle *handle, void* data, int len); 103 | 104 | /// Cleans up opened usb handle 105 | void usb_cleanup_handle(usb_handle* handle); 106 | 107 | /// Cleans up (but don't close) opened usb handle 108 | void usb_kick(usb_handle* handle); 109 | 110 | /// Closes opened usb handle 111 | int usb_close(usb_handle* handle); 112 | 113 | /// Gets interface (device) name for an opened usb handle 114 | const char *usb_name(usb_handle* handle); 115 | 116 | int known_device_locked(const char* dev_name) { 117 | usb_handle* usb; 118 | 119 | if (NULL != dev_name) { 120 | // Iterate through the list looking for the name match. 121 | for(usb = handle_list.next; usb != &handle_list; usb = usb->next) { 122 | // In Windows names are not case sensetive! 123 | if((NULL != usb->interface_name) && 124 | (0 == stricmp(usb->interface_name, dev_name))) { 125 | return 1; 126 | } 127 | } 128 | } 129 | 130 | return 0; 131 | } 132 | 133 | int known_device(const char* dev_name) { 134 | int ret = 0; 135 | 136 | if (NULL != dev_name) { 137 | adb_mutex_lock(&usb_lock); 138 | ret = known_device_locked(dev_name); 139 | adb_mutex_unlock(&usb_lock); 140 | } 141 | 142 | return ret; 143 | } 144 | 145 | int register_new_device(usb_handle* handle) { 146 | if (NULL == handle) 147 | return 0; 148 | 149 | adb_mutex_lock(&usb_lock); 150 | 151 | // Check if device is already in the list 152 | if (known_device_locked(handle->interface_name)) { 153 | adb_mutex_unlock(&usb_lock); 154 | return 0; 155 | } 156 | 157 | // Not in the list. Add this handle to the list. 158 | handle->next = &handle_list; 159 | handle->prev = handle_list.prev; 160 | handle->prev->next = handle; 161 | handle->next->prev = handle; 162 | 163 | adb_mutex_unlock(&usb_lock); 164 | 165 | return 1; 166 | } 167 | 168 | void* device_poll_thread(void* unused) { 169 | D("Created device thread\n"); 170 | 171 | while(1) { 172 | find_devices(); 173 | adb_sleep_ms(1000); 174 | } 175 | 176 | return NULL; 177 | } 178 | 179 | void usb_init() { 180 | adb_thread_t tid; 181 | 182 | if(adb_thread_create(&tid, device_poll_thread, NULL)) { 183 | fatal_errno("cannot create input thread"); 184 | } 185 | } 186 | 187 | void usb_cleanup() { 188 | } 189 | 190 | usb_handle* do_usb_open(const wchar_t* interface_name) { 191 | // Allocate our handle 192 | usb_handle* ret = (usb_handle*)malloc(sizeof(usb_handle)); 193 | if (NULL == ret) 194 | return NULL; 195 | 196 | // Set linkers back to the handle 197 | ret->next = ret; 198 | ret->prev = ret; 199 | 200 | // Create interface. 201 | ret->adb_interface = AdbCreateInterfaceByName(interface_name); 202 | 203 | if (NULL == ret->adb_interface) { 204 | free(ret); 205 | errno = GetLastError(); 206 | return NULL; 207 | } 208 | 209 | // Open read pipe (endpoint) 210 | ret->adb_read_pipe = 211 | AdbOpenDefaultBulkReadEndpoint(ret->adb_interface, 212 | AdbOpenAccessTypeReadWrite, 213 | AdbOpenSharingModeReadWrite); 214 | if (NULL != ret->adb_read_pipe) { 215 | // Open write pipe (endpoint) 216 | ret->adb_write_pipe = 217 | AdbOpenDefaultBulkWriteEndpoint(ret->adb_interface, 218 | AdbOpenAccessTypeReadWrite, 219 | AdbOpenSharingModeReadWrite); 220 | if (NULL != ret->adb_write_pipe) { 221 | // Save interface name 222 | unsigned long name_len = 0; 223 | 224 | // First get expected name length 225 | AdbGetInterfaceName(ret->adb_interface, 226 | NULL, 227 | &name_len, 228 | true); 229 | if (0 != name_len) { 230 | ret->interface_name = (char*)malloc(name_len); 231 | 232 | if (NULL != ret->interface_name) { 233 | // Now save the name 234 | if (AdbGetInterfaceName(ret->adb_interface, 235 | ret->interface_name, 236 | &name_len, 237 | true)) { 238 | // We're done at this point 239 | return ret; 240 | } 241 | } else { 242 | SetLastError(ERROR_OUTOFMEMORY); 243 | } 244 | } 245 | } 246 | } 247 | 248 | // Something went wrong. 249 | int saved_errno = GetLastError(); 250 | usb_cleanup_handle(ret); 251 | free(ret); 252 | SetLastError(saved_errno); 253 | 254 | return NULL; 255 | } 256 | 257 | int usb_write(usb_handle* handle, const void* data, int len) { 258 | unsigned long time_out = 500 + len * 8; 259 | unsigned long written = 0; 260 | int ret; 261 | 262 | D("usb_write %d\n", len); 263 | if (NULL != handle) { 264 | // Perform write 265 | ret = AdbWriteEndpointSync(handle->adb_write_pipe, 266 | (void*)data, 267 | (unsigned long)len, 268 | &written, 269 | time_out); 270 | int saved_errno = GetLastError(); 271 | 272 | if (ret) { 273 | // Make sure that we've written what we were asked to write 274 | D("usb_write got: %ld, expected: %d\n", written, len); 275 | if (written == (unsigned long)len) { 276 | if(handle->zero_mask && (len & handle->zero_mask) == 0) { 277 | // Send a zero length packet 278 | AdbWriteEndpointSync(handle->adb_write_pipe, 279 | (void*)data, 280 | 0, 281 | &written, 282 | time_out); 283 | } 284 | return 0; 285 | } 286 | } else { 287 | // assume ERROR_INVALID_HANDLE indicates we are disconnected 288 | if (saved_errno == ERROR_INVALID_HANDLE) 289 | usb_kick(handle); 290 | } 291 | errno = saved_errno; 292 | } else { 293 | D("usb_write NULL handle\n"); 294 | SetLastError(ERROR_INVALID_HANDLE); 295 | } 296 | 297 | D("usb_write failed: %d\n", errno); 298 | 299 | return -1; 300 | } 301 | 302 | int usb_read(usb_handle *handle, void* data, int len) { 303 | unsigned long time_out = 500 + len * 8; 304 | unsigned long read = 0; 305 | int ret; 306 | 307 | D("usb_read %d\n", len); 308 | if (NULL != handle) { 309 | while (len > 0) { 310 | int xfer = (len > 4096) ? 4096 : len; 311 | 312 | ret = AdbReadEndpointSync(handle->adb_read_pipe, 313 | (void*)data, 314 | (unsigned long)xfer, 315 | &read, 316 | time_out); 317 | int saved_errno = GetLastError(); 318 | D("usb_write got: %ld, expected: %d, errno: %d\n", read, xfer, saved_errno); 319 | if (ret) { 320 | data += read; 321 | len -= read; 322 | 323 | if (len == 0) 324 | return 0; 325 | } else if (saved_errno != ERROR_SEM_TIMEOUT) { 326 | // assume ERROR_INVALID_HANDLE indicates we are disconnected 327 | if (saved_errno == ERROR_INVALID_HANDLE) 328 | usb_kick(handle); 329 | break; 330 | } 331 | errno = saved_errno; 332 | } 333 | } else { 334 | D("usb_read NULL handle\n"); 335 | SetLastError(ERROR_INVALID_HANDLE); 336 | } 337 | 338 | D("usb_read failed: %d\n", errno); 339 | 340 | return -1; 341 | } 342 | 343 | void usb_cleanup_handle(usb_handle* handle) { 344 | if (NULL != handle) { 345 | if (NULL != handle->interface_name) 346 | free(handle->interface_name); 347 | if (NULL != handle->adb_write_pipe) 348 | AdbCloseHandle(handle->adb_write_pipe); 349 | if (NULL != handle->adb_read_pipe) 350 | AdbCloseHandle(handle->adb_read_pipe); 351 | if (NULL != handle->adb_interface) 352 | AdbCloseHandle(handle->adb_interface); 353 | 354 | handle->interface_name = NULL; 355 | handle->adb_write_pipe = NULL; 356 | handle->adb_read_pipe = NULL; 357 | handle->adb_interface = NULL; 358 | } 359 | } 360 | 361 | void usb_kick(usb_handle* handle) { 362 | if (NULL != handle) { 363 | adb_mutex_lock(&usb_lock); 364 | 365 | usb_cleanup_handle(handle); 366 | 367 | adb_mutex_unlock(&usb_lock); 368 | } else { 369 | SetLastError(ERROR_INVALID_HANDLE); 370 | errno = ERROR_INVALID_HANDLE; 371 | } 372 | } 373 | 374 | int usb_close(usb_handle* handle) { 375 | D("usb_close\n"); 376 | 377 | if (NULL != handle) { 378 | // Remove handle from the list 379 | adb_mutex_lock(&usb_lock); 380 | 381 | if ((handle->next != handle) && (handle->prev != handle)) { 382 | handle->next->prev = handle->prev; 383 | handle->prev->next = handle->next; 384 | handle->prev = handle; 385 | handle->next = handle; 386 | } 387 | 388 | adb_mutex_unlock(&usb_lock); 389 | 390 | // Cleanup handle 391 | usb_cleanup_handle(handle); 392 | free(handle); 393 | } 394 | 395 | return 0; 396 | } 397 | 398 | const char *usb_name(usb_handle* handle) { 399 | if (NULL == handle) { 400 | SetLastError(ERROR_INVALID_HANDLE); 401 | errno = ERROR_INVALID_HANDLE; 402 | return NULL; 403 | } 404 | 405 | return (const char*)handle->interface_name; 406 | } 407 | 408 | int recognized_device(usb_handle* handle) { 409 | if (NULL == handle) 410 | return 0; 411 | 412 | // Check vendor and product id first 413 | USB_DEVICE_DESCRIPTOR device_desc; 414 | 415 | if (!AdbGetUsbDeviceDescriptor(handle->adb_interface, 416 | &device_desc)) { 417 | return 0; 418 | } 419 | 420 | // Then check interface properties 421 | USB_INTERFACE_DESCRIPTOR interf_desc; 422 | 423 | if (!AdbGetUsbInterfaceDescriptor(handle->adb_interface, 424 | &interf_desc)) { 425 | return 0; 426 | } 427 | 428 | // Must have two endpoints 429 | if (2 != interf_desc.bNumEndpoints) { 430 | return 0; 431 | } 432 | 433 | if (is_adb_interface(device_desc.idVendor, device_desc.idProduct, 434 | interf_desc.bInterfaceClass, interf_desc.bInterfaceSubClass, interf_desc.bInterfaceProtocol)) { 435 | 436 | if(interf_desc.bInterfaceProtocol == 0x01) { 437 | AdbEndpointInformation endpoint_info; 438 | // assuming zero is a valid bulk endpoint ID 439 | if (AdbGetEndpointInformation(handle->adb_interface, 0, &endpoint_info)) { 440 | handle->zero_mask = endpoint_info.max_packet_size - 1; 441 | } 442 | } 443 | 444 | return 1; 445 | } 446 | 447 | return 0; 448 | } 449 | 450 | void find_devices() { 451 | usb_handle* handle = NULL; 452 | char entry_buffer[2048]; 453 | char interf_name[2048]; 454 | AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]); 455 | unsigned long entry_buffer_size = sizeof(entry_buffer); 456 | char* copy_name; 457 | 458 | // Enumerate all present and active interfaces. 459 | ADBAPIHANDLE enum_handle = 460 | AdbEnumInterfaces(usb_class_id, true, true, true); 461 | 462 | if (NULL == enum_handle) 463 | return; 464 | 465 | while (AdbNextInterface(enum_handle, next_interface, &entry_buffer_size)) { 466 | // TODO: FIXME - temp hack converting wchar_t into char. 467 | // It would be better to change AdbNextInterface so it will return 468 | // interface name as single char string. 469 | const wchar_t* wchar_name = next_interface->device_name; 470 | for(copy_name = interf_name; 471 | L'\0' != *wchar_name; 472 | wchar_name++, copy_name++) { 473 | *copy_name = (char)(*wchar_name); 474 | } 475 | *copy_name = '\0'; 476 | 477 | // Lets see if we already have this device in the list 478 | if (!known_device(interf_name)) { 479 | // This seems to be a new device. Open it! 480 | handle = do_usb_open(next_interface->device_name); 481 | if (NULL != handle) { 482 | // Lets see if this interface (device) belongs to us 483 | if (recognized_device(handle)) { 484 | D("adding a new device %s\n", interf_name); 485 | char serial_number[512]; 486 | unsigned long serial_number_len = sizeof(serial_number); 487 | if (AdbGetSerialNumber(handle->adb_interface, 488 | serial_number, 489 | &serial_number_len, 490 | true)) { 491 | // Lets make sure that we don't duplicate this device 492 | if (register_new_device(handle)) { 493 | register_usb_transport(handle, serial_number, 1); 494 | } else { 495 | D("register_new_device failed for %s\n", interf_name); 496 | usb_cleanup_handle(handle); 497 | free(handle); 498 | } 499 | } else { 500 | D("cannot get serial number\n"); 501 | usb_cleanup_handle(handle); 502 | free(handle); 503 | } 504 | } else { 505 | usb_cleanup_handle(handle); 506 | free(handle); 507 | } 508 | } 509 | } 510 | 511 | entry_buffer_size = sizeof(entry_buffer); 512 | } 513 | 514 | AdbCloseHandle(enum_handle); 515 | } 516 | -------------------------------------------------------------------------------- /utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include "utils.h" 17 | #include 18 | #include 19 | #include 20 | 21 | char* 22 | buff_addc (char* buff, char* buffEnd, int c) 23 | { 24 | int avail = buffEnd - buff; 25 | 26 | if (avail <= 0) /* already in overflow mode */ 27 | return buff; 28 | 29 | if (avail == 1) { /* overflowing, the last byte is reserved for zero */ 30 | buff[0] = 0; 31 | return buff + 1; 32 | } 33 | 34 | buff[0] = (char) c; /* add char and terminating zero */ 35 | buff[1] = 0; 36 | return buff + 1; 37 | } 38 | 39 | char* 40 | buff_adds (char* buff, char* buffEnd, const char* s) 41 | { 42 | int slen = strlen(s); 43 | 44 | return buff_addb(buff, buffEnd, s, slen); 45 | } 46 | 47 | char* 48 | buff_addb (char* buff, char* buffEnd, const void* data, int len) 49 | { 50 | int avail = (buffEnd - buff); 51 | 52 | if (avail <= 0 || len <= 0) /* already overflowing */ 53 | return buff; 54 | 55 | if (len > avail) 56 | len = avail; 57 | 58 | memcpy(buff, data, len); 59 | 60 | buff += len; 61 | 62 | /* ensure there is a terminating zero */ 63 | if (buff >= buffEnd) { /* overflow */ 64 | buff[-1] = 0; 65 | } else 66 | buff[0] = 0; 67 | 68 | return buff; 69 | } 70 | 71 | char* 72 | buff_add (char* buff, char* buffEnd, const char* format, ... ) 73 | { 74 | int avail; 75 | 76 | avail = (buffEnd - buff); 77 | 78 | if (avail > 0) { 79 | va_list args; 80 | int nn; 81 | 82 | va_start(args, format); 83 | nn = vsnprintf( buff, avail, format, args); 84 | va_end(args); 85 | 86 | if (nn < 0) { 87 | /* some C libraries return -1 in case of overflow, 88 | * but they will also do that if the format spec is 89 | * invalid. We assume ADB is not buggy enough to 90 | * trigger that last case. */ 91 | nn = avail; 92 | } 93 | else if (nn > avail) { 94 | nn = avail; 95 | } 96 | 97 | buff += nn; 98 | 99 | /* ensure that there is a terminating zero */ 100 | if (buff >= buffEnd) 101 | buff[-1] = 0; 102 | else 103 | buff[0] = 0; 104 | } 105 | return buff; 106 | } 107 | -------------------------------------------------------------------------------- /utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #ifndef _ADB_UTILS_H 17 | #define _ADB_UTILS_H 18 | 19 | /* bounded buffer functions */ 20 | 21 | /* all these functions are used to append data to a bounded buffer. 22 | * 23 | * after each operation, the buffer is guaranteed to be zero-terminated, 24 | * even in the case of an overflow. they all return the new buffer position 25 | * which allows one to use them in succession, only checking for overflows 26 | * at the end. For example: 27 | * 28 | * BUFF_DECL(temp,p,end,1024); 29 | * char* p; 30 | * 31 | * p = buff_addc(temp, end, '"'); 32 | * p = buff_adds(temp, end, string); 33 | * p = buff_addc(temp, end, '"'); 34 | * 35 | * if (p >= end) { 36 | * overflow detected. note that 'temp' is 37 | * zero-terminated for safety. 38 | * } 39 | * return strdup(temp); 40 | */ 41 | 42 | /* tries to add a character to the buffer, in case of overflow 43 | * this will only write a terminating zero and return buffEnd. 44 | */ 45 | char* buff_addc (char* buff, char* buffEnd, int c); 46 | 47 | /* tries to add a string to the buffer */ 48 | char* buff_adds (char* buff, char* buffEnd, const char* s); 49 | 50 | /* tries to add a bytes to the buffer. the input can contain zero bytes, 51 | * but a terminating zero will always be appended at the end anyway 52 | */ 53 | char* buff_addb (char* buff, char* buffEnd, const void* data, int len); 54 | 55 | /* tries to add a formatted string to a bounded buffer */ 56 | char* buff_add (char* buff, char* buffEnd, const char* format, ... ); 57 | 58 | /* convenience macro used to define a bounded buffer, as well as 59 | * a 'cursor' and 'end' variables all in one go. 60 | * 61 | * note: this doesn't place an initial terminating zero in the buffer, 62 | * you need to use one of the buff_ functions for this. or simply 63 | * do _cursor[0] = 0 manually. 64 | */ 65 | #define BUFF_DECL(_buff,_cursor,_end,_size) \ 66 | char _buff[_size], *_cursor=_buff, *_end = _cursor + (_size) 67 | 68 | #endif /* _ADB_UTILS_H */ 69 | --------------------------------------------------------------------------------