blob: 0e14213e09a3489464ac986a55b39c0cab05f058 [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
Elliott Hughes7b506092015-04-20 08:09:20 -070037#include <base/stringprintf.h>
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -070038#include <base/strings.h>
Elliott Hughes7b506092015-04-20 08:09:20 -070039
Benoit Gobyd5fcafa2012-04-12 12:23:49 -070040#include "adb_auth.h"
Dan Albertcc731cc2015-02-24 21:26:58 -080041#include "adb_io.h"
Dan Alberte9fca142015-02-18 18:03:26 -080042#include "adb_listeners.h"
Dan Albert76649012015-02-24 15:51:19 -080043#include "transport.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080044
Scott Andersone82c2db2012-05-25 14:10:02 -070045#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
46
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080047#if !ADB_HOST
Nick Kralevich893a4a42013-05-23 09:54:13 -070048#include <cutils/properties.h>
Nick Kraleviche2864bf2013-02-28 14:12:58 -080049#include <sys/capability.h>
Jeff Sharkey885342a2012-08-14 21:00:22 -070050#include <sys/mount.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080051#endif
52
JP Abgrall408fa572011-03-16 15:57:42 -070053ADB_MUTEX_DEFINE( D_lock );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080054
55int HOST = 0;
56
Scott Andersone82c2db2012-05-25 14:10:02 -070057#if !ADB_HOST
Dan Albertbd0b7502015-02-18 18:22:45 -080058const char *adb_device_banner = "device";
Scott Andersone82c2db2012-05-25 14:10:02 -070059#endif
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080060
61void fatal(const char *fmt, ...)
62{
63 va_list ap;
64 va_start(ap, fmt);
65 fprintf(stderr, "error: ");
66 vfprintf(stderr, fmt, ap);
67 fprintf(stderr, "\n");
68 va_end(ap);
69 exit(-1);
70}
71
72void fatal_errno(const char *fmt, ...)
73{
74 va_list ap;
75 va_start(ap, fmt);
76 fprintf(stderr, "error: %s: ", strerror(errno));
77 vfprintf(stderr, fmt, ap);
78 fprintf(stderr, "\n");
79 va_end(ap);
80 exit(-1);
81}
82
Dan Albertea2175a2015-03-08 21:12:08 -070083#if !ADB_HOST
84void start_device_log(void) {
Dan Albertea2175a2015-03-08 21:12:08 -070085 struct tm now;
86 time_t t;
87 tzset();
88 time(&t);
89 localtime_r(&t, &now);
90
Dan Albert8743ef92015-03-19 22:53:30 -070091 char timestamp[PATH_MAX];
92 strftime(timestamp, sizeof(timestamp), "%Y-%m-%d-%H-%M-%S", &now);
Dan Albertea2175a2015-03-08 21:12:08 -070093
Elliott Hughesab52c182015-05-01 17:04:38 -070094 std::string path = android::base::StringPrintf("/data/adb/adb-%s-%d", timestamp, getpid());
95 int fd = unix_open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640);
Dan Albertea2175a2015-03-08 21:12:08 -070096 if (fd == -1) {
97 return;
98 }
99
100 // redirect stdout and stderr to the log file
101 dup2(fd, STDOUT_FILENO);
102 dup2(fd, STDERR_FILENO);
103 fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid());
104 adb_close(fd);
Dan Albertea2175a2015-03-08 21:12:08 -0700105}
106#endif
107
108int adb_trace_mask;
109
110std::string get_trace_setting_from_env() {
111 const char* setting = getenv("ADB_TRACE");
112 if (setting == nullptr) {
113 setting = "";
114 }
115
116 return std::string(setting);
117}
118
119#if !ADB_HOST
120std::string get_trace_setting_from_prop() {
121 char buf[PROPERTY_VALUE_MAX];
122 property_get("persist.adb.trace_mask", buf, "");
123 return std::string(buf);
124}
125#endif
126
127std::string get_trace_setting() {
128#if ADB_HOST
129 return get_trace_setting_from_env();
130#else
131 return get_trace_setting_from_prop();
132#endif
133}
134
Dan Alberte2462192015-03-19 13:25:27 -0700135// Split the space separated list of tags from the trace setting and build the
136// trace mask from it. note that '1' and 'all' are special cases to enable all
137// tracing.
Dan Albertea2175a2015-03-08 21:12:08 -0700138//
139// adb's trace setting comes from the ADB_TRACE environment variable, whereas
140// adbd's comes from the system property persist.adb.trace_mask.
141void adb_trace_init() {
142 const std::string trace_setting = get_trace_setting();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800143
Dan Alberte2462192015-03-19 13:25:27 -0700144 std::unordered_map<std::string, int> trace_flags = {
145 {"1", 0},
146 {"all", 0},
147 {"adb", TRACE_ADB},
148 {"sockets", TRACE_SOCKETS},
149 {"packets", TRACE_PACKETS},
150 {"rwx", TRACE_RWX},
151 {"usb", TRACE_USB},
152 {"sync", TRACE_SYNC},
153 {"sysdeps", TRACE_SYSDEPS},
154 {"transport", TRACE_TRANSPORT},
155 {"jdwp", TRACE_JDWP},
156 {"services", TRACE_SERVICES},
157 {"auth", TRACE_AUTH}};
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800158
Dan Alberte2462192015-03-19 13:25:27 -0700159 std::vector<std::string> elements = android::base::Split(trace_setting, " ");
160 for (const auto& elem : elements) {
161 const auto& flag = trace_flags.find(elem);
162 if (flag == trace_flags.end()) {
163 D("Unknown trace flag: %s", flag->first.c_str());
164 continue;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800165 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800166
Dan Alberte2462192015-03-19 13:25:27 -0700167 if (flag->second == 0) {
168 // 0 is used for the special values "1" and "all" that enable all
169 // tracing.
170 adb_trace_mask = ~0;
171 return;
172 } else {
173 adb_trace_mask |= 1 << flag->second;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800174 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800175 }
Dan Albertea2175a2015-03-08 21:12:08 -0700176
177#if !ADB_HOST
178 start_device_log();
179#endif
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800180}
181
Dan Albertbac34742015-02-25 17:51:28 -0800182apacket* get_apacket(void)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800183{
Dan Albertbac34742015-02-25 17:51:28 -0800184 apacket* p = reinterpret_cast<apacket*>(malloc(sizeof(apacket)));
185 if (p == nullptr) {
186 fatal("failed to allocate an apacket");
187 }
188
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800189 memset(p, 0, sizeof(apacket) - MAX_PAYLOAD);
190 return p;
191}
192
193void put_apacket(apacket *p)
194{
195 free(p);
196}
197
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700198void handle_online(atransport *t)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800199{
200 D("adb: online\n");
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700201 t->online = 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800202}
203
204void handle_offline(atransport *t)
205{
206 D("adb: offline\n");
207 //Close the associated usb
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700208 t->online = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800209 run_transport_disconnects(t);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800210}
211
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700212#if DEBUG_PACKETS
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800213#define DUMPMAX 32
214void print_packet(const char *label, apacket *p)
215{
216 char *tag;
217 char *x;
218 unsigned count;
219
220 switch(p->msg.command){
221 case A_SYNC: tag = "SYNC"; break;
222 case A_CNXN: tag = "CNXN" ; break;
223 case A_OPEN: tag = "OPEN"; break;
224 case A_OKAY: tag = "OKAY"; break;
225 case A_CLSE: tag = "CLSE"; break;
226 case A_WRTE: tag = "WRTE"; break;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700227 case A_AUTH: tag = "AUTH"; break;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800228 default: tag = "????"; break;
229 }
230
231 fprintf(stderr, "%s: %s %08x %08x %04x \"",
232 label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length);
233 count = p->msg.data_length;
234 x = (char*) p->data;
235 if(count > DUMPMAX) {
236 count = DUMPMAX;
237 tag = "\n";
238 } else {
239 tag = "\"\n";
240 }
241 while(count-- > 0){
242 if((*x >= ' ') && (*x < 127)) {
243 fputc(*x, stderr);
244 } else {
245 fputc('.', stderr);
246 }
247 x++;
248 }
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700249 fputs(tag, stderr);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800250}
251#endif
252
253static void send_ready(unsigned local, unsigned remote, atransport *t)
254{
255 D("Calling send_ready \n");
256 apacket *p = get_apacket();
257 p->msg.command = A_OKAY;
258 p->msg.arg0 = local;
259 p->msg.arg1 = remote;
260 send_packet(p, t);
261}
262
263static void send_close(unsigned local, unsigned remote, atransport *t)
264{
265 D("Calling send_close \n");
266 apacket *p = get_apacket();
267 p->msg.command = A_CLSE;
268 p->msg.arg0 = local;
269 p->msg.arg1 = remote;
270 send_packet(p, t);
271}
272
Scott Andersone82c2db2012-05-25 14:10:02 -0700273static size_t fill_connect_data(char *buf, size_t bufsize)
274{
275#if ADB_HOST
276 return snprintf(buf, bufsize, "host::") + 1;
277#else
278 static const char *cnxn_props[] = {
279 "ro.product.name",
280 "ro.product.model",
281 "ro.product.device",
282 };
283 static const int num_cnxn_props = ARRAY_SIZE(cnxn_props);
284 int i;
285 size_t remaining = bufsize;
286 size_t len;
287
288 len = snprintf(buf, remaining, "%s::", adb_device_banner);
289 remaining -= len;
290 buf += len;
291 for (i = 0; i < num_cnxn_props; i++) {
292 char value[PROPERTY_VALUE_MAX];
293 property_get(cnxn_props[i], value, "");
294 len = snprintf(buf, remaining, "%s=%s;", cnxn_props[i], value);
295 remaining -= len;
296 buf += len;
297 }
298
299 return bufsize - remaining + 1;
300#endif
301}
302
Dan Albertba3a2512015-02-18 17:47:33 -0800303void send_connect(atransport *t)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800304{
305 D("Calling send_connect \n");
306 apacket *cp = get_apacket();
307 cp->msg.command = A_CNXN;
308 cp->msg.arg0 = A_VERSION;
309 cp->msg.arg1 = MAX_PAYLOAD;
Scott Andersone82c2db2012-05-25 14:10:02 -0700310 cp->msg.data_length = fill_connect_data((char *)cp->data,
311 sizeof(cp->data));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800312 send_packet(cp, t);
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700313}
314
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700315// qual_overwrite is used to overwrite a qualifier string. dst is a
316// pointer to a char pointer. It is assumed that if *dst is non-NULL, it
317// was malloc'ed and needs to freed. *dst will be set to a dup of src.
318// TODO: switch to std::string for these atransport fields instead.
319static void qual_overwrite(char** dst, const std::string& src) {
Scott Andersone82c2db2012-05-25 14:10:02 -0700320 free(*dst);
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700321 *dst = strdup(src.c_str());
Scott Andersone82c2db2012-05-25 14:10:02 -0700322}
323
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700324void parse_banner(const char* banner, atransport* t) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800325 D("parse_banner: %s\n", banner);
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700326
327 // The format is something like:
328 // "device::ro.product.name=x;ro.product.model=y;ro.product.device=z;".
329 std::vector<std::string> pieces = android::base::Split(banner, ":");
330
331 if (pieces.size() > 2) {
332 const std::string& props = pieces[2];
333 for (auto& prop : android::base::Split(props, ";")) {
334 // The list of properties was traditionally ;-terminated rather than ;-separated.
335 if (prop.empty()) continue;
336
337 std::vector<std::string> key_value = android::base::Split(prop, "=");
338 if (key_value.size() != 2) continue;
339
340 const std::string& key = key_value[0];
341 const std::string& value = key_value[1];
342 if (key == "ro.product.name") {
343 qual_overwrite(&t->product, value);
344 } else if (key == "ro.product.model") {
345 qual_overwrite(&t->model, value);
346 } else if (key == "ro.product.device") {
347 qual_overwrite(&t->device, value);
Scott Andersone82c2db2012-05-25 14:10:02 -0700348 }
349 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800350 }
351
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700352 const std::string& type = pieces[0];
353 if (type == "bootloader") {
Dan Albertdcd78a12015-05-18 16:43:57 -0700354 D("setting connection_state to kCsBootloader\n");
355 t->connection_state = kCsBootloader;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800356 update_transports();
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700357 } else if (type == "device") {
Dan Albertdcd78a12015-05-18 16:43:57 -0700358 D("setting connection_state to kCsDevice\n");
359 t->connection_state = kCsDevice;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800360 update_transports();
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700361 } else if (type == "recovery") {
Dan Albertdcd78a12015-05-18 16:43:57 -0700362 D("setting connection_state to kCsRecovery\n");
363 t->connection_state = kCsRecovery;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800364 update_transports();
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700365 } else if (type == "sideload") {
Dan Albertdcd78a12015-05-18 16:43:57 -0700366 D("setting connection_state to kCsSideload\n");
367 t->connection_state = kCsSideload;
Doug Zongker447f0612012-01-09 14:54:53 -0800368 update_transports();
Elliott Hughes3ce95752015-04-29 22:37:25 -0700369 } else {
Dan Albertdcd78a12015-05-18 16:43:57 -0700370 D("setting connection_state to kCsHost\n");
371 t->connection_state = kCsHost;
Doug Zongker447f0612012-01-09 14:54:53 -0800372 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800373}
374
375void handle_packet(apacket *p, atransport *t)
376{
377 asocket *s;
378
Viral Mehta899913f2010-06-16 18:41:28 +0530379 D("handle_packet() %c%c%c%c\n", ((char*) (&(p->msg.command)))[0],
380 ((char*) (&(p->msg.command)))[1],
381 ((char*) (&(p->msg.command)))[2],
382 ((char*) (&(p->msg.command)))[3]);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800383 print_packet("recv", p);
384
385 switch(p->msg.command){
386 case A_SYNC:
387 if(p->msg.arg0){
388 send_packet(p, t);
389 if(HOST) send_connect(t);
390 } else {
Dan Albertdcd78a12015-05-18 16:43:57 -0700391 t->connection_state = kCsOffline;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800392 handle_offline(t);
393 send_packet(p, t);
394 }
395 return;
396
397 case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
398 /* XXX verify version, etc */
Dan Albertdcd78a12015-05-18 16:43:57 -0700399 if(t->connection_state != kCsOffline) {
400 t->connection_state = kCsOffline;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800401 handle_offline(t);
402 }
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700403
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700404 parse_banner(reinterpret_cast<const char*>(p->data), t);
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700405
406 if (HOST || !auth_enabled) {
407 handle_online(t);
408 if(!HOST) send_connect(t);
409 } else {
410 send_auth_request(t);
411 }
412 break;
413
414 case A_AUTH:
415 if (p->msg.arg0 == ADB_AUTH_TOKEN) {
Dan Albertdcd78a12015-05-18 16:43:57 -0700416 t->connection_state = kCsUnauthorized;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700417 t->key = adb_auth_nextkey(t->key);
418 if (t->key) {
419 send_auth_response(p->data, p->msg.data_length, t);
420 } else {
421 /* No more private keys to try, send the public key */
422 send_auth_publickey(t);
423 }
424 } else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) {
425 if (adb_auth_verify(t->token, p->data, p->msg.data_length)) {
426 adb_auth_verified(t);
427 t->failed_auth_attempts = 0;
428 } else {
429 if (t->failed_auth_attempts++ > 10)
430 adb_sleep_ms(1000);
431 send_auth_request(t);
432 }
433 } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) {
434 adb_auth_confirm_key(p->data, p->msg.data_length, t);
435 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800436 break;
437
438 case A_OPEN: /* OPEN(local-id, 0, "destination") */
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100439 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800440 char *name = (char*) p->data;
441 name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
442 s = create_local_service_socket(name);
443 if(s == 0) {
444 send_close(0, p->msg.arg0, t);
445 } else {
446 s->peer = create_remote_socket(p->msg.arg0, t);
447 s->peer->peer = s;
448 send_ready(s->id, s->peer->id, t);
449 s->ready(s);
450 }
451 }
452 break;
453
454 case A_OKAY: /* READY(local-id, remote-id, "") */
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100455 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
456 if((s = find_local_socket(p->msg.arg1, 0))) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800457 if(s->peer == 0) {
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100458 /* On first READY message, create the connection. */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800459 s->peer = create_remote_socket(p->msg.arg0, t);
460 s->peer->peer = s;
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100461 s->ready(s);
462 } else if (s->peer->id == p->msg.arg0) {
463 /* Other READY messages must use the same local-id */
464 s->ready(s);
465 } else {
466 D("Invalid A_OKAY(%d,%d), expected A_OKAY(%d,%d) on transport %s\n",
467 p->msg.arg0, p->msg.arg1, s->peer->id, p->msg.arg1, t->serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800468 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800469 }
470 }
471 break;
472
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100473 case A_CLSE: /* CLOSE(local-id, remote-id, "") or CLOSE(0, remote-id, "") */
474 if (t->online && p->msg.arg1 != 0) {
475 if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
476 /* According to protocol.txt, p->msg.arg0 might be 0 to indicate
477 * a failed OPEN only. However, due to a bug in previous ADB
478 * versions, CLOSE(0, remote-id, "") was also used for normal
479 * CLOSE() operations.
480 *
481 * This is bad because it means a compromised adbd could
482 * send packets to close connections between the host and
483 * other devices. To avoid this, only allow this if the local
484 * socket has a peer on the same transport.
485 */
486 if (p->msg.arg0 == 0 && s->peer && s->peer->transport != t) {
487 D("Invalid A_CLSE(0, %u) from transport %s, expected transport %s\n",
488 p->msg.arg1, t->serial, s->peer->transport->serial);
489 } else {
490 s->close(s);
491 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800492 }
493 }
494 break;
495
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100496 case A_WRTE: /* WRITE(local-id, remote-id, <data>) */
497 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
498 if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800499 unsigned rid = p->msg.arg0;
500 p->len = p->msg.data_length;
501
502 if(s->enqueue(s, p) == 0) {
503 D("Enqueue the socket\n");
504 send_ready(s->id, rid, t);
505 }
506 return;
507 }
508 }
509 break;
510
511 default:
512 printf("handle_packet: what is %08x?!\n", p->msg.command);
513 }
514
515 put_apacket(p);
516}
517
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800518#if ADB_HOST
JP Abgrall571c1362012-12-06 18:18:12 -0800519
Stefan Hilzingera84a42e2010-04-19 12:21:12 +0100520int launch_server(int server_port)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800521{
Yabin Cuie77b6a02014-11-11 09:24:11 -0800522#if defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800523 /* we need to start the server in the background */
524 /* we create a PIPE that will be used to wait for the server's "OK" */
525 /* message since the pipe handles must be inheritable, we use a */
526 /* security attribute */
527 HANDLE pipe_read, pipe_write;
Ray Donnelly267aa8b2012-11-29 01:18:50 +0000528 HANDLE stdout_handle, stderr_handle;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800529 SECURITY_ATTRIBUTES sa;
530 STARTUPINFO startup;
531 PROCESS_INFORMATION pinfo;
532 char program_path[ MAX_PATH ];
533 int ret;
534
535 sa.nLength = sizeof(sa);
536 sa.lpSecurityDescriptor = NULL;
537 sa.bInheritHandle = TRUE;
538
539 /* create pipe, and ensure its read handle isn't inheritable */
540 ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
541 if (!ret) {
542 fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );
543 return -1;
544 }
545
546 SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );
547
Ray Donnelly267aa8b2012-11-29 01:18:50 +0000548 /* Some programs want to launch an adb command and collect its output by
549 * calling CreateProcess with inheritable stdout/stderr handles, then
550 * using read() to get its output. When this happens, the stdout/stderr
551 * handles passed to the adb client process will also be inheritable.
552 * When starting the adb server here, care must be taken to reset them
553 * to non-inheritable.
554 * Otherwise, something bad happens: even if the adb command completes,
555 * the calling process is stuck while read()-ing from the stdout/stderr
556 * descriptors, because they're connected to corresponding handles in the
557 * adb server process (even if the latter never uses/writes to them).
558 */
559 stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE );
560 stderr_handle = GetStdHandle( STD_ERROR_HANDLE );
561 if (stdout_handle != INVALID_HANDLE_VALUE) {
562 SetHandleInformation( stdout_handle, HANDLE_FLAG_INHERIT, 0 );
563 }
564 if (stderr_handle != INVALID_HANDLE_VALUE) {
565 SetHandleInformation( stderr_handle, HANDLE_FLAG_INHERIT, 0 );
566 }
567
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800568 ZeroMemory( &startup, sizeof(startup) );
569 startup.cb = sizeof(startup);
570 startup.hStdInput = GetStdHandle( STD_INPUT_HANDLE );
571 startup.hStdOutput = pipe_write;
572 startup.hStdError = GetStdHandle( STD_ERROR_HANDLE );
573 startup.dwFlags = STARTF_USESTDHANDLES;
574
575 ZeroMemory( &pinfo, sizeof(pinfo) );
576
577 /* get path of current program */
578 GetModuleFileName( NULL, program_path, sizeof(program_path) );
Wenhao Lia09558c2013-11-13 16:23:37 +0800579 char args[64];
580 snprintf(args, sizeof(args), "adb -P %d fork-server server", server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800581 ret = CreateProcess(
582 program_path, /* program path */
Wenhao Lia09558c2013-11-13 16:23:37 +0800583 args,
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800584 /* the fork-server argument will set the
585 debug = 2 in the child */
586 NULL, /* process handle is not inheritable */
587 NULL, /* thread handle is not inheritable */
588 TRUE, /* yes, inherit some handles */
589 DETACHED_PROCESS, /* the new process doesn't have a console */
590 NULL, /* use parent's environment block */
591 NULL, /* use parent's starting directory */
592 &startup, /* startup info, i.e. std handles */
593 &pinfo );
594
595 CloseHandle( pipe_write );
596
597 if (!ret) {
598 fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );
599 CloseHandle( pipe_read );
600 return -1;
601 }
602
603 CloseHandle( pinfo.hProcess );
604 CloseHandle( pinfo.hThread );
605
606 /* wait for the "OK\n" message */
607 {
608 char temp[3];
609 DWORD count;
610
611 ret = ReadFile( pipe_read, temp, 3, &count, NULL );
612 CloseHandle( pipe_read );
613 if ( !ret ) {
614 fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() );
615 return -1;
616 }
617 if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
618 fprintf(stderr, "ADB server didn't ACK\n" );
619 return -1;
620 }
621 }
Yabin Cuie77b6a02014-11-11 09:24:11 -0800622#else /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800623 char path[PATH_MAX];
624 int fd[2];
625
626 // set up a pipe so the child can tell us when it is ready.
627 // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child.
628 if (pipe(fd)) {
629 fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
630 return -1;
631 }
Alexey Tarasov31664102009-10-22 02:55:00 +1100632 get_my_path(path, PATH_MAX);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800633 pid_t pid = fork();
634 if(pid < 0) return -1;
635
636 if (pid == 0) {
637 // child side of the fork
638
639 // redirect stderr to the pipe
640 // we use stderr instead of stdout due to stdout's buffering behavior.
641 adb_close(fd[0]);
642 dup2(fd[1], STDERR_FILENO);
643 adb_close(fd[1]);
644
Matt Gumbeld7b33082012-11-14 10:16:17 -0800645 char str_port[30];
646 snprintf(str_port, sizeof(str_port), "%d", server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800647 // child process
Matt Gumbeld7b33082012-11-14 10:16:17 -0800648 int result = execl(path, "adb", "-P", str_port, "fork-server", "server", NULL);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800649 // this should not return
650 fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
651 } else {
652 // parent side of the fork
653
654 char temp[3];
655
656 temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
657 // wait for the "OK\n" message
658 adb_close(fd[1]);
659 int ret = adb_read(fd[0], temp, 3);
JP Abgrall408fa572011-03-16 15:57:42 -0700660 int saved_errno = errno;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800661 adb_close(fd[0]);
662 if (ret < 0) {
JP Abgrall408fa572011-03-16 15:57:42 -0700663 fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800664 return -1;
665 }
666 if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
667 fprintf(stderr, "ADB server didn't ACK\n" );
668 return -1;
669 }
670
671 setsid();
672 }
Yabin Cuie77b6a02014-11-11 09:24:11 -0800673#endif /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800674 return 0;
675}
Yabin Cuie77b6a02014-11-11 09:24:11 -0800676#endif /* ADB_HOST */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800677
David 'Digit' Turner25258692013-03-21 21:07:42 +0100678// Try to handle a network forwarding request.
679// This returns 1 on success, 0 on failure, and -1 to indicate this is not
680// a forwarding-related request.
Elliott Hughesaee80fb2015-05-07 21:38:41 -0700681int handle_forward_request(const char* service, TransportType type, const char* serial, int reply_fd)
David 'Digit' Turner25258692013-03-21 21:07:42 +0100682{
683 if (!strcmp(service, "list-forward")) {
684 // Create the list of forward redirections.
Elliott Hughese67f1f82015-04-30 17:32:03 -0700685 std::string listeners = format_listeners();
David 'Digit' Turner25258692013-03-21 21:07:42 +0100686#if ADB_HOST
Elliott Hughese67f1f82015-04-30 17:32:03 -0700687 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100688#endif
Elliott Hughese67f1f82015-04-30 17:32:03 -0700689 SendProtocolString(reply_fd, listeners);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100690 return 1;
691 }
692
693 if (!strcmp(service, "killforward-all")) {
694 remove_all_listeners();
695#if ADB_HOST
696 /* On the host: 1st OKAY is connect, 2nd OKAY is status */
Elliott Hughese67f1f82015-04-30 17:32:03 -0700697 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100698#endif
Elliott Hughese67f1f82015-04-30 17:32:03 -0700699 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100700 return 1;
701 }
702
703 if (!strncmp(service, "forward:",8) ||
704 !strncmp(service, "killforward:",12)) {
Dan Albertbac34742015-02-25 17:51:28 -0800705 char *local, *remote;
David 'Digit' Turner25258692013-03-21 21:07:42 +0100706 atransport *transport;
707
708 int createForward = strncmp(service, "kill", 4);
709 int no_rebind = 0;
710
711 local = strchr(service, ':') + 1;
712
713 // Handle forward:norebind:<local>... here
714 if (createForward && !strncmp(local, "norebind:", 9)) {
715 no_rebind = 1;
716 local = strchr(local, ':') + 1;
717 }
718
719 remote = strchr(local,';');
720
721 if (createForward) {
722 // Check forward: parameter format: '<local>;<remote>'
723 if(remote == 0) {
Elliott Hughese67f1f82015-04-30 17:32:03 -0700724 SendFail(reply_fd, "malformed forward spec");
David 'Digit' Turner25258692013-03-21 21:07:42 +0100725 return 1;
726 }
727
728 *remote++ = 0;
729 if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) {
Elliott Hughese67f1f82015-04-30 17:32:03 -0700730 SendFail(reply_fd, "malformed forward spec");
David 'Digit' Turner25258692013-03-21 21:07:42 +0100731 return 1;
732 }
733 } else {
734 // Check killforward: parameter format: '<local>'
735 if (local[0] == 0) {
Elliott Hughese67f1f82015-04-30 17:32:03 -0700736 SendFail(reply_fd, "malformed forward spec");
David 'Digit' Turner25258692013-03-21 21:07:42 +0100737 return 1;
738 }
739 }
740
Elliott Hughes7be29c82015-04-16 22:54:44 -0700741 std::string error_msg;
Dan Albertdcd78a12015-05-18 16:43:57 -0700742 transport = acquire_one_transport(kCsAny, type, serial, &error_msg);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100743 if (!transport) {
Elliott Hughese67f1f82015-04-30 17:32:03 -0700744 SendFail(reply_fd, error_msg);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100745 return 1;
746 }
747
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700748 InstallStatus r;
David 'Digit' Turner25258692013-03-21 21:07:42 +0100749 if (createForward) {
750 r = install_listener(local, remote, transport, no_rebind);
751 } else {
752 r = remove_listener(local, transport);
753 }
Elliott Hughes7b506092015-04-20 08:09:20 -0700754 if (r == INSTALL_STATUS_OK) {
David 'Digit' Turner25258692013-03-21 21:07:42 +0100755#if ADB_HOST
756 /* On the host: 1st OKAY is connect, 2nd OKAY is status */
Elliott Hughese67f1f82015-04-30 17:32:03 -0700757 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100758#endif
Elliott Hughese67f1f82015-04-30 17:32:03 -0700759 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100760 return 1;
761 }
762
Elliott Hughes7b506092015-04-20 08:09:20 -0700763 std::string message;
764 switch (r) {
765 case INSTALL_STATUS_OK: message = " "; break;
766 case INSTALL_STATUS_INTERNAL_ERROR: message = "internal error"; break;
767 case INSTALL_STATUS_CANNOT_BIND:
768 message = android::base::StringPrintf("cannot bind to socket: %s", strerror(errno));
769 break;
770 case INSTALL_STATUS_CANNOT_REBIND:
771 message = android::base::StringPrintf("cannot rebind existing socket: %s", strerror(errno));
772 break;
773 case INSTALL_STATUS_LISTENER_NOT_FOUND: message = "listener not found"; break;
David 'Digit' Turner25258692013-03-21 21:07:42 +0100774 }
Elliott Hughese67f1f82015-04-30 17:32:03 -0700775 SendFail(reply_fd, message);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100776 return 1;
777 }
778 return 0;
779}
780
Dan Albertc89e0cc2015-05-08 16:13:53 -0700781int handle_host_request(const char* service, TransportType type,
782 const char* serial, int reply_fd, asocket* s) {
783 if (strcmp(service, "kill") == 0) {
784 fprintf(stderr, "adb server killed by remote request\n");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800785 fflush(stdout);
Elliott Hughese67f1f82015-04-30 17:32:03 -0700786 SendOkay(reply_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800787 exit(0);
788 }
789
790#if ADB_HOST
Chih-Hung Hsiehf787b382014-09-05 15:38:15 -0700791 atransport *transport = NULL;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800792 // "transport:" is used for switching transport with a specified serial number
793 // "transport-usb:" is used for switching transport to the only USB transport
794 // "transport-local:" is used for switching transport to the only local transport
795 // "transport-any:" is used for switching transport to the only transport
796 if (!strncmp(service, "transport", strlen("transport"))) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700797 TransportType type = kTransportAny;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800798
799 if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
800 type = kTransportUsb;
801 } else if (!strncmp(service, "transport-local", strlen("transport-local"))) {
802 type = kTransportLocal;
803 } else if (!strncmp(service, "transport-any", strlen("transport-any"))) {
804 type = kTransportAny;
805 } else if (!strncmp(service, "transport:", strlen("transport:"))) {
806 service += strlen("transport:");
Tom Marlin3175c8e2011-07-27 12:56:14 -0500807 serial = service;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800808 }
809
Elliott Hughes7be29c82015-04-16 22:54:44 -0700810 std::string error_msg = "unknown failure";
Dan Albertdcd78a12015-05-18 16:43:57 -0700811 transport = acquire_one_transport(kCsAny, type, serial, &error_msg);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800812
813 if (transport) {
814 s->transport = transport;
Elliott Hughese67f1f82015-04-30 17:32:03 -0700815 SendOkay(reply_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800816 } else {
Elliott Hughese67f1f82015-04-30 17:32:03 -0700817 SendFail(reply_fd, error_msg);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800818 }
819 return 1;
820 }
821
822 // return a list of all connected devices
Scott Andersone109d262012-04-20 11:21:14 -0700823 if (!strncmp(service, "devices", 7)) {
Elliott Hughese67f1f82015-04-30 17:32:03 -0700824 bool long_listing = (strcmp(service+7, "-l") == 0);
825 if (long_listing || service[7] == 0) {
826 D("Getting device list...\n");
827 std::string device_list = list_transports(long_listing);
828 D("Sending device list...\n");
829 SendOkay(reply_fd);
830 SendProtocolString(reply_fd, device_list);
Scott Andersone109d262012-04-20 11:21:14 -0700831 return 0;
832 }
Elliott Hughese67f1f82015-04-30 17:32:03 -0700833 return 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800834 }
835
Mike Lockwood74d7ff82009-10-11 23:04:18 -0400836 // remove TCP transport
837 if (!strncmp(service, "disconnect:", 11)) {
838 char buffer[4096];
839 memset(buffer, 0, sizeof(buffer));
Elliott Hughesaee80fb2015-05-07 21:38:41 -0700840 const char* serial = service + 11;
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -0400841 if (serial[0] == 0) {
842 // disconnect from all TCP devices
843 unregister_all_tcp_transports();
Mike Lockwood74d7ff82009-10-11 23:04:18 -0400844 } else {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -0400845 char hostbuf[100];
846 // assume port 5555 if no port is specified
847 if (!strchr(serial, ':')) {
848 snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial);
849 serial = hostbuf;
850 }
851 atransport *t = find_transport(serial);
852
853 if (t) {
854 unregister_transport(t);
855 } else {
856 snprintf(buffer, sizeof(buffer), "No such device %s", serial);
857 }
Mike Lockwood74d7ff82009-10-11 23:04:18 -0400858 }
859
Elliott Hughese67f1f82015-04-30 17:32:03 -0700860 SendOkay(reply_fd);
861 SendProtocolString(reply_fd, buffer);
Mike Lockwood2f38b692009-08-24 15:58:40 -0700862 return 0;
863 }
864
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800865 // returns our value for ADB_SERVER_VERSION
866 if (!strcmp(service, "version")) {
Elliott Hughese67f1f82015-04-30 17:32:03 -0700867 SendOkay(reply_fd);
868 SendProtocolString(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800869 return 0;
870 }
871
872 if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {
Dan Albertbac34742015-02-25 17:51:28 -0800873 const char *out = "unknown";
Dan Albertdcd78a12015-05-18 16:43:57 -0700874 transport = acquire_one_transport(kCsAny, type, serial, NULL);
Elliott Hughes7be29c82015-04-16 22:54:44 -0700875 if (transport && transport->serial) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800876 out = transport->serial;
877 }
Elliott Hughese67f1f82015-04-30 17:32:03 -0700878 SendOkay(reply_fd);
879 SendProtocolString(reply_fd, out);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800880 return 0;
881 }
Scott Andersone109d262012-04-20 11:21:14 -0700882 if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
Dan Albertbac34742015-02-25 17:51:28 -0800883 const char *out = "unknown";
Dan Albertdcd78a12015-05-18 16:43:57 -0700884 transport = acquire_one_transport(kCsAny, type, serial, NULL);
Elliott Hughes7be29c82015-04-16 22:54:44 -0700885 if (transport && transport->devpath) {
Scott Andersone109d262012-04-20 11:21:14 -0700886 out = transport->devpath;
887 }
Elliott Hughese67f1f82015-04-30 17:32:03 -0700888 SendOkay(reply_fd);
889 SendProtocolString(reply_fd, out);
Scott Andersone109d262012-04-20 11:21:14 -0700890 return 0;
891 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800892 // indicates a new emulator instance has started
893 if (!strncmp(service,"emulator:",9)) {
894 int port = atoi(service+9);
895 local_connect(port);
896 /* we don't even need to send a reply */
897 return 0;
898 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800899
900 if(!strncmp(service,"get-state",strlen("get-state"))) {
Dan Albertdcd78a12015-05-18 16:43:57 -0700901 transport = acquire_one_transport(kCsAny, type, serial, NULL);
Elliott Hughese67f1f82015-04-30 17:32:03 -0700902 SendOkay(reply_fd);
903 SendProtocolString(reply_fd, transport->connection_state_name());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800904 return 0;
905 }
Simon Yedc22c3c2014-07-14 17:23:06 -0700906#endif // ADB_HOST
907
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700908 int ret = handle_forward_request(service, type, serial, reply_fd);
Simon Yedc22c3c2014-07-14 17:23:06 -0700909 if (ret >= 0)
910 return ret - 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800911 return -1;
912}