blob: 18e14de87adc71d495182826784ddf501ad128ad [file] [log] [blame]
Dan Albertb302d122015-02-24 15:51:19 -08001/*
2 * Copyright (C) 2015 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
Dan Albertdb6fe642015-03-19 15:21:08 -070017#define TRACE_TAG TRACE_ADB
18
19#include "sysdeps.h"
20#include "adb_client.h"
21
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080022#include <errno.h>
23#include <limits.h>
24#include <stdarg.h>
Dan Albertb302d122015-02-24 15:51:19 -080025#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080028#include <sys/stat.h>
Dan Albertb302d122015-02-24 15:51:19 -080029#include <sys/types.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080030
Elliott Hughes949f2622015-04-27 14:20:17 -070031#include <string>
Elliott Hughes04a98c22015-04-29 08:35:59 -070032#include <vector>
33
34#include <base/stringprintf.h>
Elliott Hughesda945812015-04-29 12:28:13 -070035#include <base/strings.h>
Elliott Hughes949f2622015-04-27 14:20:17 -070036
Dan Albert66a91b02015-02-24 21:26:58 -080037#include "adb_io.h"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080038
Elliott Hughes3aec2ba2015-05-05 13:10:43 -070039static TransportType __adb_transport = kTransportAny;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080040static const char* __adb_serial = NULL;
41
Stefan Hilzingerfb798d92010-04-19 12:21:12 +010042static int __adb_server_port = DEFAULT_ADB_PORT;
Matt Gumbel411775c2012-11-14 10:16:17 -080043static const char* __adb_server_name = NULL;
Stefan Hilzingerfb798d92010-04-19 12:21:12 +010044
Elliott Hughesda945812015-04-29 12:28:13 -070045static std::string perror_str(const char* msg) {
46 return android::base::StringPrintf("%s: %s", msg, strerror(errno));
47}
48
49static bool ReadProtocolString(int fd, std::string* s, std::string* error) {
50 char buf[5];
Elliott Hughesda945812015-04-29 12:28:13 -070051 if (!ReadFdExactly(fd, buf, 4)) {
52 *error = perror_str("protocol fault (couldn't read status length)");
53 return false;
54 }
55 buf[4] = 0;
56
57 unsigned long len = strtoul(buf, 0, 16);
Elliott Hughes88b4c852015-04-30 17:32:03 -070058 s->resize(len, '\0');
Elliott Hughesda945812015-04-29 12:28:13 -070059 if (!ReadFdExactly(fd, &(*s)[0], len)) {
60 *error = perror_str("protocol fault (couldn't read status message)");
61 return false;
62 }
63
64 return true;
65}
66
Elliott Hughes3aec2ba2015-05-05 13:10:43 -070067void adb_set_transport(TransportType type, const char* serial)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080068{
69 __adb_transport = type;
70 __adb_serial = serial;
71}
72
Stefan Hilzingerfb798d92010-04-19 12:21:12 +010073void adb_set_tcp_specifics(int server_port)
74{
75 __adb_server_port = server_port;
76}
77
Matt Gumbel411775c2012-11-14 10:16:17 -080078void adb_set_tcp_name(const char* hostname)
79{
80 __adb_server_name = hostname;
81}
82
Elliott Hughesda945812015-04-29 12:28:13 -070083int adb_get_emulator_console_port() {
84 if (__adb_serial) {
85 // The user specified a serial number; is it an emulator?
86 int port;
87 return (sscanf(__adb_serial, "emulator-%d", &port) == 1) ? port : -1;
88 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080089
Elliott Hughesda945812015-04-29 12:28:13 -070090 // No specific device was given, so get the list of connected
91 // devices and search for emulators. If there's one, we'll
92 // take it. If there are more than one, that's an error.
93 std::string devices;
94 std::string error;
95 if (!adb_query("host:devices", &devices, &error)) {
96 printf("no emulator connected: %s\n", error.c_str());
97 return -1;
98 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080099
Elliott Hughesda945812015-04-29 12:28:13 -0700100 int port;
101 size_t emulator_count = 0;
102 for (auto& device : android::base::Split(devices, "\n")) {
103 if (sscanf(device.c_str(), "emulator-%d", &port) == 1) {
104 if (++emulator_count > 1) {
105 return -2;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800106 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800107 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800108 }
Elliott Hughesda945812015-04-29 12:28:13 -0700109 if (emulator_count == 0) return -1;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800110 return port;
111}
112
Elliott Hughes04a98c22015-04-29 08:35:59 -0700113static int switch_socket_transport(int fd, std::string* error) {
Elliott Hughes949f2622015-04-27 14:20:17 -0700114 std::string service;
115 if (__adb_serial) {
116 service += "host:transport:";
117 service += __adb_serial;
118 } else {
Dan Albertf30d73c2015-02-25 17:51:28 -0800119 const char* transport_type = "???";
Elliott Hughes949f2622015-04-27 14:20:17 -0700120 switch (__adb_transport) {
121 case kTransportUsb:
122 transport_type = "transport-usb";
123 break;
124 case kTransportLocal:
125 transport_type = "transport-local";
126 break;
127 case kTransportAny:
128 transport_type = "transport-any";
129 break;
130 case kTransportHost:
131 // no switch necessary
132 return 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800133 }
Elliott Hughes949f2622015-04-27 14:20:17 -0700134 service += "host:";
135 service += transport_type;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800136 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800137
Elliott Hughes88b4c852015-04-30 17:32:03 -0700138 if (!SendProtocolString(fd, service)) {
Elliott Hughes04a98c22015-04-29 08:35:59 -0700139 *error = perror_str("write failure during connection");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800140 adb_close(fd);
141 return -1;
142 }
143 D("Switch transport in progress\n");
144
Elliott Hughes04a98c22015-04-29 08:35:59 -0700145 if (!adb_status(fd, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800146 adb_close(fd);
Elliott Hughes04a98c22015-04-29 08:35:59 -0700147 D("Switch transport failed: %s\n", error->c_str());
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800148 return -1;
149 }
150 D("Switch transport success\n");
151 return 0;
152}
153
Elliott Hughes04a98c22015-04-29 08:35:59 -0700154bool adb_status(int fd, std::string* error) {
155 char buf[5];
Elliott Hughes04a98c22015-04-29 08:35:59 -0700156 if (!ReadFdExactly(fd, buf, 4)) {
157 *error = perror_str("protocol fault (couldn't read status)");
158 return false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800159 }
160
Elliott Hughes04a98c22015-04-29 08:35:59 -0700161 if (!memcmp(buf, "OKAY", 4)) {
162 return true;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800163 }
164
Elliott Hughes04a98c22015-04-29 08:35:59 -0700165 if (memcmp(buf, "FAIL", 4)) {
166 *error = android::base::StringPrintf("protocol fault (status %02x %02x %02x %02x?!)",
167 buf[0], buf[1], buf[2], buf[3]);
168 return false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800169 }
170
Elliott Hughesda945812015-04-29 12:28:13 -0700171 ReadProtocolString(fd, error, error);
Elliott Hughes04a98c22015-04-29 08:35:59 -0700172 return false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800173}
174
Elliott Hughesda945812015-04-29 12:28:13 -0700175int _adb_connect(const std::string& service, std::string* error) {
176 D("_adb_connect: %s\n", service.c_str());
177 if (service.empty() || service.size() > 1024) {
178 *error = android::base::StringPrintf("bad service name length (%d)",
179 static_cast<int>(service.size()));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800180 return -1;
181 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800182
Elliott Hughesda945812015-04-29 12:28:13 -0700183 int fd;
184 if (__adb_server_name) {
Matt Gumbel411775c2012-11-14 10:16:17 -0800185 fd = socket_network_client(__adb_server_name, __adb_server_port, SOCK_STREAM);
Elliott Hughesda945812015-04-29 12:28:13 -0700186 } else {
Matt Gumbel411775c2012-11-14 10:16:17 -0800187 fd = socket_loopback_client(__adb_server_port, SOCK_STREAM);
Elliott Hughesda945812015-04-29 12:28:13 -0700188 }
189 if (fd < 0) {
Elliott Hughes04a98c22015-04-29 08:35:59 -0700190 *error = perror_str("cannot connect to daemon");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800191 return -2;
192 }
193
Elliott Hughesda945812015-04-29 12:28:13 -0700194 if (memcmp(&service[0],"host",4) != 0 && switch_socket_transport(fd, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800195 return -1;
196 }
197
Elliott Hughes88b4c852015-04-30 17:32:03 -0700198 if(!SendProtocolString(fd, service)) {
Elliott Hughes04a98c22015-04-29 08:35:59 -0700199 *error = perror_str("write failure during connection");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800200 adb_close(fd);
201 return -1;
202 }
203
Elliott Hughes04a98c22015-04-29 08:35:59 -0700204 if (!adb_status(fd, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800205 adb_close(fd);
206 return -1;
207 }
208
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700209 D("_adb_connect: return fd %d\n", fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800210 return fd;
211}
212
Elliott Hughesda945812015-04-29 12:28:13 -0700213int adb_connect(const std::string& service, std::string* error) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800214 // first query the adb server's version
Elliott Hughes04a98c22015-04-29 08:35:59 -0700215 int fd = _adb_connect("host:version", error);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800216
Elliott Hughesda945812015-04-29 12:28:13 -0700217 D("adb_connect: service %s\n", service.c_str());
Elliott Hughes04a98c22015-04-29 08:35:59 -0700218 if (fd == -2 && __adb_server_name) {
Matt Gumbel411775c2012-11-14 10:16:17 -0800219 fprintf(stderr,"** Cannot start server on remote host\n");
220 return fd;
Elliott Hughes04a98c22015-04-29 08:35:59 -0700221 } else if (fd == -2) {
Stefan Hilzingerfb798d92010-04-19 12:21:12 +0100222 fprintf(stdout,"* daemon not running. starting it now on port %d *\n",
223 __adb_server_port);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800224 start_server:
Elliott Hughes04a98c22015-04-29 08:35:59 -0700225 if (launch_server(__adb_server_port)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800226 fprintf(stderr,"* failed to start daemon *\n");
227 return -1;
228 } else {
229 fprintf(stdout,"* daemon started successfully *\n");
230 }
231 /* give the server some time to start properly and detect devices */
Xavier Ducrohet30a40332009-05-21 17:47:43 -0700232 adb_sleep_ms(3000);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800233 // fall through to _adb_connect
234 } else {
235 // if server was running, check its version to make sure it is not out of date
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800236 int version = ADB_SERVER_VERSION - 1;
237
238 // if we have a file descriptor, then parse version result
Elliott Hughes04a98c22015-04-29 08:35:59 -0700239 if (fd >= 0) {
Elliott Hughesda945812015-04-29 12:28:13 -0700240 std::string version_string;
241 if (!ReadProtocolString(fd, &version_string, error)) {
242 goto error;
243 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800244
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800245 adb_close(fd);
246
Elliott Hughesda945812015-04-29 12:28:13 -0700247 if (sscanf(&version_string[0], "%04x", &version) != 1) {
248 goto error;
249 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800250 } else {
251 // if fd is -1, then check for "unknown host service",
252 // which would indicate a version of adb that does not support the version command
Elliott Hughes04a98c22015-04-29 08:35:59 -0700253 if (*error == "unknown host service") {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800254 return fd;
Elliott Hughes04a98c22015-04-29 08:35:59 -0700255 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800256 }
257
Elliott Hughesda945812015-04-29 12:28:13 -0700258 if (version != ADB_SERVER_VERSION) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800259 printf("adb server is out of date. killing...\n");
Elliott Hughes04a98c22015-04-29 08:35:59 -0700260 fd = _adb_connect("host:kill", error);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800261 adb_close(fd);
262
263 /* XXX can we better detect its death? */
264 adb_sleep_ms(2000);
265 goto start_server;
266 }
267 }
268
269 // if the command is start-server, we are done.
Elliott Hughesda945812015-04-29 12:28:13 -0700270 if (service == "host:start-server") {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800271 return 0;
Elliott Hughes04a98c22015-04-29 08:35:59 -0700272 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800273
Elliott Hughes04a98c22015-04-29 08:35:59 -0700274 fd = _adb_connect(service, error);
275 if (fd == -1) {
276 D("_adb_connect error: %s", error->c_str());
Brian Carlstromcad81322013-10-18 13:58:48 -0700277 } else if(fd == -2) {
Matt Gumbel411775c2012-11-14 10:16:17 -0800278 fprintf(stderr,"** daemon still not running\n");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800279 }
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700280 D("adb_connect: return fd %d\n", fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800281
282 return fd;
283error:
284 adb_close(fd);
285 return -1;
286}
287
288
Elliott Hughesda945812015-04-29 12:28:13 -0700289int adb_command(const std::string& service, std::string* error) {
Elliott Hughes04a98c22015-04-29 08:35:59 -0700290 int fd = adb_connect(service, error);
291 if (fd < 0) {
292 fprintf(stderr, "error: %s\n", error->c_str());
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800293 return -1;
294 }
295
Elliott Hughes04a98c22015-04-29 08:35:59 -0700296 if (!adb_status(fd, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800297 adb_close(fd);
298 return -1;
299 }
300
301 return 0;
302}
303
Elliott Hughesda945812015-04-29 12:28:13 -0700304bool adb_query(const std::string& service, std::string* result, std::string* error) {
305 D("adb_query: %s\n", service.c_str());
Elliott Hughes04a98c22015-04-29 08:35:59 -0700306 int fd = adb_connect(service, error);
307 if (fd < 0) {
308 fprintf(stderr,"error: %s\n", error->c_str());
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800309 return 0;
310 }
311
Elliott Hughesda945812015-04-29 12:28:13 -0700312 result->clear();
313 if (!ReadProtocolString(fd, result, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800314 adb_close(fd);
Elliott Hughesda945812015-04-29 12:28:13 -0700315 return false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800316 }
Elliott Hughesda945812015-04-29 12:28:13 -0700317 return true;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800318}