blob: 33eee82d63b29f1642ade85d1815bc2019527947 [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);
Elliott Hughes88b4c852015-04-30 17:32:03 -070059 s->resize(len, '\0');
Elliott Hughesda945812015-04-29 12:28:13 -070060 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 Hughes88b4c852015-04-30 17:32:03 -0700139 if (!SendProtocolString(fd, service)) {
Elliott Hughes04a98c22015-04-29 08:35:59 -0700140 *error = perror_str("write failure during connection");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800141 adb_close(fd);
142 return -1;
143 }
144 D("Switch transport in progress\n");
145
Elliott Hughes04a98c22015-04-29 08:35:59 -0700146 if (!adb_status(fd, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800147 adb_close(fd);
Elliott Hughes04a98c22015-04-29 08:35:59 -0700148 D("Switch transport failed: %s\n", error->c_str());
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800149 return -1;
150 }
151 D("Switch transport success\n");
152 return 0;
153}
154
Elliott Hughes04a98c22015-04-29 08:35:59 -0700155bool adb_status(int fd, std::string* error) {
156 char buf[5];
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800157
Elliott Hughes04a98c22015-04-29 08:35:59 -0700158 if (!ReadFdExactly(fd, buf, 4)) {
159 *error = perror_str("protocol fault (couldn't read status)");
160 return false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800161 }
162
Elliott Hughes04a98c22015-04-29 08:35:59 -0700163 if (!memcmp(buf, "OKAY", 4)) {
164 return true;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800165 }
166
Elliott Hughes04a98c22015-04-29 08:35:59 -0700167 if (memcmp(buf, "FAIL", 4)) {
168 *error = android::base::StringPrintf("protocol fault (status %02x %02x %02x %02x?!)",
169 buf[0], buf[1], buf[2], buf[3]);
170 return false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800171 }
172
Elliott Hughesda945812015-04-29 12:28:13 -0700173 ReadProtocolString(fd, error, error);
Elliott Hughes04a98c22015-04-29 08:35:59 -0700174 return false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800175}
176
Elliott Hughesda945812015-04-29 12:28:13 -0700177int _adb_connect(const std::string& service, std::string* error) {
178 D("_adb_connect: %s\n", service.c_str());
179 if (service.empty() || service.size() > 1024) {
180 *error = android::base::StringPrintf("bad service name length (%d)",
181 static_cast<int>(service.size()));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800182 return -1;
183 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800184
Elliott Hughesda945812015-04-29 12:28:13 -0700185 int fd;
186 if (__adb_server_name) {
Matt Gumbel411775c2012-11-14 10:16:17 -0800187 fd = socket_network_client(__adb_server_name, __adb_server_port, SOCK_STREAM);
Elliott Hughesda945812015-04-29 12:28:13 -0700188 } else {
Matt Gumbel411775c2012-11-14 10:16:17 -0800189 fd = socket_loopback_client(__adb_server_port, SOCK_STREAM);
Elliott Hughesda945812015-04-29 12:28:13 -0700190 }
191 if (fd < 0) {
Elliott Hughes04a98c22015-04-29 08:35:59 -0700192 *error = perror_str("cannot connect to daemon");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800193 return -2;
194 }
195
Elliott Hughesda945812015-04-29 12:28:13 -0700196 if (memcmp(&service[0],"host",4) != 0 && switch_socket_transport(fd, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800197 return -1;
198 }
199
Elliott Hughes88b4c852015-04-30 17:32:03 -0700200 if(!SendProtocolString(fd, service)) {
Elliott Hughes04a98c22015-04-29 08:35:59 -0700201 *error = perror_str("write failure during connection");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800202 adb_close(fd);
203 return -1;
204 }
205
Elliott Hughes04a98c22015-04-29 08:35:59 -0700206 if (!adb_status(fd, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800207 adb_close(fd);
208 return -1;
209 }
210
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700211 D("_adb_connect: return fd %d\n", fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800212 return fd;
213}
214
Elliott Hughesda945812015-04-29 12:28:13 -0700215int adb_connect(const std::string& service, std::string* error) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800216 // first query the adb server's version
Elliott Hughes04a98c22015-04-29 08:35:59 -0700217 int fd = _adb_connect("host:version", error);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800218
Elliott Hughesda945812015-04-29 12:28:13 -0700219 D("adb_connect: service %s\n", service.c_str());
Elliott Hughes04a98c22015-04-29 08:35:59 -0700220 if (fd == -2 && __adb_server_name) {
Matt Gumbel411775c2012-11-14 10:16:17 -0800221 fprintf(stderr,"** Cannot start server on remote host\n");
222 return fd;
Elliott Hughes04a98c22015-04-29 08:35:59 -0700223 } else if (fd == -2) {
Stefan Hilzingerfb798d92010-04-19 12:21:12 +0100224 fprintf(stdout,"* daemon not running. starting it now on port %d *\n",
225 __adb_server_port);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800226 start_server:
Elliott Hughes04a98c22015-04-29 08:35:59 -0700227 if (launch_server(__adb_server_port)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800228 fprintf(stderr,"* failed to start daemon *\n");
229 return -1;
230 } else {
231 fprintf(stdout,"* daemon started successfully *\n");
232 }
233 /* give the server some time to start properly and detect devices */
Xavier Ducrohet30a40332009-05-21 17:47:43 -0700234 adb_sleep_ms(3000);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800235 // fall through to _adb_connect
236 } else {
237 // 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 -0800238 int version = ADB_SERVER_VERSION - 1;
239
240 // if we have a file descriptor, then parse version result
Elliott Hughes04a98c22015-04-29 08:35:59 -0700241 if (fd >= 0) {
Elliott Hughesda945812015-04-29 12:28:13 -0700242 std::string version_string;
243 if (!ReadProtocolString(fd, &version_string, error)) {
244 goto error;
245 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800246
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800247 adb_close(fd);
248
Elliott Hughesda945812015-04-29 12:28:13 -0700249 if (sscanf(&version_string[0], "%04x", &version) != 1) {
250 goto error;
251 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800252 } else {
253 // if fd is -1, then check for "unknown host service",
254 // which would indicate a version of adb that does not support the version command
Elliott Hughes04a98c22015-04-29 08:35:59 -0700255 if (*error == "unknown host service") {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800256 return fd;
Elliott Hughes04a98c22015-04-29 08:35:59 -0700257 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800258 }
259
Elliott Hughesda945812015-04-29 12:28:13 -0700260 if (version != ADB_SERVER_VERSION) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800261 printf("adb server is out of date. killing...\n");
Elliott Hughes04a98c22015-04-29 08:35:59 -0700262 fd = _adb_connect("host:kill", error);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800263 adb_close(fd);
264
265 /* XXX can we better detect its death? */
266 adb_sleep_ms(2000);
267 goto start_server;
268 }
269 }
270
271 // if the command is start-server, we are done.
Elliott Hughesda945812015-04-29 12:28:13 -0700272 if (service == "host:start-server") {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800273 return 0;
Elliott Hughes04a98c22015-04-29 08:35:59 -0700274 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800275
Elliott Hughes04a98c22015-04-29 08:35:59 -0700276 fd = _adb_connect(service, error);
277 if (fd == -1) {
278 D("_adb_connect error: %s", error->c_str());
Brian Carlstromcad81322013-10-18 13:58:48 -0700279 } else if(fd == -2) {
Matt Gumbel411775c2012-11-14 10:16:17 -0800280 fprintf(stderr,"** daemon still not running\n");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800281 }
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700282 D("adb_connect: return fd %d\n", fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800283
284 return fd;
285error:
286 adb_close(fd);
287 return -1;
288}
289
290
Elliott Hughesda945812015-04-29 12:28:13 -0700291int adb_command(const std::string& service, std::string* error) {
Elliott Hughes04a98c22015-04-29 08:35:59 -0700292 int fd = adb_connect(service, error);
293 if (fd < 0) {
294 fprintf(stderr, "error: %s\n", error->c_str());
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800295 return -1;
296 }
297
Elliott Hughes04a98c22015-04-29 08:35:59 -0700298 if (!adb_status(fd, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800299 adb_close(fd);
300 return -1;
301 }
302
303 return 0;
304}
305
Elliott Hughesda945812015-04-29 12:28:13 -0700306bool adb_query(const std::string& service, std::string* result, std::string* error) {
307 D("adb_query: %s\n", service.c_str());
Elliott Hughes04a98c22015-04-29 08:35:59 -0700308 int fd = adb_connect(service, error);
309 if (fd < 0) {
310 fprintf(stderr,"error: %s\n", error->c_str());
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800311 return 0;
312 }
313
Elliott Hughesda945812015-04-29 12:28:13 -0700314 result->clear();
315 if (!ReadProtocolString(fd, result, error)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800316 adb_close(fd);
Elliott Hughesda945812015-04-29 12:28:13 -0700317 return false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800318 }
Elliott Hughesda945812015-04-29 12:28:13 -0700319 return true;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800320}