blob: 62f79fa983640e8e5998f13b49f14762802851ff [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
39static transport_type __adb_transport = kTransportAny;
40static 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];
51
52 if (!ReadFdExactly(fd, buf, 4)) {
53 *error = perror_str("protocol fault (couldn't read status length)");
54 return false;
55 }
56 buf[4] = 0;
57
58 unsigned long len = strtoul(buf, 0, 16);
59 s->resize(len + 1, '\0'); // Ensure NUL-termination.
60 if (!ReadFdExactly(fd, &(*s)[0], len)) {
61 *error = perror_str("protocol fault (couldn't read status message)");
62 return false;
63 }
64
65 return true;
66}
67
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080068void adb_set_transport(transport_type type, const char* serial)
69{
70 __adb_transport = type;
71 __adb_serial = serial;
72}
73
Stefan Hilzingerfb798d92010-04-19 12:21:12 +010074void adb_set_tcp_specifics(int server_port)
75{
76 __adb_server_port = server_port;
77}
78
Matt Gumbel411775c2012-11-14 10:16:17 -080079void adb_set_tcp_name(const char* hostname)
80{
81 __adb_server_name = hostname;
82}
83
Elliott Hughesda945812015-04-29 12:28:13 -070084int adb_get_emulator_console_port() {
85 if (__adb_serial) {
86 // The user specified a serial number; is it an emulator?
87 int port;
88 return (sscanf(__adb_serial, "emulator-%d", &port) == 1) ? port : -1;
89 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080090
Elliott Hughesda945812015-04-29 12:28:13 -070091 // No specific device was given, so get the list of connected
92 // devices and search for emulators. If there's one, we'll
93 // take it. If there are more than one, that's an error.
94 std::string devices;
95 std::string error;
96 if (!adb_query("host:devices", &devices, &error)) {
97 printf("no emulator connected: %s\n", error.c_str());
98 return -1;
99 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800100
Elliott Hughesda945812015-04-29 12:28:13 -0700101 int port;
102 size_t emulator_count = 0;
103 for (auto& device : android::base::Split(devices, "\n")) {
104 if (sscanf(device.c_str(), "emulator-%d", &port) == 1) {
105 if (++emulator_count > 1) {
106 return -2;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800107 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800108 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800109 }
Elliott Hughesda945812015-04-29 12:28:13 -0700110 if (emulator_count == 0) return -1;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800111 return port;
112}
113
Elliott Hughes04a98c22015-04-29 08:35:59 -0700114static int switch_socket_transport(int fd, std::string* error) {
Elliott Hughes949f2622015-04-27 14:20:17 -0700115 std::string service;
116 if (__adb_serial) {
117 service += "host:transport:";
118 service += __adb_serial;
119 } else {
Dan Albertf30d73c2015-02-25 17:51:28 -0800120 const char* transport_type = "???";
Elliott Hughes949f2622015-04-27 14:20:17 -0700121 switch (__adb_transport) {
122 case kTransportUsb:
123 transport_type = "transport-usb";
124 break;
125 case kTransportLocal:
126 transport_type = "transport-local";
127 break;
128 case kTransportAny:
129 transport_type = "transport-any";
130 break;
131 case kTransportHost:
132 // no switch necessary
133 return 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800134 }
Elliott Hughes949f2622015-04-27 14:20:17 -0700135 service += "host:";
136 service += transport_type;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800137 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800138
Elliott Hughes949f2622015-04-27 14:20:17 -0700139 char tmp[5];
140 snprintf(tmp, sizeof(tmp), "%04zx", service.size());
141 if (!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, service.c_str(), service.size())) {
Elliott Hughes04a98c22015-04-29 08:35:59 -0700142 *error = perror_str("write failure during connection");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800143 adb_close(fd);
144 return -1;
145 }
146 D("Switch transport in progress\n");
147
Elliott Hughes04a98c22015-04-29 08:35:59 -0700148 if (!adb_status(fd, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800149 adb_close(fd);
Elliott Hughes04a98c22015-04-29 08:35:59 -0700150 D("Switch transport failed: %s\n", error->c_str());
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800151 return -1;
152 }
153 D("Switch transport success\n");
154 return 0;
155}
156
Elliott Hughes04a98c22015-04-29 08:35:59 -0700157bool adb_status(int fd, std::string* error) {
158 char buf[5];
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800159
Elliott Hughes04a98c22015-04-29 08:35:59 -0700160 if (!ReadFdExactly(fd, buf, 4)) {
161 *error = perror_str("protocol fault (couldn't read status)");
162 return false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800163 }
164
Elliott Hughes04a98c22015-04-29 08:35:59 -0700165 if (!memcmp(buf, "OKAY", 4)) {
166 return true;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800167 }
168
Elliott Hughes04a98c22015-04-29 08:35:59 -0700169 if (memcmp(buf, "FAIL", 4)) {
170 *error = android::base::StringPrintf("protocol fault (status %02x %02x %02x %02x?!)",
171 buf[0], buf[1], buf[2], buf[3]);
172 return false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800173 }
174
Elliott Hughesda945812015-04-29 12:28:13 -0700175 ReadProtocolString(fd, error, error);
Elliott Hughes04a98c22015-04-29 08:35:59 -0700176 return false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800177}
178
Elliott Hughesda945812015-04-29 12:28:13 -0700179int _adb_connect(const std::string& service, std::string* error) {
180 D("_adb_connect: %s\n", service.c_str());
181 if (service.empty() || service.size() > 1024) {
182 *error = android::base::StringPrintf("bad service name length (%d)",
183 static_cast<int>(service.size()));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800184 return -1;
185 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800186
Elliott Hughesda945812015-04-29 12:28:13 -0700187 int fd;
188 if (__adb_server_name) {
Matt Gumbel411775c2012-11-14 10:16:17 -0800189 fd = socket_network_client(__adb_server_name, __adb_server_port, SOCK_STREAM);
Elliott Hughesda945812015-04-29 12:28:13 -0700190 } else {
Matt Gumbel411775c2012-11-14 10:16:17 -0800191 fd = socket_loopback_client(__adb_server_port, SOCK_STREAM);
Elliott Hughesda945812015-04-29 12:28:13 -0700192 }
193 if (fd < 0) {
Elliott Hughes04a98c22015-04-29 08:35:59 -0700194 *error = perror_str("cannot connect to daemon");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800195 return -2;
196 }
197
Elliott Hughesda945812015-04-29 12:28:13 -0700198 if (memcmp(&service[0],"host",4) != 0 && switch_socket_transport(fd, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800199 return -1;
200 }
201
Elliott Hughesda945812015-04-29 12:28:13 -0700202 char tmp[5];
203 snprintf(tmp, sizeof(tmp), "%04zx", service.size());
204 if(!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, &service[0], service.size())) {
Elliott Hughes04a98c22015-04-29 08:35:59 -0700205 *error = perror_str("write failure during connection");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800206 adb_close(fd);
207 return -1;
208 }
209
Elliott Hughes04a98c22015-04-29 08:35:59 -0700210 if (!adb_status(fd, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800211 adb_close(fd);
212 return -1;
213 }
214
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700215 D("_adb_connect: return fd %d\n", fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800216 return fd;
217}
218
Elliott Hughesda945812015-04-29 12:28:13 -0700219int adb_connect(const std::string& service, std::string* error) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800220 // first query the adb server's version
Elliott Hughes04a98c22015-04-29 08:35:59 -0700221 int fd = _adb_connect("host:version", error);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800222
Elliott Hughesda945812015-04-29 12:28:13 -0700223 D("adb_connect: service %s\n", service.c_str());
Elliott Hughes04a98c22015-04-29 08:35:59 -0700224 if (fd == -2 && __adb_server_name) {
Matt Gumbel411775c2012-11-14 10:16:17 -0800225 fprintf(stderr,"** Cannot start server on remote host\n");
226 return fd;
Elliott Hughes04a98c22015-04-29 08:35:59 -0700227 } else if (fd == -2) {
Stefan Hilzingerfb798d92010-04-19 12:21:12 +0100228 fprintf(stdout,"* daemon not running. starting it now on port %d *\n",
229 __adb_server_port);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800230 start_server:
Elliott Hughes04a98c22015-04-29 08:35:59 -0700231 if (launch_server(__adb_server_port)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800232 fprintf(stderr,"* failed to start daemon *\n");
233 return -1;
234 } else {
235 fprintf(stdout,"* daemon started successfully *\n");
236 }
237 /* give the server some time to start properly and detect devices */
Xavier Ducrohet30a40332009-05-21 17:47:43 -0700238 adb_sleep_ms(3000);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800239 // fall through to _adb_connect
240 } else {
241 // 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 -0800242 int version = ADB_SERVER_VERSION - 1;
243
244 // if we have a file descriptor, then parse version result
Elliott Hughes04a98c22015-04-29 08:35:59 -0700245 if (fd >= 0) {
Elliott Hughesda945812015-04-29 12:28:13 -0700246 std::string version_string;
247 if (!ReadProtocolString(fd, &version_string, error)) {
248 goto error;
249 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800250
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800251 adb_close(fd);
252
Elliott Hughesda945812015-04-29 12:28:13 -0700253 if (sscanf(&version_string[0], "%04x", &version) != 1) {
254 goto error;
255 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800256 } else {
257 // if fd is -1, then check for "unknown host service",
258 // which would indicate a version of adb that does not support the version command
Elliott Hughes04a98c22015-04-29 08:35:59 -0700259 if (*error == "unknown host service") {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800260 return fd;
Elliott Hughes04a98c22015-04-29 08:35:59 -0700261 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800262 }
263
Elliott Hughesda945812015-04-29 12:28:13 -0700264 if (version != ADB_SERVER_VERSION) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800265 printf("adb server is out of date. killing...\n");
Elliott Hughes04a98c22015-04-29 08:35:59 -0700266 fd = _adb_connect("host:kill", error);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800267 adb_close(fd);
268
269 /* XXX can we better detect its death? */
270 adb_sleep_ms(2000);
271 goto start_server;
272 }
273 }
274
275 // if the command is start-server, we are done.
Elliott Hughesda945812015-04-29 12:28:13 -0700276 if (service == "host:start-server") {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800277 return 0;
Elliott Hughes04a98c22015-04-29 08:35:59 -0700278 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800279
Elliott Hughes04a98c22015-04-29 08:35:59 -0700280 fd = _adb_connect(service, error);
281 if (fd == -1) {
282 D("_adb_connect error: %s", error->c_str());
Brian Carlstromcad81322013-10-18 13:58:48 -0700283 } else if(fd == -2) {
Matt Gumbel411775c2012-11-14 10:16:17 -0800284 fprintf(stderr,"** daemon still not running\n");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800285 }
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700286 D("adb_connect: return fd %d\n", fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800287
288 return fd;
289error:
290 adb_close(fd);
291 return -1;
292}
293
294
Elliott Hughesda945812015-04-29 12:28:13 -0700295int adb_command(const std::string& service, std::string* error) {
Elliott Hughes04a98c22015-04-29 08:35:59 -0700296 int fd = adb_connect(service, error);
297 if (fd < 0) {
298 fprintf(stderr, "error: %s\n", error->c_str());
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800299 return -1;
300 }
301
Elliott Hughes04a98c22015-04-29 08:35:59 -0700302 if (!adb_status(fd, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800303 adb_close(fd);
304 return -1;
305 }
306
307 return 0;
308}
309
Elliott Hughesda945812015-04-29 12:28:13 -0700310bool adb_query(const std::string& service, std::string* result, std::string* error) {
311 D("adb_query: %s\n", service.c_str());
Elliott Hughes04a98c22015-04-29 08:35:59 -0700312 int fd = adb_connect(service, error);
313 if (fd < 0) {
314 fprintf(stderr,"error: %s\n", error->c_str());
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800315 return 0;
316 }
317
Elliott Hughesda945812015-04-29 12:28:13 -0700318 result->clear();
319 if (!ReadProtocolString(fd, result, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800320 adb_close(fd);
Elliott Hughesda945812015-04-29 12:28:13 -0700321 return false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800322 }
Elliott Hughesda945812015-04-29 12:28:13 -0700323 return true;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800324}