blob: de82cd48e14a0e94f168d44d856e8b2909dc0d46 [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>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080034
Elliott Hughes7b506092015-04-20 08:09:20 -070035#include <base/stringprintf.h>
36
Benoit Gobyd5fcafa2012-04-12 12:23:49 -070037#include "adb_auth.h"
Dan Albertcc731cc2015-02-24 21:26:58 -080038#include "adb_io.h"
Dan Alberte9fca142015-02-18 18:03:26 -080039#include "adb_listeners.h"
Dan Albert76649012015-02-24 15:51:19 -080040#include "transport.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080041
Scott Andersone82c2db2012-05-25 14:10:02 -070042#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
43
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080044#if !ADB_HOST
Nick Kralevich893a4a42013-05-23 09:54:13 -070045#include <cutils/properties.h>
Nick Kraleviche2864bf2013-02-28 14:12:58 -080046#include <sys/capability.h>
Jeff Sharkey885342a2012-08-14 21:00:22 -070047#include <sys/mount.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080048#endif
49
JP Abgrall408fa572011-03-16 15:57:42 -070050#if ADB_TRACE
51ADB_MUTEX_DEFINE( D_lock );
52#endif
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080053
54int HOST = 0;
55
Scott Andersone82c2db2012-05-25 14:10:02 -070056#if !ADB_HOST
Dan Albertbd0b7502015-02-18 18:22:45 -080057const char *adb_device_banner = "device";
Scott Andersone82c2db2012-05-25 14:10:02 -070058#endif
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080059
60void fatal(const char *fmt, ...)
61{
62 va_list ap;
63 va_start(ap, fmt);
64 fprintf(stderr, "error: ");
65 vfprintf(stderr, fmt, ap);
66 fprintf(stderr, "\n");
67 va_end(ap);
68 exit(-1);
69}
70
71void fatal_errno(const char *fmt, ...)
72{
73 va_list ap;
74 va_start(ap, fmt);
75 fprintf(stderr, "error: %s: ", strerror(errno));
76 vfprintf(stderr, fmt, ap);
77 fprintf(stderr, "\n");
78 va_end(ap);
79 exit(-1);
80}
81
Dan Albertea2175a2015-03-08 21:12:08 -070082#if !ADB_HOST
83void start_device_log(void) {
Dan Albertea2175a2015-03-08 21:12:08 -070084 struct tm now;
85 time_t t;
86 tzset();
87 time(&t);
88 localtime_r(&t, &now);
89
Dan Albert8743ef92015-03-19 22:53:30 -070090 char timestamp[PATH_MAX];
91 strftime(timestamp, sizeof(timestamp), "%Y-%m-%d-%H-%M-%S", &now);
Dan Albertea2175a2015-03-08 21:12:08 -070092
Dan Albert8743ef92015-03-19 22:53:30 -070093 char path[PATH_MAX];
94 snprintf(path, sizeof(path), "/data/adb/adb-%s-%d", timestamp, getpid());
95
96 int fd = unix_open(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640);
Dan Albertea2175a2015-03-08 21:12:08 -070097 if (fd == -1) {
98 return;
99 }
100
101 // redirect stdout and stderr to the log file
102 dup2(fd, STDOUT_FILENO);
103 dup2(fd, STDERR_FILENO);
104 fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid());
105 adb_close(fd);
Dan Albertea2175a2015-03-08 21:12:08 -0700106}
107#endif
108
109int adb_trace_mask;
110
111std::string get_trace_setting_from_env() {
112 const char* setting = getenv("ADB_TRACE");
113 if (setting == nullptr) {
114 setting = "";
115 }
116
117 return std::string(setting);
118}
119
120#if !ADB_HOST
121std::string get_trace_setting_from_prop() {
122 char buf[PROPERTY_VALUE_MAX];
123 property_get("persist.adb.trace_mask", buf, "");
124 return std::string(buf);
125}
126#endif
127
128std::string get_trace_setting() {
129#if ADB_HOST
130 return get_trace_setting_from_env();
131#else
132 return get_trace_setting_from_prop();
133#endif
134}
135
136// Split the comma/space/colum/semi-column separated list of tags from the trace
137// setting and build the trace mask from it. note that '1' and 'all' are special
138// cases to enable all tracing.
139//
140// adb's trace setting comes from the ADB_TRACE environment variable, whereas
141// adbd's comes from the system property persist.adb.trace_mask.
142void adb_trace_init() {
143 const std::string trace_setting = get_trace_setting();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800144
145 static const struct {
146 const char* tag;
147 int flag;
148 } tags[] = {
149 { "1", 0 },
150 { "all", 0 },
151 { "adb", TRACE_ADB },
152 { "sockets", TRACE_SOCKETS },
153 { "packets", TRACE_PACKETS },
154 { "rwx", TRACE_RWX },
155 { "usb", TRACE_USB },
156 { "sync", TRACE_SYNC },
157 { "sysdeps", TRACE_SYSDEPS },
158 { "transport", TRACE_TRANSPORT },
159 { "jdwp", TRACE_JDWP },
JP Abgrall408fa572011-03-16 15:57:42 -0700160 { "services", TRACE_SERVICES },
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700161 { "auth", TRACE_AUTH },
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800162 { NULL, 0 }
163 };
164
Dan Albertea2175a2015-03-08 21:12:08 -0700165 if (trace_setting.empty()) {
166 return;
167 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800168
Dan Albertea2175a2015-03-08 21:12:08 -0700169 // Use a comma/colon/semi-colon/space separated list
170 const char* p = trace_setting.c_str();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800171 while (*p) {
172 int len, tagn;
173
Dan Albertea2175a2015-03-08 21:12:08 -0700174 const char* q = strpbrk(p, " ,:;");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800175 if (q == NULL) {
176 q = p + strlen(p);
177 }
178 len = q - p;
179
Dan Albertea2175a2015-03-08 21:12:08 -0700180 for (tagn = 0; tags[tagn].tag != NULL; tagn++) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800181 int taglen = strlen(tags[tagn].tag);
182
Dan Albertea2175a2015-03-08 21:12:08 -0700183 if (len == taglen && !memcmp(tags[tagn].tag, p, len)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800184 int flag = tags[tagn].flag;
185 if (flag == 0) {
186 adb_trace_mask = ~0;
187 return;
188 }
189 adb_trace_mask |= (1 << flag);
190 break;
191 }
192 }
193 p = q;
194 if (*p)
195 p++;
196 }
Dan Albertea2175a2015-03-08 21:12:08 -0700197
198#if !ADB_HOST
199 start_device_log();
200#endif
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800201}
202
Dan Albertbac34742015-02-25 17:51:28 -0800203apacket* get_apacket(void)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800204{
Dan Albertbac34742015-02-25 17:51:28 -0800205 apacket* p = reinterpret_cast<apacket*>(malloc(sizeof(apacket)));
206 if (p == nullptr) {
207 fatal("failed to allocate an apacket");
208 }
209
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800210 memset(p, 0, sizeof(apacket) - MAX_PAYLOAD);
211 return p;
212}
213
214void put_apacket(apacket *p)
215{
216 free(p);
217}
218
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700219void handle_online(atransport *t)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800220{
221 D("adb: online\n");
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700222 t->online = 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800223}
224
225void handle_offline(atransport *t)
226{
227 D("adb: offline\n");
228 //Close the associated usb
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700229 t->online = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800230 run_transport_disconnects(t);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800231}
232
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700233#if DEBUG_PACKETS
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800234#define DUMPMAX 32
235void print_packet(const char *label, apacket *p)
236{
237 char *tag;
238 char *x;
239 unsigned count;
240
241 switch(p->msg.command){
242 case A_SYNC: tag = "SYNC"; break;
243 case A_CNXN: tag = "CNXN" ; break;
244 case A_OPEN: tag = "OPEN"; break;
245 case A_OKAY: tag = "OKAY"; break;
246 case A_CLSE: tag = "CLSE"; break;
247 case A_WRTE: tag = "WRTE"; break;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700248 case A_AUTH: tag = "AUTH"; break;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800249 default: tag = "????"; break;
250 }
251
252 fprintf(stderr, "%s: %s %08x %08x %04x \"",
253 label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length);
254 count = p->msg.data_length;
255 x = (char*) p->data;
256 if(count > DUMPMAX) {
257 count = DUMPMAX;
258 tag = "\n";
259 } else {
260 tag = "\"\n";
261 }
262 while(count-- > 0){
263 if((*x >= ' ') && (*x < 127)) {
264 fputc(*x, stderr);
265 } else {
266 fputc('.', stderr);
267 }
268 x++;
269 }
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700270 fputs(tag, stderr);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800271}
272#endif
273
274static void send_ready(unsigned local, unsigned remote, atransport *t)
275{
276 D("Calling send_ready \n");
277 apacket *p = get_apacket();
278 p->msg.command = A_OKAY;
279 p->msg.arg0 = local;
280 p->msg.arg1 = remote;
281 send_packet(p, t);
282}
283
284static void send_close(unsigned local, unsigned remote, atransport *t)
285{
286 D("Calling send_close \n");
287 apacket *p = get_apacket();
288 p->msg.command = A_CLSE;
289 p->msg.arg0 = local;
290 p->msg.arg1 = remote;
291 send_packet(p, t);
292}
293
Scott Andersone82c2db2012-05-25 14:10:02 -0700294static size_t fill_connect_data(char *buf, size_t bufsize)
295{
296#if ADB_HOST
297 return snprintf(buf, bufsize, "host::") + 1;
298#else
299 static const char *cnxn_props[] = {
300 "ro.product.name",
301 "ro.product.model",
302 "ro.product.device",
303 };
304 static const int num_cnxn_props = ARRAY_SIZE(cnxn_props);
305 int i;
306 size_t remaining = bufsize;
307 size_t len;
308
309 len = snprintf(buf, remaining, "%s::", adb_device_banner);
310 remaining -= len;
311 buf += len;
312 for (i = 0; i < num_cnxn_props; i++) {
313 char value[PROPERTY_VALUE_MAX];
314 property_get(cnxn_props[i], value, "");
315 len = snprintf(buf, remaining, "%s=%s;", cnxn_props[i], value);
316 remaining -= len;
317 buf += len;
318 }
319
320 return bufsize - remaining + 1;
321#endif
322}
323
David 'Digit' Turner25258692013-03-21 21:07:42 +0100324#if !ADB_HOST
325static void send_msg_with_header(int fd, const char* msg, size_t msglen) {
326 char header[5];
327 if (msglen > 0xffff)
328 msglen = 0xffff;
329 snprintf(header, sizeof(header), "%04x", (unsigned)msglen);
Dan Albertcc731cc2015-02-24 21:26:58 -0800330 WriteFdExactly(fd, header, 4);
331 WriteFdExactly(fd, msg, msglen);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100332}
333#endif
334
Chih-Hung Hsiehf787b382014-09-05 15:38:15 -0700335#if ADB_HOST
David 'Digit' Turner25258692013-03-21 21:07:42 +0100336static void send_msg_with_okay(int fd, const char* msg, size_t msglen) {
Snild Dolkow2264e7c2014-01-30 10:08:38 +0100337 char header[9];
338 if (msglen > 0xffff)
339 msglen = 0xffff;
340 snprintf(header, sizeof(header), "OKAY%04x", (unsigned)msglen);
Dan Albertcc731cc2015-02-24 21:26:58 -0800341 WriteFdExactly(fd, header, 8);
342 WriteFdExactly(fd, msg, msglen);
Snild Dolkow2264e7c2014-01-30 10:08:38 +0100343}
Chih-Hung Hsiehf787b382014-09-05 15:38:15 -0700344#endif // ADB_HOST
Snild Dolkow2264e7c2014-01-30 10:08:38 +0100345
Dan Albertba3a2512015-02-18 17:47:33 -0800346void send_connect(atransport *t)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800347{
348 D("Calling send_connect \n");
349 apacket *cp = get_apacket();
350 cp->msg.command = A_CNXN;
351 cp->msg.arg0 = A_VERSION;
352 cp->msg.arg1 = MAX_PAYLOAD;
Scott Andersone82c2db2012-05-25 14:10:02 -0700353 cp->msg.data_length = fill_connect_data((char *)cp->data,
354 sizeof(cp->data));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800355 send_packet(cp, t);
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700356}
357
Chih-Hung Hsiehf787b382014-09-05 15:38:15 -0700358#if ADB_HOST
Dan Albertbac34742015-02-25 17:51:28 -0800359static const char* connection_state_name(atransport *t)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800360{
361 if (t == NULL) {
362 return "unknown";
363 }
364
365 switch(t->connection_state) {
366 case CS_BOOTLOADER:
367 return "bootloader";
368 case CS_DEVICE:
369 return "device";
trevda5ad5392013-04-17 14:34:23 +0100370 case CS_RECOVERY:
371 return "recovery";
372 case CS_SIDELOAD:
373 return "sideload";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800374 case CS_OFFLINE:
375 return "offline";
Benoit Goby77e8e582013-01-15 12:36:47 -0800376 case CS_UNAUTHORIZED:
377 return "unauthorized";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800378 default:
379 return "unknown";
380 }
381}
Chih-Hung Hsiehf787b382014-09-05 15:38:15 -0700382#endif // ADB_HOST
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800383
Scott Andersone82c2db2012-05-25 14:10:02 -0700384/* qual_overwrite is used to overwrite a qualifier string. dst is a
385 * pointer to a char pointer. It is assumed that if *dst is non-NULL, it
Scott Anderson2ca3e6b2012-05-30 18:11:27 -0700386 * was malloc'ed and needs to freed. *dst will be set to a dup of src.
Scott Andersone82c2db2012-05-25 14:10:02 -0700387 */
388static void qual_overwrite(char **dst, const char *src)
389{
390 if (!dst)
391 return;
392
393 free(*dst);
394 *dst = NULL;
395
396 if (!src || !*src)
397 return;
398
399 *dst = strdup(src);
400}
401
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800402void parse_banner(char *banner, atransport *t)
403{
Scott Andersone82c2db2012-05-25 14:10:02 -0700404 static const char *prop_seps = ";";
405 static const char key_val_sep = '=';
Scott Anderson2ca3e6b2012-05-30 18:11:27 -0700406 char *cp;
407 char *type;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800408
409 D("parse_banner: %s\n", banner);
410 type = banner;
Scott Andersone82c2db2012-05-25 14:10:02 -0700411 cp = strchr(type, ':');
412 if (cp) {
413 *cp++ = 0;
414 /* Nothing is done with second field. */
415 cp = strchr(cp, ':');
416 if (cp) {
417 char *save;
418 char *key;
Scott Anderson1b7a7e82012-06-05 17:54:27 -0700419 key = adb_strtok_r(cp + 1, prop_seps, &save);
Scott Andersone82c2db2012-05-25 14:10:02 -0700420 while (key) {
421 cp = strchr(key, key_val_sep);
422 if (cp) {
423 *cp++ = '\0';
424 if (!strcmp(key, "ro.product.name"))
425 qual_overwrite(&t->product, cp);
426 else if (!strcmp(key, "ro.product.model"))
427 qual_overwrite(&t->model, cp);
428 else if (!strcmp(key, "ro.product.device"))
429 qual_overwrite(&t->device, cp);
430 }
Scott Anderson1b7a7e82012-06-05 17:54:27 -0700431 key = adb_strtok_r(NULL, prop_seps, &save);
Scott Andersone82c2db2012-05-25 14:10:02 -0700432 }
433 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800434 }
435
436 if(!strcmp(type, "bootloader")){
437 D("setting connection_state to CS_BOOTLOADER\n");
438 t->connection_state = CS_BOOTLOADER;
439 update_transports();
440 return;
441 }
442
443 if(!strcmp(type, "device")) {
444 D("setting connection_state to CS_DEVICE\n");
445 t->connection_state = CS_DEVICE;
446 update_transports();
447 return;
448 }
449
450 if(!strcmp(type, "recovery")) {
451 D("setting connection_state to CS_RECOVERY\n");
452 t->connection_state = CS_RECOVERY;
453 update_transports();
454 return;
455 }
456
Doug Zongker447f0612012-01-09 14:54:53 -0800457 if(!strcmp(type, "sideload")) {
458 D("setting connection_state to CS_SIDELOAD\n");
459 t->connection_state = CS_SIDELOAD;
460 update_transports();
461 return;
462 }
463
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800464 t->connection_state = CS_HOST;
465}
466
467void handle_packet(apacket *p, atransport *t)
468{
469 asocket *s;
470
Viral Mehta899913f2010-06-16 18:41:28 +0530471 D("handle_packet() %c%c%c%c\n", ((char*) (&(p->msg.command)))[0],
472 ((char*) (&(p->msg.command)))[1],
473 ((char*) (&(p->msg.command)))[2],
474 ((char*) (&(p->msg.command)))[3]);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800475 print_packet("recv", p);
476
477 switch(p->msg.command){
478 case A_SYNC:
479 if(p->msg.arg0){
480 send_packet(p, t);
481 if(HOST) send_connect(t);
482 } else {
483 t->connection_state = CS_OFFLINE;
484 handle_offline(t);
485 send_packet(p, t);
486 }
487 return;
488
489 case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
490 /* XXX verify version, etc */
491 if(t->connection_state != CS_OFFLINE) {
492 t->connection_state = CS_OFFLINE;
493 handle_offline(t);
494 }
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700495
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800496 parse_banner((char*) p->data, t);
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700497
498 if (HOST || !auth_enabled) {
499 handle_online(t);
500 if(!HOST) send_connect(t);
501 } else {
502 send_auth_request(t);
503 }
504 break;
505
506 case A_AUTH:
507 if (p->msg.arg0 == ADB_AUTH_TOKEN) {
Benoit Goby77e8e582013-01-15 12:36:47 -0800508 t->connection_state = CS_UNAUTHORIZED;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700509 t->key = adb_auth_nextkey(t->key);
510 if (t->key) {
511 send_auth_response(p->data, p->msg.data_length, t);
512 } else {
513 /* No more private keys to try, send the public key */
514 send_auth_publickey(t);
515 }
516 } else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) {
517 if (adb_auth_verify(t->token, p->data, p->msg.data_length)) {
518 adb_auth_verified(t);
519 t->failed_auth_attempts = 0;
520 } else {
521 if (t->failed_auth_attempts++ > 10)
522 adb_sleep_ms(1000);
523 send_auth_request(t);
524 }
525 } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) {
526 adb_auth_confirm_key(p->data, p->msg.data_length, t);
527 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800528 break;
529
530 case A_OPEN: /* OPEN(local-id, 0, "destination") */
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100531 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800532 char *name = (char*) p->data;
533 name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
534 s = create_local_service_socket(name);
535 if(s == 0) {
536 send_close(0, p->msg.arg0, t);
537 } else {
538 s->peer = create_remote_socket(p->msg.arg0, t);
539 s->peer->peer = s;
540 send_ready(s->id, s->peer->id, t);
541 s->ready(s);
542 }
543 }
544 break;
545
546 case A_OKAY: /* READY(local-id, remote-id, "") */
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100547 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
548 if((s = find_local_socket(p->msg.arg1, 0))) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800549 if(s->peer == 0) {
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100550 /* On first READY message, create the connection. */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800551 s->peer = create_remote_socket(p->msg.arg0, t);
552 s->peer->peer = s;
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100553 s->ready(s);
554 } else if (s->peer->id == p->msg.arg0) {
555 /* Other READY messages must use the same local-id */
556 s->ready(s);
557 } else {
558 D("Invalid A_OKAY(%d,%d), expected A_OKAY(%d,%d) on transport %s\n",
559 p->msg.arg0, p->msg.arg1, s->peer->id, p->msg.arg1, t->serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800560 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800561 }
562 }
563 break;
564
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100565 case A_CLSE: /* CLOSE(local-id, remote-id, "") or CLOSE(0, remote-id, "") */
566 if (t->online && p->msg.arg1 != 0) {
567 if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
568 /* According to protocol.txt, p->msg.arg0 might be 0 to indicate
569 * a failed OPEN only. However, due to a bug in previous ADB
570 * versions, CLOSE(0, remote-id, "") was also used for normal
571 * CLOSE() operations.
572 *
573 * This is bad because it means a compromised adbd could
574 * send packets to close connections between the host and
575 * other devices. To avoid this, only allow this if the local
576 * socket has a peer on the same transport.
577 */
578 if (p->msg.arg0 == 0 && s->peer && s->peer->transport != t) {
579 D("Invalid A_CLSE(0, %u) from transport %s, expected transport %s\n",
580 p->msg.arg1, t->serial, s->peer->transport->serial);
581 } else {
582 s->close(s);
583 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800584 }
585 }
586 break;
587
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100588 case A_WRTE: /* WRITE(local-id, remote-id, <data>) */
589 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
590 if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800591 unsigned rid = p->msg.arg0;
592 p->len = p->msg.data_length;
593
594 if(s->enqueue(s, p) == 0) {
595 D("Enqueue the socket\n");
596 send_ready(s->id, rid, t);
597 }
598 return;
599 }
600 }
601 break;
602
603 default:
604 printf("handle_packet: what is %08x?!\n", p->msg.command);
605 }
606
607 put_apacket(p);
608}
609
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800610#if ADB_HOST
JP Abgrall571c1362012-12-06 18:18:12 -0800611
Stefan Hilzingera84a42e2010-04-19 12:21:12 +0100612int launch_server(int server_port)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800613{
Yabin Cuie77b6a02014-11-11 09:24:11 -0800614#if defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800615 /* we need to start the server in the background */
616 /* we create a PIPE that will be used to wait for the server's "OK" */
617 /* message since the pipe handles must be inheritable, we use a */
618 /* security attribute */
619 HANDLE pipe_read, pipe_write;
Ray Donnelly267aa8b2012-11-29 01:18:50 +0000620 HANDLE stdout_handle, stderr_handle;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800621 SECURITY_ATTRIBUTES sa;
622 STARTUPINFO startup;
623 PROCESS_INFORMATION pinfo;
624 char program_path[ MAX_PATH ];
625 int ret;
626
627 sa.nLength = sizeof(sa);
628 sa.lpSecurityDescriptor = NULL;
629 sa.bInheritHandle = TRUE;
630
631 /* create pipe, and ensure its read handle isn't inheritable */
632 ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
633 if (!ret) {
634 fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );
635 return -1;
636 }
637
638 SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );
639
Ray Donnelly267aa8b2012-11-29 01:18:50 +0000640 /* Some programs want to launch an adb command and collect its output by
641 * calling CreateProcess with inheritable stdout/stderr handles, then
642 * using read() to get its output. When this happens, the stdout/stderr
643 * handles passed to the adb client process will also be inheritable.
644 * When starting the adb server here, care must be taken to reset them
645 * to non-inheritable.
646 * Otherwise, something bad happens: even if the adb command completes,
647 * the calling process is stuck while read()-ing from the stdout/stderr
648 * descriptors, because they're connected to corresponding handles in the
649 * adb server process (even if the latter never uses/writes to them).
650 */
651 stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE );
652 stderr_handle = GetStdHandle( STD_ERROR_HANDLE );
653 if (stdout_handle != INVALID_HANDLE_VALUE) {
654 SetHandleInformation( stdout_handle, HANDLE_FLAG_INHERIT, 0 );
655 }
656 if (stderr_handle != INVALID_HANDLE_VALUE) {
657 SetHandleInformation( stderr_handle, HANDLE_FLAG_INHERIT, 0 );
658 }
659
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800660 ZeroMemory( &startup, sizeof(startup) );
661 startup.cb = sizeof(startup);
662 startup.hStdInput = GetStdHandle( STD_INPUT_HANDLE );
663 startup.hStdOutput = pipe_write;
664 startup.hStdError = GetStdHandle( STD_ERROR_HANDLE );
665 startup.dwFlags = STARTF_USESTDHANDLES;
666
667 ZeroMemory( &pinfo, sizeof(pinfo) );
668
669 /* get path of current program */
670 GetModuleFileName( NULL, program_path, sizeof(program_path) );
Wenhao Lia09558c2013-11-13 16:23:37 +0800671 char args[64];
672 snprintf(args, sizeof(args), "adb -P %d fork-server server", server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800673 ret = CreateProcess(
674 program_path, /* program path */
Wenhao Lia09558c2013-11-13 16:23:37 +0800675 args,
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800676 /* the fork-server argument will set the
677 debug = 2 in the child */
678 NULL, /* process handle is not inheritable */
679 NULL, /* thread handle is not inheritable */
680 TRUE, /* yes, inherit some handles */
681 DETACHED_PROCESS, /* the new process doesn't have a console */
682 NULL, /* use parent's environment block */
683 NULL, /* use parent's starting directory */
684 &startup, /* startup info, i.e. std handles */
685 &pinfo );
686
687 CloseHandle( pipe_write );
688
689 if (!ret) {
690 fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );
691 CloseHandle( pipe_read );
692 return -1;
693 }
694
695 CloseHandle( pinfo.hProcess );
696 CloseHandle( pinfo.hThread );
697
698 /* wait for the "OK\n" message */
699 {
700 char temp[3];
701 DWORD count;
702
703 ret = ReadFile( pipe_read, temp, 3, &count, NULL );
704 CloseHandle( pipe_read );
705 if ( !ret ) {
706 fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() );
707 return -1;
708 }
709 if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
710 fprintf(stderr, "ADB server didn't ACK\n" );
711 return -1;
712 }
713 }
Yabin Cuie77b6a02014-11-11 09:24:11 -0800714#else /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800715 char path[PATH_MAX];
716 int fd[2];
717
718 // set up a pipe so the child can tell us when it is ready.
719 // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child.
720 if (pipe(fd)) {
721 fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
722 return -1;
723 }
Alexey Tarasov31664102009-10-22 02:55:00 +1100724 get_my_path(path, PATH_MAX);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800725 pid_t pid = fork();
726 if(pid < 0) return -1;
727
728 if (pid == 0) {
729 // child side of the fork
730
731 // redirect stderr to the pipe
732 // we use stderr instead of stdout due to stdout's buffering behavior.
733 adb_close(fd[0]);
734 dup2(fd[1], STDERR_FILENO);
735 adb_close(fd[1]);
736
Matt Gumbeld7b33082012-11-14 10:16:17 -0800737 char str_port[30];
738 snprintf(str_port, sizeof(str_port), "%d", server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800739 // child process
Matt Gumbeld7b33082012-11-14 10:16:17 -0800740 int result = execl(path, "adb", "-P", str_port, "fork-server", "server", NULL);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800741 // this should not return
742 fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
743 } else {
744 // parent side of the fork
745
746 char temp[3];
747
748 temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
749 // wait for the "OK\n" message
750 adb_close(fd[1]);
751 int ret = adb_read(fd[0], temp, 3);
JP Abgrall408fa572011-03-16 15:57:42 -0700752 int saved_errno = errno;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800753 adb_close(fd[0]);
754 if (ret < 0) {
JP Abgrall408fa572011-03-16 15:57:42 -0700755 fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800756 return -1;
757 }
758 if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
759 fprintf(stderr, "ADB server didn't ACK\n" );
760 return -1;
761 }
762
763 setsid();
764 }
Yabin Cuie77b6a02014-11-11 09:24:11 -0800765#endif /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800766 return 0;
767}
Yabin Cuie77b6a02014-11-11 09:24:11 -0800768#endif /* ADB_HOST */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800769
David 'Digit' Turner25258692013-03-21 21:07:42 +0100770// Try to handle a network forwarding request.
771// This returns 1 on success, 0 on failure, and -1 to indicate this is not
772// a forwarding-related request.
773int handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd)
774{
775 if (!strcmp(service, "list-forward")) {
776 // Create the list of forward redirections.
777 int buffer_size = format_listeners(NULL, 0);
778 // Add one byte for the trailing zero.
Dan Albertbac34742015-02-25 17:51:28 -0800779 char* buffer = reinterpret_cast<char*>(malloc(buffer_size + 1));
780 if (buffer == nullptr) {
David 'Digit' Turner25258692013-03-21 21:07:42 +0100781 sendfailmsg(reply_fd, "not enough memory");
782 return 1;
783 }
784 (void) format_listeners(buffer, buffer_size + 1);
785#if ADB_HOST
786 send_msg_with_okay(reply_fd, buffer, buffer_size);
787#else
788 send_msg_with_header(reply_fd, buffer, buffer_size);
789#endif
790 free(buffer);
791 return 1;
792 }
793
794 if (!strcmp(service, "killforward-all")) {
795 remove_all_listeners();
796#if ADB_HOST
797 /* On the host: 1st OKAY is connect, 2nd OKAY is status */
798 adb_write(reply_fd, "OKAY", 4);
799#endif
800 adb_write(reply_fd, "OKAY", 4);
801 return 1;
802 }
803
804 if (!strncmp(service, "forward:",8) ||
805 !strncmp(service, "killforward:",12)) {
Dan Albertbac34742015-02-25 17:51:28 -0800806 char *local, *remote;
David 'Digit' Turner25258692013-03-21 21:07:42 +0100807 atransport *transport;
808
809 int createForward = strncmp(service, "kill", 4);
810 int no_rebind = 0;
811
812 local = strchr(service, ':') + 1;
813
814 // Handle forward:norebind:<local>... here
815 if (createForward && !strncmp(local, "norebind:", 9)) {
816 no_rebind = 1;
817 local = strchr(local, ':') + 1;
818 }
819
820 remote = strchr(local,';');
821
822 if (createForward) {
823 // Check forward: parameter format: '<local>;<remote>'
824 if(remote == 0) {
825 sendfailmsg(reply_fd, "malformed forward spec");
826 return 1;
827 }
828
829 *remote++ = 0;
830 if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) {
831 sendfailmsg(reply_fd, "malformed forward spec");
832 return 1;
833 }
834 } else {
835 // Check killforward: parameter format: '<local>'
836 if (local[0] == 0) {
837 sendfailmsg(reply_fd, "malformed forward spec");
838 return 1;
839 }
840 }
841
Elliott Hughes7be29c82015-04-16 22:54:44 -0700842 std::string error_msg;
843 transport = acquire_one_transport(CS_ANY, ttype, serial, &error_msg);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100844 if (!transport) {
Elliott Hughes7be29c82015-04-16 22:54:44 -0700845 sendfailmsg(reply_fd, error_msg.c_str());
David 'Digit' Turner25258692013-03-21 21:07:42 +0100846 return 1;
847 }
848
Elliott Hughes7b506092015-04-20 08:09:20 -0700849 install_status_t r;
David 'Digit' Turner25258692013-03-21 21:07:42 +0100850 if (createForward) {
851 r = install_listener(local, remote, transport, no_rebind);
852 } else {
853 r = remove_listener(local, transport);
854 }
Elliott Hughes7b506092015-04-20 08:09:20 -0700855 if (r == INSTALL_STATUS_OK) {
David 'Digit' Turner25258692013-03-21 21:07:42 +0100856#if ADB_HOST
857 /* On the host: 1st OKAY is connect, 2nd OKAY is status */
Dan Albertcc731cc2015-02-24 21:26:58 -0800858 WriteFdExactly(reply_fd, "OKAY", 4);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100859#endif
Dan Albertcc731cc2015-02-24 21:26:58 -0800860 WriteFdExactly(reply_fd, "OKAY", 4);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100861 return 1;
862 }
863
Elliott Hughes7b506092015-04-20 08:09:20 -0700864 std::string message;
865 switch (r) {
866 case INSTALL_STATUS_OK: message = " "; break;
867 case INSTALL_STATUS_INTERNAL_ERROR: message = "internal error"; break;
868 case INSTALL_STATUS_CANNOT_BIND:
869 message = android::base::StringPrintf("cannot bind to socket: %s", strerror(errno));
870 break;
871 case INSTALL_STATUS_CANNOT_REBIND:
872 message = android::base::StringPrintf("cannot rebind existing socket: %s", strerror(errno));
873 break;
874 case INSTALL_STATUS_LISTENER_NOT_FOUND: message = "listener not found"; break;
David 'Digit' Turner25258692013-03-21 21:07:42 +0100875 }
Elliott Hughes7b506092015-04-20 08:09:20 -0700876 sendfailmsg(reply_fd, message.c_str());
David 'Digit' Turner25258692013-03-21 21:07:42 +0100877 return 1;
878 }
879 return 0;
880}
881
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800882int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
883{
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800884 if(!strcmp(service, "kill")) {
885 fprintf(stderr,"adb server killed by remote request\n");
886 fflush(stdout);
887 adb_write(reply_fd, "OKAY", 4);
888 usb_cleanup();
889 exit(0);
890 }
891
892#if ADB_HOST
Chih-Hung Hsiehf787b382014-09-05 15:38:15 -0700893 atransport *transport = NULL;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800894 // "transport:" is used for switching transport with a specified serial number
895 // "transport-usb:" is used for switching transport to the only USB transport
896 // "transport-local:" is used for switching transport to the only local transport
897 // "transport-any:" is used for switching transport to the only transport
898 if (!strncmp(service, "transport", strlen("transport"))) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800899 transport_type type = kTransportAny;
900
901 if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
902 type = kTransportUsb;
903 } else if (!strncmp(service, "transport-local", strlen("transport-local"))) {
904 type = kTransportLocal;
905 } else if (!strncmp(service, "transport-any", strlen("transport-any"))) {
906 type = kTransportAny;
907 } else if (!strncmp(service, "transport:", strlen("transport:"))) {
908 service += strlen("transport:");
Tom Marlin3175c8e2011-07-27 12:56:14 -0500909 serial = service;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800910 }
911
Elliott Hughes7be29c82015-04-16 22:54:44 -0700912 std::string error_msg = "unknown failure";
913 transport = acquire_one_transport(CS_ANY, type, serial, &error_msg);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800914
915 if (transport) {
916 s->transport = transport;
917 adb_write(reply_fd, "OKAY", 4);
918 } else {
Elliott Hughes7be29c82015-04-16 22:54:44 -0700919 sendfailmsg(reply_fd, error_msg.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800920 }
921 return 1;
922 }
923
924 // return a list of all connected devices
Scott Andersone109d262012-04-20 11:21:14 -0700925 if (!strncmp(service, "devices", 7)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800926 char buffer[4096];
Scott Andersone109d262012-04-20 11:21:14 -0700927 int use_long = !strcmp(service+7, "-l");
928 if (use_long || service[7] == 0) {
Scott Andersone109d262012-04-20 11:21:14 -0700929 memset(buffer, 0, sizeof(buffer));
930 D("Getting device list \n");
931 list_transports(buffer, sizeof(buffer), use_long);
Scott Andersone109d262012-04-20 11:21:14 -0700932 D("Wrote device list \n");
Snild Dolkow2264e7c2014-01-30 10:08:38 +0100933 send_msg_with_okay(reply_fd, buffer, strlen(buffer));
Scott Andersone109d262012-04-20 11:21:14 -0700934 return 0;
935 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800936 }
937
Mike Lockwood74d7ff82009-10-11 23:04:18 -0400938 // remove TCP transport
939 if (!strncmp(service, "disconnect:", 11)) {
940 char buffer[4096];
941 memset(buffer, 0, sizeof(buffer));
942 char* serial = service + 11;
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -0400943 if (serial[0] == 0) {
944 // disconnect from all TCP devices
945 unregister_all_tcp_transports();
Mike Lockwood74d7ff82009-10-11 23:04:18 -0400946 } else {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -0400947 char hostbuf[100];
948 // assume port 5555 if no port is specified
949 if (!strchr(serial, ':')) {
950 snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial);
951 serial = hostbuf;
952 }
953 atransport *t = find_transport(serial);
954
955 if (t) {
956 unregister_transport(t);
957 } else {
958 snprintf(buffer, sizeof(buffer), "No such device %s", serial);
959 }
Mike Lockwood74d7ff82009-10-11 23:04:18 -0400960 }
961
Snild Dolkow2264e7c2014-01-30 10:08:38 +0100962 send_msg_with_okay(reply_fd, buffer, strlen(buffer));
Mike Lockwood2f38b692009-08-24 15:58:40 -0700963 return 0;
964 }
965
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800966 // returns our value for ADB_SERVER_VERSION
967 if (!strcmp(service, "version")) {
968 char version[12];
969 snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION);
Snild Dolkow2264e7c2014-01-30 10:08:38 +0100970 send_msg_with_okay(reply_fd, version, strlen(version));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800971 return 0;
972 }
973
974 if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {
Dan Albertbac34742015-02-25 17:51:28 -0800975 const char *out = "unknown";
976 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
Elliott Hughes7be29c82015-04-16 22:54:44 -0700977 if (transport && transport->serial) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800978 out = transport->serial;
979 }
Snild Dolkow2264e7c2014-01-30 10:08:38 +0100980 send_msg_with_okay(reply_fd, out, strlen(out));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800981 return 0;
982 }
Scott Andersone109d262012-04-20 11:21:14 -0700983 if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
Dan Albertbac34742015-02-25 17:51:28 -0800984 const char *out = "unknown";
985 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
Elliott Hughes7be29c82015-04-16 22:54:44 -0700986 if (transport && transport->devpath) {
Scott Andersone109d262012-04-20 11:21:14 -0700987 out = transport->devpath;
988 }
Snild Dolkow2264e7c2014-01-30 10:08:38 +0100989 send_msg_with_okay(reply_fd, out, strlen(out));
Scott Andersone109d262012-04-20 11:21:14 -0700990 return 0;
991 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800992 // indicates a new emulator instance has started
993 if (!strncmp(service,"emulator:",9)) {
994 int port = atoi(service+9);
995 local_connect(port);
996 /* we don't even need to send a reply */
997 return 0;
998 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800999
1000 if(!strncmp(service,"get-state",strlen("get-state"))) {
1001 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
Dan Albertbac34742015-02-25 17:51:28 -08001002 const char *state = connection_state_name(transport);
Snild Dolkow2264e7c2014-01-30 10:08:38 +01001003 send_msg_with_okay(reply_fd, state, strlen(state));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001004 return 0;
1005 }
Simon Yedc22c3c2014-07-14 17:23:06 -07001006#endif // ADB_HOST
1007
1008 int ret = handle_forward_request(service, ttype, serial, reply_fd);
1009 if (ret >= 0)
1010 return ret - 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001011 return -1;
1012}