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 #define TRACE_TAG SERVICES 18 19 #include "sysdeps.h" 20 21 #include <errno.h> 22 #include <stddef.h> 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 27 #include <cstring> 28 #include <thread> 29 30 #include <android-base/stringprintf.h> 31 #include <android-base/strings.h> 32 #include <cutils/sockets.h> 33 34 #include "adb.h" 35 #include "adb_io.h" 36 #include "adb_unique_fd.h" 37 #include "adb_utils.h" 38 #include "adb_wifi.h" 39 #include "services.h" 40 #include "socket_spec.h" 41 #include "sysdeps.h" 42 #include "transport.h" 43 44 namespace { 45 46 void service_bootstrap_func(std::string service_name, std::function<void(unique_fd)> func, 47 unique_fd fd) { 48 adb_thread_setname(android::base::StringPrintf("%s svc %d", service_name.c_str(), fd.get())); 49 func(std::move(fd)); 50 } 51 52 } // namespace 53 54 unique_fd create_service_thread(const char* service_name, std::function<void(unique_fd)> func) { 55 int s[2]; 56 if (adb_socketpair(s)) { 57 printf("cannot create service socket pair\n"); 58 return unique_fd(); 59 } 60 D("socketpair: (%d,%d)", s[0], s[1]); 61 62 #if !ADB_HOST 63 if (strcmp(service_name, "sync") == 0) { 64 // Set file sync service socket to maximum size 65 int max_buf = LINUX_MAX_SOCKET_SIZE; 66 adb_setsockopt(s[0], SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf)); 67 adb_setsockopt(s[1], SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf)); 68 } 69 #endif // !ADB_HOST 70 71 std::thread(service_bootstrap_func, service_name, func, unique_fd(s[1])).detach(); 72 73 D("service thread started, %d:%d", s[0], s[1]); 74 return unique_fd(s[0]); 75 } 76 77 unique_fd service_to_fd(std::string_view name, atransport* transport) { 78 unique_fd ret; 79 80 if (is_socket_spec(name)) { 81 std::string error; 82 if (!socket_spec_connect(&ret, name, nullptr, nullptr, &error)) { 83 LOG(ERROR) << "failed to connect to socket '" << name << "': " << error; 84 } 85 } else { 86 #if !ADB_HOST 87 ret = daemon_service_to_fd(name, transport); 88 #endif 89 } 90 91 if (ret >= 0) { 92 close_on_exec(ret.get()); 93 } 94 return ret; 95 } 96 97 #if ADB_HOST 98 void connect_emulator(const std::string& port_spec, std::string* response) { 99 std::vector<std::string> pieces = android::base::Split(port_spec, ","); 100 if (pieces.size() != 2) { 101 *response = android::base::StringPrintf("unable to parse '%s' as <console port>,<adb port>", 102 port_spec.c_str()); 103 return; 104 } 105 106 int console_port = strtol(pieces[0].c_str(), nullptr, 0); 107 int adb_port = strtol(pieces[1].c_str(), nullptr, 0); 108 if (console_port <= 0 || adb_port <= 0) { 109 *response = android::base::StringPrintf("Invalid port numbers: %s", port_spec.c_str()); 110 return; 111 } 112 113 // Check if the emulator is already known. 114 // Note: There's a small but harmless race condition here: An emulator not 115 // present just yet could be registered by another invocation right 116 // after doing this check here. However, local_connect protects 117 // against double-registration too. From here, a better error message 118 // can be produced. In the case of the race condition, the very specific 119 // error message won't be shown, but the data doesn't get corrupted. 120 atransport* known_emulator = find_emulator_transport_by_adb_port(adb_port); 121 if (known_emulator != nullptr) { 122 *response = android::base::StringPrintf("Emulator already registered on port %d", adb_port); 123 return; 124 } 125 126 // Preconditions met, try to connect to the emulator. 127 std::string error; 128 if (!local_connect_arbitrary_ports(console_port, adb_port, &error)) { 129 *response = android::base::StringPrintf("Connected to emulator on ports %d,%d", 130 console_port, adb_port); 131 } else { 132 *response = android::base::StringPrintf("Could not connect to emulator on ports %d,%d: %s", 133 console_port, adb_port, error.c_str()); 134 } 135 } 136 137 static void connect_service(unique_fd fd, std::string host) { 138 std::string response; 139 if (!strncmp(host.c_str(), "emu:", 4)) { 140 connect_emulator(host.c_str() + 4, &response); 141 } else { 142 connect_device(host, &response); 143 } 144 145 // Send response for emulator and device 146 SendProtocolString(fd.get(), response); 147 } 148 149 static void pair_service(unique_fd fd, std::string host, std::string password) { 150 std::string response; 151 adb_wifi_pair_device(host, password, response); 152 SendProtocolString(fd.get(), response); 153 } 154 155 static void wait_service(unique_fd fd, std::string serial, TransportId transport_id, 156 std::string spec) { 157 std::vector<std::string> components = android::base::Split(spec, "-"); 158 if (components.size() < 2) { 159 SendFail(fd, "short wait-for-: " + spec); 160 return; 161 } 162 163 TransportType transport_type; 164 if (components[0] == "local") { 165 transport_type = kTransportLocal; 166 } else if (components[0] == "usb") { 167 transport_type = kTransportUsb; 168 } else if (components[0] == "any") { 169 transport_type = kTransportAny; 170 } else { 171 SendFail(fd, "bad wait-for- transport: " + spec); 172 return; 173 } 174 175 std::vector<ConnectionState> states; 176 for (size_t i = 1; i < components.size(); ++i) { 177 if (components[i] == "device") { 178 states.push_back(kCsDevice); 179 } else if (components[i] == "recovery") { 180 states.push_back(kCsRecovery); 181 } else if (components[i] == "rescue") { 182 states.push_back(kCsRescue); 183 } else if (components[i] == "sideload") { 184 states.push_back(kCsSideload); 185 } else if (components[i] == "bootloader") { 186 states.push_back(kCsBootloader); 187 } else if (components[i] == "any") { 188 states.push_back(kCsAny); 189 } else if (components[i] == "disconnect") { 190 states.push_back(kCsOffline); 191 } else { 192 SendFail(fd, "bad wait-for- state: " + spec); 193 return; 194 } 195 } 196 197 while (true) { 198 bool is_ambiguous = false; 199 std::string error = "unknown error"; 200 atransport* t = 201 acquire_one_transport(transport_type, !serial.empty() ? serial.c_str() : nullptr, 202 transport_id, &is_ambiguous, &error); 203 204 for (const auto& state : states) { 205 if (state == kCsOffline) { 206 // Special case for wait-for-disconnect: 207 // We want to wait for USB devices to completely disappear, but TCP devices can 208 // go into the offline state, since we automatically reconnect. 209 if (!t) { 210 SendOkay(fd); 211 return; 212 } else if (!t->GetUsbHandle()) { 213 SendOkay(fd); 214 return; 215 } 216 } else { 217 if (t && (state == kCsAny || state == t->GetConnectionState())) { 218 SendOkay(fd); 219 return; 220 } 221 } 222 } 223 224 if (is_ambiguous) { 225 SendFail(fd, error); 226 return; 227 } 228 229 // Sleep before retrying. 230 adb_pollfd pfd = {.fd = fd.get(), .events = POLLIN}; 231 if (adb_poll(&pfd, 1, 100) != 0) { 232 // The other end of the socket is closed, probably because the 233 // client terminated. Bail out. 234 SendFail(fd, error); 235 return; 236 } 237 } 238 } 239 #endif 240 241 #if ADB_HOST 242 asocket* host_service_to_socket(std::string_view name, std::string_view serial, 243 TransportId transport_id) { 244 if (name == "track-devices") { 245 return create_device_tracker(false); 246 } else if (name == "track-devices-l") { 247 return create_device_tracker(true); 248 } else if (android::base::ConsumePrefix(&name, "wait-for-")) { 249 std::string spec(name); 250 unique_fd fd = 251 create_service_thread("wait", std::bind(wait_service, std::placeholders::_1, 252 std::string(serial), transport_id, spec)); 253 return create_local_socket(std::move(fd)); 254 } else if (android::base::ConsumePrefix(&name, "connect:")) { 255 std::string host(name); 256 unique_fd fd = create_service_thread( 257 "connect", std::bind(connect_service, std::placeholders::_1, host)); 258 return create_local_socket(std::move(fd)); 259 } else if (android::base::ConsumePrefix(&name, "pair:")) { 260 const char* divider = strchr(name.data(), ':'); 261 if (!divider) { 262 return nullptr; 263 } 264 std::string password(name.data(), divider); 265 std::string host(divider + 1); 266 unique_fd fd = create_service_thread( 267 "pair", std::bind(pair_service, std::placeholders::_1, host, password)); 268 return create_local_socket(std::move(fd)); 269 } 270 return nullptr; 271 } 272 #endif /* ADB_HOST */ 273