blob: 97ce12562ce9d2c005ba050bdf5a1b431087fcae [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001/*
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
Dan Albert33134262015-03-19 15:21:08 -070017#define TRACE_TAG TRACE_ADB
18
19#include "sysdeps.h"
20#include "adb.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080021
Dan Albertea2175a2015-03-08 21:12:08 -070022#include <ctype.h>
23#include <errno.h>
24#include <stdarg.h>
25#include <stddef.h>
26#include <stdint.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080027#include <stdio.h>
28#include <stdlib.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080029#include <string.h>
Mike Lockwood1f546e62009-05-25 18:17:55 -040030#include <sys/time.h>
Dan Albertea2175a2015-03-08 21:12:08 -070031#include <time.h>
32
33#include <string>
Dan Alberte2462192015-03-19 13:25:27 -070034#include <vector>
35#include <unordered_map>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080036
Dan Albert9313c0d2015-05-21 13:58:50 -070037#include <base/logging.h>
Elliott Hughes7b506092015-04-20 08:09:20 -070038#include <base/stringprintf.h>
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -070039#include <base/strings.h>
Elliott Hughes7b506092015-04-20 08:09:20 -070040
Benoit Gobyd5fcafa2012-04-12 12:23:49 -070041#include "adb_auth.h"
Dan Albertcc731cc2015-02-24 21:26:58 -080042#include "adb_io.h"
Dan Alberte9fca142015-02-18 18:03:26 -080043#include "adb_listeners.h"
Elliott Hughes3d5f60d2015-07-18 12:21:30 -070044#include "adb_utils.h"
Dan Albert76649012015-02-24 15:51:19 -080045#include "transport.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080046
Scott Andersone82c2db2012-05-25 14:10:02 -070047#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
48
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080049#if !ADB_HOST
Nick Kralevich893a4a42013-05-23 09:54:13 -070050#include <cutils/properties.h>
Nick Kraleviche2864bf2013-02-28 14:12:58 -080051#include <sys/capability.h>
Jeff Sharkey885342a2012-08-14 21:00:22 -070052#include <sys/mount.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080053#endif
54
Dan Albert9313c0d2015-05-21 13:58:50 -070055ADB_MUTEX_DEFINE(D_lock);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080056
57int HOST = 0;
58
Scott Andersone82c2db2012-05-25 14:10:02 -070059#if !ADB_HOST
Dan Albert9313c0d2015-05-21 13:58:50 -070060const char* adb_device_banner = "device";
61static android::base::LogdLogger gLogdLogger;
Scott Andersone82c2db2012-05-25 14:10:02 -070062#endif
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080063
Dan Albert9313c0d2015-05-21 13:58:50 -070064void AdbLogger(android::base::LogId id, android::base::LogSeverity severity,
65 const char* tag, const char* file, unsigned int line,
66 const char* message) {
67 android::base::StderrLogger(id, severity, tag, file, line, message);
68#if !ADB_HOST
69 gLogdLogger(id, severity, tag, file, line, message);
70#endif
71}
72
73void fatal(const char *fmt, ...) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080074 va_list ap;
75 va_start(ap, fmt);
76 fprintf(stderr, "error: ");
77 vfprintf(stderr, fmt, ap);
78 fprintf(stderr, "\n");
79 va_end(ap);
80 exit(-1);
81}
82
Dan Albert9313c0d2015-05-21 13:58:50 -070083void fatal_errno(const char* fmt, ...) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080084 va_list ap;
85 va_start(ap, fmt);
86 fprintf(stderr, "error: %s: ", strerror(errno));
87 vfprintf(stderr, fmt, ap);
88 fprintf(stderr, "\n");
89 va_end(ap);
90 exit(-1);
91}
92
Dan Albertea2175a2015-03-08 21:12:08 -070093#if !ADB_HOST
Dan Albert9313c0d2015-05-21 13:58:50 -070094static std::string get_log_file_name() {
Dan Albertea2175a2015-03-08 21:12:08 -070095 struct tm now;
96 time_t t;
97 tzset();
98 time(&t);
99 localtime_r(&t, &now);
100
Dan Albert8743ef92015-03-19 22:53:30 -0700101 char timestamp[PATH_MAX];
102 strftime(timestamp, sizeof(timestamp), "%Y-%m-%d-%H-%M-%S", &now);
Dan Albertea2175a2015-03-08 21:12:08 -0700103
Dan Albert9313c0d2015-05-21 13:58:50 -0700104 return android::base::StringPrintf("/data/adb/adb-%s-%d", timestamp,
105 getpid());
106}
107
108void start_device_log(void) {
109 int fd = unix_open(get_log_file_name().c_str(),
110 O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640);
Dan Albertea2175a2015-03-08 21:12:08 -0700111 if (fd == -1) {
112 return;
113 }
114
Dan Albert9313c0d2015-05-21 13:58:50 -0700115 // Redirect stdout and stderr to the log file.
Dan Albertea2175a2015-03-08 21:12:08 -0700116 dup2(fd, STDOUT_FILENO);
117 dup2(fd, STDERR_FILENO);
118 fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid());
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700119 unix_close(fd);
Dan Albertea2175a2015-03-08 21:12:08 -0700120}
121#endif
122
123int adb_trace_mask;
124
125std::string get_trace_setting_from_env() {
126 const char* setting = getenv("ADB_TRACE");
127 if (setting == nullptr) {
128 setting = "";
129 }
130
131 return std::string(setting);
132}
133
134#if !ADB_HOST
135std::string get_trace_setting_from_prop() {
136 char buf[PROPERTY_VALUE_MAX];
137 property_get("persist.adb.trace_mask", buf, "");
138 return std::string(buf);
139}
140#endif
141
142std::string get_trace_setting() {
143#if ADB_HOST
144 return get_trace_setting_from_env();
145#else
146 return get_trace_setting_from_prop();
147#endif
148}
149
Dan Alberte2462192015-03-19 13:25:27 -0700150// Split the space separated list of tags from the trace setting and build the
151// trace mask from it. note that '1' and 'all' are special cases to enable all
152// tracing.
Dan Albertea2175a2015-03-08 21:12:08 -0700153//
154// adb's trace setting comes from the ADB_TRACE environment variable, whereas
155// adbd's comes from the system property persist.adb.trace_mask.
Dan Albert9313c0d2015-05-21 13:58:50 -0700156static void setup_trace_mask() {
Dan Albertea2175a2015-03-08 21:12:08 -0700157 const std::string trace_setting = get_trace_setting();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800158
Dan Alberte2462192015-03-19 13:25:27 -0700159 std::unordered_map<std::string, int> trace_flags = {
160 {"1", 0},
161 {"all", 0},
162 {"adb", TRACE_ADB},
163 {"sockets", TRACE_SOCKETS},
164 {"packets", TRACE_PACKETS},
165 {"rwx", TRACE_RWX},
166 {"usb", TRACE_USB},
167 {"sync", TRACE_SYNC},
168 {"sysdeps", TRACE_SYSDEPS},
169 {"transport", TRACE_TRANSPORT},
170 {"jdwp", TRACE_JDWP},
171 {"services", TRACE_SERVICES},
172 {"auth", TRACE_AUTH}};
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800173
Dan Alberte2462192015-03-19 13:25:27 -0700174 std::vector<std::string> elements = android::base::Split(trace_setting, " ");
175 for (const auto& elem : elements) {
176 const auto& flag = trace_flags.find(elem);
177 if (flag == trace_flags.end()) {
Spencer Low8d8126a2015-07-21 02:06:26 -0700178 D("Unknown trace flag: %s\n", flag->first.c_str());
Dan Alberte2462192015-03-19 13:25:27 -0700179 continue;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800180 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800181
Dan Alberte2462192015-03-19 13:25:27 -0700182 if (flag->second == 0) {
183 // 0 is used for the special values "1" and "all" that enable all
184 // tracing.
185 adb_trace_mask = ~0;
186 return;
187 } else {
188 adb_trace_mask |= 1 << flag->second;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800189 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800190 }
Dan Albert9313c0d2015-05-21 13:58:50 -0700191}
Dan Albertea2175a2015-03-08 21:12:08 -0700192
Dan Albert9313c0d2015-05-21 13:58:50 -0700193void adb_trace_init(char** argv) {
Paul Lawrence6f009d92015-06-05 16:00:07 -0700194 // Don't open log file if no tracing, since this will block
195 // the crypto unmount of /data
196 const std::string trace_setting = get_trace_setting();
197 if (trace_setting.empty()) {
198 return;
199 }
200
Dan Albertea2175a2015-03-08 21:12:08 -0700201#if !ADB_HOST
Dan Albert9313c0d2015-05-21 13:58:50 -0700202 if (isatty(STDOUT_FILENO) == 0) {
203 start_device_log();
204 }
Dan Albertea2175a2015-03-08 21:12:08 -0700205#endif
Dan Albert9313c0d2015-05-21 13:58:50 -0700206
207 setup_trace_mask();
208 android::base::InitLogging(argv, AdbLogger);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800209}
210
Dan Albertbac34742015-02-25 17:51:28 -0800211apacket* get_apacket(void)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800212{
Dan Albertbac34742015-02-25 17:51:28 -0800213 apacket* p = reinterpret_cast<apacket*>(malloc(sizeof(apacket)));
214 if (p == nullptr) {
215 fatal("failed to allocate an apacket");
216 }
217
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800218 memset(p, 0, sizeof(apacket) - MAX_PAYLOAD);
219 return p;
220}
221
222void put_apacket(apacket *p)
223{
224 free(p);
225}
226
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700227void handle_online(atransport *t)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800228{
229 D("adb: online\n");
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700230 t->online = 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800231}
232
233void handle_offline(atransport *t)
234{
235 D("adb: offline\n");
236 //Close the associated usb
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700237 t->online = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800238 run_transport_disconnects(t);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800239}
240
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700241#if DEBUG_PACKETS
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800242#define DUMPMAX 32
243void print_packet(const char *label, apacket *p)
244{
245 char *tag;
246 char *x;
247 unsigned count;
248
249 switch(p->msg.command){
250 case A_SYNC: tag = "SYNC"; break;
251 case A_CNXN: tag = "CNXN" ; break;
252 case A_OPEN: tag = "OPEN"; break;
253 case A_OKAY: tag = "OKAY"; break;
254 case A_CLSE: tag = "CLSE"; break;
255 case A_WRTE: tag = "WRTE"; break;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700256 case A_AUTH: tag = "AUTH"; break;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800257 default: tag = "????"; break;
258 }
259
260 fprintf(stderr, "%s: %s %08x %08x %04x \"",
261 label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length);
262 count = p->msg.data_length;
263 x = (char*) p->data;
264 if(count > DUMPMAX) {
265 count = DUMPMAX;
266 tag = "\n";
267 } else {
268 tag = "\"\n";
269 }
270 while(count-- > 0){
271 if((*x >= ' ') && (*x < 127)) {
272 fputc(*x, stderr);
273 } else {
274 fputc('.', stderr);
275 }
276 x++;
277 }
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700278 fputs(tag, stderr);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800279}
280#endif
281
282static void send_ready(unsigned local, unsigned remote, atransport *t)
283{
284 D("Calling send_ready \n");
285 apacket *p = get_apacket();
286 p->msg.command = A_OKAY;
287 p->msg.arg0 = local;
288 p->msg.arg1 = remote;
289 send_packet(p, t);
290}
291
292static void send_close(unsigned local, unsigned remote, atransport *t)
293{
294 D("Calling send_close \n");
295 apacket *p = get_apacket();
296 p->msg.command = A_CLSE;
297 p->msg.arg0 = local;
298 p->msg.arg1 = remote;
299 send_packet(p, t);
300}
301
Scott Andersone82c2db2012-05-25 14:10:02 -0700302static size_t fill_connect_data(char *buf, size_t bufsize)
303{
304#if ADB_HOST
305 return snprintf(buf, bufsize, "host::") + 1;
306#else
307 static const char *cnxn_props[] = {
308 "ro.product.name",
309 "ro.product.model",
310 "ro.product.device",
311 };
312 static const int num_cnxn_props = ARRAY_SIZE(cnxn_props);
313 int i;
314 size_t remaining = bufsize;
315 size_t len;
316
317 len = snprintf(buf, remaining, "%s::", adb_device_banner);
318 remaining -= len;
319 buf += len;
320 for (i = 0; i < num_cnxn_props; i++) {
321 char value[PROPERTY_VALUE_MAX];
322 property_get(cnxn_props[i], value, "");
323 len = snprintf(buf, remaining, "%s=%s;", cnxn_props[i], value);
324 remaining -= len;
325 buf += len;
326 }
327
328 return bufsize - remaining + 1;
329#endif
330}
331
Dan Albertba3a2512015-02-18 17:47:33 -0800332void send_connect(atransport *t)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800333{
334 D("Calling send_connect \n");
335 apacket *cp = get_apacket();
336 cp->msg.command = A_CNXN;
Tamas Berghammer3d2904c2015-07-13 19:12:28 +0100337 cp->msg.arg0 = t->get_protocol_version();
338 cp->msg.arg1 = t->get_max_payload();
Scott Andersone82c2db2012-05-25 14:10:02 -0700339 cp->msg.data_length = fill_connect_data((char *)cp->data,
Tamas Berghammer3d2904c2015-07-13 19:12:28 +0100340 MAX_PAYLOAD_V1);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800341 send_packet(cp, t);
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700342}
343
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700344// qual_overwrite is used to overwrite a qualifier string. dst is a
345// pointer to a char pointer. It is assumed that if *dst is non-NULL, it
346// was malloc'ed and needs to freed. *dst will be set to a dup of src.
347// TODO: switch to std::string for these atransport fields instead.
348static void qual_overwrite(char** dst, const std::string& src) {
Scott Andersone82c2db2012-05-25 14:10:02 -0700349 free(*dst);
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700350 *dst = strdup(src.c_str());
Scott Andersone82c2db2012-05-25 14:10:02 -0700351}
352
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700353void parse_banner(const char* banner, atransport* t) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800354 D("parse_banner: %s\n", banner);
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700355
356 // The format is something like:
357 // "device::ro.product.name=x;ro.product.model=y;ro.product.device=z;".
358 std::vector<std::string> pieces = android::base::Split(banner, ":");
359
360 if (pieces.size() > 2) {
361 const std::string& props = pieces[2];
362 for (auto& prop : android::base::Split(props, ";")) {
363 // The list of properties was traditionally ;-terminated rather than ;-separated.
364 if (prop.empty()) continue;
365
366 std::vector<std::string> key_value = android::base::Split(prop, "=");
367 if (key_value.size() != 2) continue;
368
369 const std::string& key = key_value[0];
370 const std::string& value = key_value[1];
371 if (key == "ro.product.name") {
372 qual_overwrite(&t->product, value);
373 } else if (key == "ro.product.model") {
374 qual_overwrite(&t->model, value);
375 } else if (key == "ro.product.device") {
376 qual_overwrite(&t->device, value);
Scott Andersone82c2db2012-05-25 14:10:02 -0700377 }
378 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800379 }
380
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700381 const std::string& type = pieces[0];
382 if (type == "bootloader") {
Dan Albertdcd78a12015-05-18 16:43:57 -0700383 D("setting connection_state to kCsBootloader\n");
384 t->connection_state = kCsBootloader;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800385 update_transports();
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700386 } else if (type == "device") {
Dan Albertdcd78a12015-05-18 16:43:57 -0700387 D("setting connection_state to kCsDevice\n");
388 t->connection_state = kCsDevice;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800389 update_transports();
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700390 } else if (type == "recovery") {
Dan Albertdcd78a12015-05-18 16:43:57 -0700391 D("setting connection_state to kCsRecovery\n");
392 t->connection_state = kCsRecovery;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800393 update_transports();
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700394 } else if (type == "sideload") {
Dan Albertdcd78a12015-05-18 16:43:57 -0700395 D("setting connection_state to kCsSideload\n");
396 t->connection_state = kCsSideload;
Doug Zongker447f0612012-01-09 14:54:53 -0800397 update_transports();
Elliott Hughes3ce95752015-04-29 22:37:25 -0700398 } else {
Dan Albertdcd78a12015-05-18 16:43:57 -0700399 D("setting connection_state to kCsHost\n");
400 t->connection_state = kCsHost;
Doug Zongker447f0612012-01-09 14:54:53 -0800401 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800402}
403
404void handle_packet(apacket *p, atransport *t)
405{
406 asocket *s;
407
Viral Mehta899913f2010-06-16 18:41:28 +0530408 D("handle_packet() %c%c%c%c\n", ((char*) (&(p->msg.command)))[0],
409 ((char*) (&(p->msg.command)))[1],
410 ((char*) (&(p->msg.command)))[2],
411 ((char*) (&(p->msg.command)))[3]);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800412 print_packet("recv", p);
413
414 switch(p->msg.command){
415 case A_SYNC:
416 if(p->msg.arg0){
417 send_packet(p, t);
418 if(HOST) send_connect(t);
419 } else {
Dan Albertdcd78a12015-05-18 16:43:57 -0700420 t->connection_state = kCsOffline;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800421 handle_offline(t);
422 send_packet(p, t);
423 }
424 return;
425
426 case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
Dan Albertdcd78a12015-05-18 16:43:57 -0700427 if(t->connection_state != kCsOffline) {
428 t->connection_state = kCsOffline;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800429 handle_offline(t);
430 }
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700431
Tamas Berghammer3d2904c2015-07-13 19:12:28 +0100432 t->update_version(p->msg.arg0, p->msg.arg1);
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700433 parse_banner(reinterpret_cast<const char*>(p->data), t);
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700434
Elliott Hughes5cba5042015-06-17 15:23:42 -0700435 if (HOST || !auth_required) {
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700436 handle_online(t);
Elliott Hughes5cba5042015-06-17 15:23:42 -0700437 if (!HOST) send_connect(t);
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700438 } else {
439 send_auth_request(t);
440 }
441 break;
442
443 case A_AUTH:
444 if (p->msg.arg0 == ADB_AUTH_TOKEN) {
Dan Albertdcd78a12015-05-18 16:43:57 -0700445 t->connection_state = kCsUnauthorized;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700446 t->key = adb_auth_nextkey(t->key);
447 if (t->key) {
448 send_auth_response(p->data, p->msg.data_length, t);
449 } else {
450 /* No more private keys to try, send the public key */
451 send_auth_publickey(t);
452 }
453 } else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) {
454 if (adb_auth_verify(t->token, p->data, p->msg.data_length)) {
455 adb_auth_verified(t);
456 t->failed_auth_attempts = 0;
457 } else {
458 if (t->failed_auth_attempts++ > 10)
459 adb_sleep_ms(1000);
460 send_auth_request(t);
461 }
462 } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) {
463 adb_auth_confirm_key(p->data, p->msg.data_length, t);
464 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800465 break;
466
467 case A_OPEN: /* OPEN(local-id, 0, "destination") */
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100468 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800469 char *name = (char*) p->data;
470 name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
471 s = create_local_service_socket(name);
472 if(s == 0) {
473 send_close(0, p->msg.arg0, t);
474 } else {
475 s->peer = create_remote_socket(p->msg.arg0, t);
476 s->peer->peer = s;
477 send_ready(s->id, s->peer->id, t);
478 s->ready(s);
479 }
480 }
481 break;
482
483 case A_OKAY: /* READY(local-id, remote-id, "") */
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100484 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
485 if((s = find_local_socket(p->msg.arg1, 0))) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800486 if(s->peer == 0) {
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100487 /* On first READY message, create the connection. */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800488 s->peer = create_remote_socket(p->msg.arg0, t);
489 s->peer->peer = s;
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100490 s->ready(s);
491 } else if (s->peer->id == p->msg.arg0) {
492 /* Other READY messages must use the same local-id */
493 s->ready(s);
494 } else {
495 D("Invalid A_OKAY(%d,%d), expected A_OKAY(%d,%d) on transport %s\n",
496 p->msg.arg0, p->msg.arg1, s->peer->id, p->msg.arg1, t->serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800497 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800498 }
499 }
500 break;
501
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100502 case A_CLSE: /* CLOSE(local-id, remote-id, "") or CLOSE(0, remote-id, "") */
503 if (t->online && p->msg.arg1 != 0) {
504 if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
505 /* According to protocol.txt, p->msg.arg0 might be 0 to indicate
506 * a failed OPEN only. However, due to a bug in previous ADB
507 * versions, CLOSE(0, remote-id, "") was also used for normal
508 * CLOSE() operations.
509 *
510 * This is bad because it means a compromised adbd could
511 * send packets to close connections between the host and
512 * other devices. To avoid this, only allow this if the local
513 * socket has a peer on the same transport.
514 */
515 if (p->msg.arg0 == 0 && s->peer && s->peer->transport != t) {
516 D("Invalid A_CLSE(0, %u) from transport %s, expected transport %s\n",
517 p->msg.arg1, t->serial, s->peer->transport->serial);
518 } else {
519 s->close(s);
520 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800521 }
522 }
523 break;
524
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100525 case A_WRTE: /* WRITE(local-id, remote-id, <data>) */
526 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
527 if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800528 unsigned rid = p->msg.arg0;
529 p->len = p->msg.data_length;
530
531 if(s->enqueue(s, p) == 0) {
532 D("Enqueue the socket\n");
533 send_ready(s->id, rid, t);
534 }
535 return;
536 }
537 }
538 break;
539
540 default:
541 printf("handle_packet: what is %08x?!\n", p->msg.command);
542 }
543
544 put_apacket(p);
545}
546
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800547#if ADB_HOST
JP Abgrall571c1362012-12-06 18:18:12 -0800548
Stefan Hilzingera84a42e2010-04-19 12:21:12 +0100549int launch_server(int server_port)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800550{
Yabin Cuie77b6a02014-11-11 09:24:11 -0800551#if defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800552 /* we need to start the server in the background */
553 /* we create a PIPE that will be used to wait for the server's "OK" */
554 /* message since the pipe handles must be inheritable, we use a */
555 /* security attribute */
Spencer Lowd0f66c32015-05-20 23:17:26 -0700556 HANDLE nul_read, nul_write;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800557 HANDLE pipe_read, pipe_write;
Ray Donnelly267aa8b2012-11-29 01:18:50 +0000558 HANDLE stdout_handle, stderr_handle;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800559 SECURITY_ATTRIBUTES sa;
560 STARTUPINFO startup;
561 PROCESS_INFORMATION pinfo;
562 char program_path[ MAX_PATH ];
563 int ret;
564
565 sa.nLength = sizeof(sa);
566 sa.lpSecurityDescriptor = NULL;
567 sa.bInheritHandle = TRUE;
568
Spencer Lowd0f66c32015-05-20 23:17:26 -0700569 /* Redirect stdin and stderr to Windows /dev/null. If we instead pass our
570 * stdin/stderr handles and they are console handles, when the adb server
571 * starts up, the C Runtime will see console handles for a process that
572 * isn't connected to a console and it will configure stderr to be closed.
573 * At that point, freopen() could be used to reopen stderr, but it would
574 * take more massaging to fixup the file descriptor number that freopen()
575 * uses. It's simplest to avoid all of this complexity by just redirecting
576 * stdin/stderr to `nul' and then the C Runtime acts as expected.
577 */
578 nul_read = CreateFileW(L"nul", GENERIC_READ,
579 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa,
580 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
581 if (nul_read == INVALID_HANDLE_VALUE) {
582 fprintf(stderr, "CreateFileW(nul, GENERIC_READ) failure, error %ld\n",
583 GetLastError());
584 return -1;
585 }
586
587 nul_write = CreateFileW(L"nul", GENERIC_WRITE,
588 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa,
589 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
590 if (nul_write == INVALID_HANDLE_VALUE) {
591 fprintf(stderr, "CreateFileW(nul, GENERIC_WRITE) failure, error %ld\n",
592 GetLastError());
593 CloseHandle(nul_read);
594 return -1;
595 }
596
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800597 /* create pipe, and ensure its read handle isn't inheritable */
598 ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
599 if (!ret) {
600 fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );
Spencer Lowd0f66c32015-05-20 23:17:26 -0700601 CloseHandle(nul_read);
602 CloseHandle(nul_write);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800603 return -1;
604 }
605
606 SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );
607
Ray Donnelly267aa8b2012-11-29 01:18:50 +0000608 /* Some programs want to launch an adb command and collect its output by
609 * calling CreateProcess with inheritable stdout/stderr handles, then
610 * using read() to get its output. When this happens, the stdout/stderr
611 * handles passed to the adb client process will also be inheritable.
612 * When starting the adb server here, care must be taken to reset them
613 * to non-inheritable.
614 * Otherwise, something bad happens: even if the adb command completes,
615 * the calling process is stuck while read()-ing from the stdout/stderr
616 * descriptors, because they're connected to corresponding handles in the
617 * adb server process (even if the latter never uses/writes to them).
618 */
619 stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE );
620 stderr_handle = GetStdHandle( STD_ERROR_HANDLE );
621 if (stdout_handle != INVALID_HANDLE_VALUE) {
622 SetHandleInformation( stdout_handle, HANDLE_FLAG_INHERIT, 0 );
623 }
624 if (stderr_handle != INVALID_HANDLE_VALUE) {
625 SetHandleInformation( stderr_handle, HANDLE_FLAG_INHERIT, 0 );
626 }
627
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800628 ZeroMemory( &startup, sizeof(startup) );
629 startup.cb = sizeof(startup);
Spencer Lowd0f66c32015-05-20 23:17:26 -0700630 startup.hStdInput = nul_read;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800631 startup.hStdOutput = pipe_write;
Spencer Lowd0f66c32015-05-20 23:17:26 -0700632 startup.hStdError = nul_write;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800633 startup.dwFlags = STARTF_USESTDHANDLES;
634
635 ZeroMemory( &pinfo, sizeof(pinfo) );
636
637 /* get path of current program */
638 GetModuleFileName( NULL, program_path, sizeof(program_path) );
Wenhao Lia09558c2013-11-13 16:23:37 +0800639 char args[64];
640 snprintf(args, sizeof(args), "adb -P %d fork-server server", server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800641 ret = CreateProcess(
642 program_path, /* program path */
Wenhao Lia09558c2013-11-13 16:23:37 +0800643 args,
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800644 /* the fork-server argument will set the
645 debug = 2 in the child */
646 NULL, /* process handle is not inheritable */
647 NULL, /* thread handle is not inheritable */
648 TRUE, /* yes, inherit some handles */
649 DETACHED_PROCESS, /* the new process doesn't have a console */
650 NULL, /* use parent's environment block */
651 NULL, /* use parent's starting directory */
652 &startup, /* startup info, i.e. std handles */
653 &pinfo );
654
Spencer Lowd0f66c32015-05-20 23:17:26 -0700655 CloseHandle( nul_read );
656 CloseHandle( nul_write );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800657 CloseHandle( pipe_write );
658
659 if (!ret) {
660 fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );
661 CloseHandle( pipe_read );
662 return -1;
663 }
664
665 CloseHandle( pinfo.hProcess );
666 CloseHandle( pinfo.hThread );
667
668 /* wait for the "OK\n" message */
669 {
670 char temp[3];
671 DWORD count;
672
673 ret = ReadFile( pipe_read, temp, 3, &count, NULL );
674 CloseHandle( pipe_read );
675 if ( !ret ) {
676 fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() );
677 return -1;
678 }
679 if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
680 fprintf(stderr, "ADB server didn't ACK\n" );
681 return -1;
682 }
683 }
Yabin Cuie77b6a02014-11-11 09:24:11 -0800684#else /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800685 char path[PATH_MAX];
686 int fd[2];
687
688 // set up a pipe so the child can tell us when it is ready.
689 // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child.
690 if (pipe(fd)) {
691 fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
692 return -1;
693 }
Alexey Tarasov31664102009-10-22 02:55:00 +1100694 get_my_path(path, PATH_MAX);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800695 pid_t pid = fork();
696 if(pid < 0) return -1;
697
698 if (pid == 0) {
699 // child side of the fork
700
701 // redirect stderr to the pipe
702 // we use stderr instead of stdout due to stdout's buffering behavior.
703 adb_close(fd[0]);
704 dup2(fd[1], STDERR_FILENO);
705 adb_close(fd[1]);
706
Matt Gumbeld7b33082012-11-14 10:16:17 -0800707 char str_port[30];
708 snprintf(str_port, sizeof(str_port), "%d", server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800709 // child process
Matt Gumbeld7b33082012-11-14 10:16:17 -0800710 int result = execl(path, "adb", "-P", str_port, "fork-server", "server", NULL);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800711 // this should not return
712 fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
713 } else {
714 // parent side of the fork
715
716 char temp[3];
717
718 temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
719 // wait for the "OK\n" message
720 adb_close(fd[1]);
721 int ret = adb_read(fd[0], temp, 3);
JP Abgrall408fa572011-03-16 15:57:42 -0700722 int saved_errno = errno;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800723 adb_close(fd[0]);
724 if (ret < 0) {
JP Abgrall408fa572011-03-16 15:57:42 -0700725 fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800726 return -1;
727 }
728 if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
729 fprintf(stderr, "ADB server didn't ACK\n" );
730 return -1;
731 }
732
733 setsid();
734 }
Yabin Cuie77b6a02014-11-11 09:24:11 -0800735#endif /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800736 return 0;
737}
Yabin Cuie77b6a02014-11-11 09:24:11 -0800738#endif /* ADB_HOST */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800739
David 'Digit' Turner25258692013-03-21 21:07:42 +0100740// Try to handle a network forwarding request.
741// This returns 1 on success, 0 on failure, and -1 to indicate this is not
742// a forwarding-related request.
Elliott Hughesaee80fb2015-05-07 21:38:41 -0700743int handle_forward_request(const char* service, TransportType type, const char* serial, int reply_fd)
David 'Digit' Turner25258692013-03-21 21:07:42 +0100744{
745 if (!strcmp(service, "list-forward")) {
746 // Create the list of forward redirections.
Elliott Hughese67f1f82015-04-30 17:32:03 -0700747 std::string listeners = format_listeners();
David 'Digit' Turner25258692013-03-21 21:07:42 +0100748#if ADB_HOST
Elliott Hughese67f1f82015-04-30 17:32:03 -0700749 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100750#endif
Elliott Hughese67f1f82015-04-30 17:32:03 -0700751 SendProtocolString(reply_fd, listeners);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100752 return 1;
753 }
754
755 if (!strcmp(service, "killforward-all")) {
756 remove_all_listeners();
757#if ADB_HOST
758 /* On the host: 1st OKAY is connect, 2nd OKAY is status */
Elliott Hughese67f1f82015-04-30 17:32:03 -0700759 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100760#endif
Elliott Hughese67f1f82015-04-30 17:32:03 -0700761 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100762 return 1;
763 }
764
Elliott Hughes424af022015-05-29 17:55:19 -0700765 if (!strncmp(service, "forward:", 8) || !strncmp(service, "killforward:", 12)) {
766 // killforward:local
767 // forward:(norebind:)?local;remote
768 bool kill_forward = false;
769 bool no_rebind = false;
770 if (android::base::StartsWith(service, "killforward:")) {
771 kill_forward = true;
772 service += 12;
773 if (android::base::StartsWith(service, "norebind:")) {
774 no_rebind = true;
775 service += 9;
776 }
777 } else {
778 service += 8;
David 'Digit' Turner25258692013-03-21 21:07:42 +0100779 }
780
Elliott Hughes424af022015-05-29 17:55:19 -0700781 std::vector<std::string> pieces = android::base::Split(service, ";");
David 'Digit' Turner25258692013-03-21 21:07:42 +0100782
Elliott Hughes424af022015-05-29 17:55:19 -0700783 if (kill_forward) {
784 // Check killforward: parameter format: '<local>'
785 if (pieces.size() != 1 || pieces[0].empty()) {
786 SendFail(reply_fd, android::base::StringPrintf("bad killforward: %s", service));
David 'Digit' Turner25258692013-03-21 21:07:42 +0100787 return 1;
788 }
789 } else {
Elliott Hughes424af022015-05-29 17:55:19 -0700790 // Check forward: parameter format: '<local>;<remote>'
791 if (pieces.size() != 2 || pieces[0].empty() || pieces[1].empty() || pieces[1][0] == '*') {
792 SendFail(reply_fd, android::base::StringPrintf("bad forward: %s", service));
David 'Digit' Turner25258692013-03-21 21:07:42 +0100793 return 1;
794 }
795 }
796
Elliott Hughes7be29c82015-04-16 22:54:44 -0700797 std::string error_msg;
Elliott Hughes424af022015-05-29 17:55:19 -0700798 atransport* transport = acquire_one_transport(kCsAny, type, serial, &error_msg);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100799 if (!transport) {
Elliott Hughese67f1f82015-04-30 17:32:03 -0700800 SendFail(reply_fd, error_msg);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100801 return 1;
802 }
803
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700804 InstallStatus r;
Elliott Hughes424af022015-05-29 17:55:19 -0700805 if (kill_forward) {
806 r = remove_listener(pieces[0].c_str(), transport);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100807 } else {
Elliott Hughes424af022015-05-29 17:55:19 -0700808 r = install_listener(pieces[0], pieces[1].c_str(), transport, no_rebind);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100809 }
Elliott Hughes7b506092015-04-20 08:09:20 -0700810 if (r == INSTALL_STATUS_OK) {
David 'Digit' Turner25258692013-03-21 21:07:42 +0100811#if ADB_HOST
812 /* On the host: 1st OKAY is connect, 2nd OKAY is status */
Elliott Hughese67f1f82015-04-30 17:32:03 -0700813 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100814#endif
Elliott Hughese67f1f82015-04-30 17:32:03 -0700815 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100816 return 1;
817 }
818
Elliott Hughes7b506092015-04-20 08:09:20 -0700819 std::string message;
820 switch (r) {
Elliott Hughes424af022015-05-29 17:55:19 -0700821 case INSTALL_STATUS_OK: message = "success (!)"; break;
Elliott Hughes7b506092015-04-20 08:09:20 -0700822 case INSTALL_STATUS_INTERNAL_ERROR: message = "internal error"; break;
823 case INSTALL_STATUS_CANNOT_BIND:
824 message = android::base::StringPrintf("cannot bind to socket: %s", strerror(errno));
825 break;
826 case INSTALL_STATUS_CANNOT_REBIND:
827 message = android::base::StringPrintf("cannot rebind existing socket: %s", strerror(errno));
828 break;
Elliott Hughes424af022015-05-29 17:55:19 -0700829 case INSTALL_STATUS_LISTENER_NOT_FOUND:
830 message = android::base::StringPrintf("listener '%s' not found", service);
831 break;
David 'Digit' Turner25258692013-03-21 21:07:42 +0100832 }
Elliott Hughese67f1f82015-04-30 17:32:03 -0700833 SendFail(reply_fd, message);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100834 return 1;
835 }
836 return 0;
837}
838
Elliott Hughese2d36772015-06-23 13:00:32 -0700839#if ADB_HOST
840static int SendOkay(int fd, const std::string& s) {
841 SendOkay(fd);
842 SendProtocolString(fd, s);
843 return 0;
844}
845#endif
846
Dan Albertc89e0cc2015-05-08 16:13:53 -0700847int handle_host_request(const char* service, TransportType type,
848 const char* serial, int reply_fd, asocket* s) {
849 if (strcmp(service, "kill") == 0) {
850 fprintf(stderr, "adb server killed by remote request\n");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800851 fflush(stdout);
Elliott Hughese67f1f82015-04-30 17:32:03 -0700852 SendOkay(reply_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800853 exit(0);
854 }
855
856#if ADB_HOST
857 // "transport:" is used for switching transport with a specified serial number
858 // "transport-usb:" is used for switching transport to the only USB transport
859 // "transport-local:" is used for switching transport to the only local transport
860 // "transport-any:" is used for switching transport to the only transport
861 if (!strncmp(service, "transport", strlen("transport"))) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700862 TransportType type = kTransportAny;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800863
864 if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
865 type = kTransportUsb;
866 } else if (!strncmp(service, "transport-local", strlen("transport-local"))) {
867 type = kTransportLocal;
868 } else if (!strncmp(service, "transport-any", strlen("transport-any"))) {
869 type = kTransportAny;
870 } else if (!strncmp(service, "transport:", strlen("transport:"))) {
871 service += strlen("transport:");
Tom Marlin3175c8e2011-07-27 12:56:14 -0500872 serial = service;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800873 }
874
Elliott Hughese2d36772015-06-23 13:00:32 -0700875 std::string error_msg;
876 atransport* t = acquire_one_transport(kCsAny, type, serial, &error_msg);
877 if (t != nullptr) {
878 s->transport = t;
Elliott Hughese67f1f82015-04-30 17:32:03 -0700879 SendOkay(reply_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800880 } else {
Elliott Hughese67f1f82015-04-30 17:32:03 -0700881 SendFail(reply_fd, error_msg);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800882 }
883 return 1;
884 }
885
886 // return a list of all connected devices
Scott Andersone109d262012-04-20 11:21:14 -0700887 if (!strncmp(service, "devices", 7)) {
Elliott Hughese67f1f82015-04-30 17:32:03 -0700888 bool long_listing = (strcmp(service+7, "-l") == 0);
889 if (long_listing || service[7] == 0) {
890 D("Getting device list...\n");
891 std::string device_list = list_transports(long_listing);
892 D("Sending device list...\n");
Elliott Hughese2d36772015-06-23 13:00:32 -0700893 return SendOkay(reply_fd, device_list);
Scott Andersone109d262012-04-20 11:21:14 -0700894 }
Elliott Hughese67f1f82015-04-30 17:32:03 -0700895 return 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800896 }
897
Mike Lockwood74d7ff82009-10-11 23:04:18 -0400898 // remove TCP transport
899 if (!strncmp(service, "disconnect:", 11)) {
Elliott Hughes3d5f60d2015-07-18 12:21:30 -0700900 const std::string address(service + 11);
901 if (address.empty()) {
Mike Lockwoodcbbe79ad2010-05-24 10:44:35 -0400902 // disconnect from all TCP devices
903 unregister_all_tcp_transports();
Elliott Hughes3d5f60d2015-07-18 12:21:30 -0700904 return SendOkay(reply_fd, "disconnected everything");
Mike Lockwood74d7ff82009-10-11 23:04:18 -0400905 }
906
Elliott Hughes3d5f60d2015-07-18 12:21:30 -0700907 std::string serial;
908 std::string host;
909 int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
910 std::string error;
911 if (!parse_host_and_port(address, &serial, &host, &port, &error)) {
912 return SendFail(reply_fd, android::base::StringPrintf("couldn't parse '%s': %s",
913 address.c_str(), error.c_str()));
914 }
915 atransport* t = find_transport(serial.c_str());
916 if (t == nullptr) {
917 return SendFail(reply_fd, android::base::StringPrintf("no such device '%s'",
918 serial.c_str()));
919 }
920 unregister_transport(t);
921 return SendOkay(reply_fd, android::base::StringPrintf("disconnected %s", address.c_str()));
Mike Lockwood2f38b692009-08-24 15:58:40 -0700922 }
923
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800924 // returns our value for ADB_SERVER_VERSION
925 if (!strcmp(service, "version")) {
Elliott Hughese2d36772015-06-23 13:00:32 -0700926 return SendOkay(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800927 }
928
Elliott Hughese2d36772015-06-23 13:00:32 -0700929 // These always report "unknown" rather than the actual error, for scripts.
930 if (!strcmp(service, "get-serialno")) {
931 std::string ignored;
932 atransport* t = acquire_one_transport(kCsAny, type, serial, &ignored);
933 return SendOkay(reply_fd, (t && t->serial) ? t->serial : "unknown");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800934 }
Elliott Hughese2d36772015-06-23 13:00:32 -0700935 if (!strcmp(service, "get-devpath")) {
936 std::string ignored;
937 atransport* t = acquire_one_transport(kCsAny, type, serial, &ignored);
938 return SendOkay(reply_fd, (t && t->devpath) ? t->devpath : "unknown");
Scott Andersone109d262012-04-20 11:21:14 -0700939 }
Elliott Hughese2d36772015-06-23 13:00:32 -0700940 if (!strcmp(service, "get-state")) {
941 std::string ignored;
942 atransport* t = acquire_one_transport(kCsAny, type, serial, &ignored);
943 return SendOkay(reply_fd, t ? t->connection_state_name() : "unknown");
944 }
945
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800946 // indicates a new emulator instance has started
Elliott Hughese2d36772015-06-23 13:00:32 -0700947 if (!strncmp(service, "emulator:", 9)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800948 int port = atoi(service+9);
949 local_connect(port);
950 /* we don't even need to send a reply */
951 return 0;
952 }
Simon Yedc22c3c2014-07-14 17:23:06 -0700953#endif // ADB_HOST
954
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700955 int ret = handle_forward_request(service, type, serial, reply_fd);
Simon Yedc22c3c2014-07-14 17:23:06 -0700956 if (ret >= 0)
957 return ret - 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800958 return -1;
959}