blob: ad85184f6c99859ea17c578b951293b1e43caf71 [file] [log] [blame]
The Android Open Source Project9ca14dc2009-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 Albertdb6fe642015-03-19 15:21:08 -070017#define TRACE_TAG TRACE_ADB
18
19#include "sysdeps.h"
20#include "adb.h"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080021
Dan Albertecbd8742015-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 Project9ca14dc2009-03-03 19:32:55 -080027#include <stdio.h>
28#include <stdlib.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080029#include <string.h>
Mike Lockwood4ac1e282009-05-25 18:17:55 -040030#include <sys/time.h>
Dan Albertecbd8742015-03-08 21:12:08 -070031#include <time.h>
32
33#include <string>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080034
Benoit Goby2cc19e42012-04-12 12:23:49 -070035#include "adb_auth.h"
Dan Albert66a91b02015-02-24 21:26:58 -080036#include "adb_io.h"
Dan Albert020292b2015-02-18 18:03:26 -080037#include "adb_listeners.h"
Dan Albertb302d122015-02-24 15:51:19 -080038#include "transport.h"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080039
Scott Andersonfa020922012-05-25 14:10:02 -070040#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
41
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080042#if !ADB_HOST
Nick Kralevich7472d292013-05-23 09:54:13 -070043#include <cutils/properties.h>
Nick Kralevich9de01bd2013-02-28 14:12:58 -080044#include <sys/capability.h>
Jeff Sharkey11987252012-08-14 21:00:22 -070045#include <sys/mount.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080046#endif
47
JP Abgrall2e5dd6e2011-03-16 15:57:42 -070048#if ADB_TRACE
49ADB_MUTEX_DEFINE( D_lock );
50#endif
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080051
52int HOST = 0;
53
Scott Andersonfa020922012-05-25 14:10:02 -070054#if !ADB_HOST
Dan Albert432ffe22015-02-18 18:22:45 -080055const char *adb_device_banner = "device";
Scott Andersonfa020922012-05-25 14:10:02 -070056#endif
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080057
58void fatal(const char *fmt, ...)
59{
60 va_list ap;
61 va_start(ap, fmt);
62 fprintf(stderr, "error: ");
63 vfprintf(stderr, fmt, ap);
64 fprintf(stderr, "\n");
65 va_end(ap);
66 exit(-1);
67}
68
69void fatal_errno(const char *fmt, ...)
70{
71 va_list ap;
72 va_start(ap, fmt);
73 fprintf(stderr, "error: %s: ", strerror(errno));
74 vfprintf(stderr, fmt, ap);
75 fprintf(stderr, "\n");
76 va_end(ap);
77 exit(-1);
78}
79
Dan Albertecbd8742015-03-08 21:12:08 -070080#if !ADB_HOST
81void start_device_log(void) {
Dan Albertecbd8742015-03-08 21:12:08 -070082 struct tm now;
83 time_t t;
84 tzset();
85 time(&t);
86 localtime_r(&t, &now);
87
Dan Albertdec2b242015-03-19 22:53:30 -070088 char timestamp[PATH_MAX];
89 strftime(timestamp, sizeof(timestamp), "%Y-%m-%d-%H-%M-%S", &now);
Dan Albertecbd8742015-03-08 21:12:08 -070090
Dan Albertdec2b242015-03-19 22:53:30 -070091 char path[PATH_MAX];
92 snprintf(path, sizeof(path), "/data/adb/adb-%s-%d", timestamp, getpid());
93
94 int fd = unix_open(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640);
Dan Albertecbd8742015-03-08 21:12:08 -070095 if (fd == -1) {
96 return;
97 }
98
99 // redirect stdout and stderr to the log file
100 dup2(fd, STDOUT_FILENO);
101 dup2(fd, STDERR_FILENO);
102 fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid());
103 adb_close(fd);
Dan Albertecbd8742015-03-08 21:12:08 -0700104}
105#endif
106
107int adb_trace_mask;
108
109std::string get_trace_setting_from_env() {
110 const char* setting = getenv("ADB_TRACE");
111 if (setting == nullptr) {
112 setting = "";
113 }
114
115 return std::string(setting);
116}
117
118#if !ADB_HOST
119std::string get_trace_setting_from_prop() {
120 char buf[PROPERTY_VALUE_MAX];
121 property_get("persist.adb.trace_mask", buf, "");
122 return std::string(buf);
123}
124#endif
125
126std::string get_trace_setting() {
127#if ADB_HOST
128 return get_trace_setting_from_env();
129#else
130 return get_trace_setting_from_prop();
131#endif
132}
133
134// Split the comma/space/colum/semi-column separated list of tags from the trace
135// setting and build the trace mask from it. note that '1' and 'all' are special
136// cases to enable all tracing.
137//
138// adb's trace setting comes from the ADB_TRACE environment variable, whereas
139// adbd's comes from the system property persist.adb.trace_mask.
140void adb_trace_init() {
141 const std::string trace_setting = get_trace_setting();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800142
143 static const struct {
144 const char* tag;
145 int flag;
146 } tags[] = {
147 { "1", 0 },
148 { "all", 0 },
149 { "adb", TRACE_ADB },
150 { "sockets", TRACE_SOCKETS },
151 { "packets", TRACE_PACKETS },
152 { "rwx", TRACE_RWX },
153 { "usb", TRACE_USB },
154 { "sync", TRACE_SYNC },
155 { "sysdeps", TRACE_SYSDEPS },
156 { "transport", TRACE_TRANSPORT },
157 { "jdwp", TRACE_JDWP },
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700158 { "services", TRACE_SERVICES },
Benoit Goby2cc19e42012-04-12 12:23:49 -0700159 { "auth", TRACE_AUTH },
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800160 { NULL, 0 }
161 };
162
Dan Albertecbd8742015-03-08 21:12:08 -0700163 if (trace_setting.empty()) {
164 return;
165 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800166
Dan Albertecbd8742015-03-08 21:12:08 -0700167 // Use a comma/colon/semi-colon/space separated list
168 const char* p = trace_setting.c_str();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800169 while (*p) {
170 int len, tagn;
171
Dan Albertecbd8742015-03-08 21:12:08 -0700172 const char* q = strpbrk(p, " ,:;");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800173 if (q == NULL) {
174 q = p + strlen(p);
175 }
176 len = q - p;
177
Dan Albertecbd8742015-03-08 21:12:08 -0700178 for (tagn = 0; tags[tagn].tag != NULL; tagn++) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800179 int taglen = strlen(tags[tagn].tag);
180
Dan Albertecbd8742015-03-08 21:12:08 -0700181 if (len == taglen && !memcmp(tags[tagn].tag, p, len)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800182 int flag = tags[tagn].flag;
183 if (flag == 0) {
184 adb_trace_mask = ~0;
185 return;
186 }
187 adb_trace_mask |= (1 << flag);
188 break;
189 }
190 }
191 p = q;
192 if (*p)
193 p++;
194 }
Dan Albertecbd8742015-03-08 21:12:08 -0700195
196#if !ADB_HOST
197 start_device_log();
198#endif
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800199}
200
Dan Albertf30d73c2015-02-25 17:51:28 -0800201apacket* get_apacket(void)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800202{
Dan Albertf30d73c2015-02-25 17:51:28 -0800203 apacket* p = reinterpret_cast<apacket*>(malloc(sizeof(apacket)));
204 if (p == nullptr) {
205 fatal("failed to allocate an apacket");
206 }
207
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800208 memset(p, 0, sizeof(apacket) - MAX_PAYLOAD);
209 return p;
210}
211
212void put_apacket(apacket *p)
213{
214 free(p);
215}
216
Benoit Goby2cc19e42012-04-12 12:23:49 -0700217void handle_online(atransport *t)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800218{
219 D("adb: online\n");
Benoit Goby2cc19e42012-04-12 12:23:49 -0700220 t->online = 1;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800221}
222
223void handle_offline(atransport *t)
224{
225 D("adb: offline\n");
226 //Close the associated usb
Benoit Goby2cc19e42012-04-12 12:23:49 -0700227 t->online = 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800228 run_transport_disconnects(t);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800229}
230
Benoit Goby2cc19e42012-04-12 12:23:49 -0700231#if DEBUG_PACKETS
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800232#define DUMPMAX 32
233void print_packet(const char *label, apacket *p)
234{
235 char *tag;
236 char *x;
237 unsigned count;
238
239 switch(p->msg.command){
240 case A_SYNC: tag = "SYNC"; break;
241 case A_CNXN: tag = "CNXN" ; break;
242 case A_OPEN: tag = "OPEN"; break;
243 case A_OKAY: tag = "OKAY"; break;
244 case A_CLSE: tag = "CLSE"; break;
245 case A_WRTE: tag = "WRTE"; break;
Benoit Goby2cc19e42012-04-12 12:23:49 -0700246 case A_AUTH: tag = "AUTH"; break;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800247 default: tag = "????"; break;
248 }
249
250 fprintf(stderr, "%s: %s %08x %08x %04x \"",
251 label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length);
252 count = p->msg.data_length;
253 x = (char*) p->data;
254 if(count > DUMPMAX) {
255 count = DUMPMAX;
256 tag = "\n";
257 } else {
258 tag = "\"\n";
259 }
260 while(count-- > 0){
261 if((*x >= ' ') && (*x < 127)) {
262 fputc(*x, stderr);
263 } else {
264 fputc('.', stderr);
265 }
266 x++;
267 }
Benoit Goby2cc19e42012-04-12 12:23:49 -0700268 fputs(tag, stderr);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800269}
270#endif
271
272static void send_ready(unsigned local, unsigned remote, atransport *t)
273{
274 D("Calling send_ready \n");
275 apacket *p = get_apacket();
276 p->msg.command = A_OKAY;
277 p->msg.arg0 = local;
278 p->msg.arg1 = remote;
279 send_packet(p, t);
280}
281
282static void send_close(unsigned local, unsigned remote, atransport *t)
283{
284 D("Calling send_close \n");
285 apacket *p = get_apacket();
286 p->msg.command = A_CLSE;
287 p->msg.arg0 = local;
288 p->msg.arg1 = remote;
289 send_packet(p, t);
290}
291
Scott Andersonfa020922012-05-25 14:10:02 -0700292static size_t fill_connect_data(char *buf, size_t bufsize)
293{
294#if ADB_HOST
295 return snprintf(buf, bufsize, "host::") + 1;
296#else
297 static const char *cnxn_props[] = {
298 "ro.product.name",
299 "ro.product.model",
300 "ro.product.device",
301 };
302 static const int num_cnxn_props = ARRAY_SIZE(cnxn_props);
303 int i;
304 size_t remaining = bufsize;
305 size_t len;
306
307 len = snprintf(buf, remaining, "%s::", adb_device_banner);
308 remaining -= len;
309 buf += len;
310 for (i = 0; i < num_cnxn_props; i++) {
311 char value[PROPERTY_VALUE_MAX];
312 property_get(cnxn_props[i], value, "");
313 len = snprintf(buf, remaining, "%s=%s;", cnxn_props[i], value);
314 remaining -= len;
315 buf += len;
316 }
317
318 return bufsize - remaining + 1;
319#endif
320}
321
David 'Digit' Turner963a4492013-03-21 21:07:42 +0100322#if !ADB_HOST
323static void send_msg_with_header(int fd, const char* msg, size_t msglen) {
324 char header[5];
325 if (msglen > 0xffff)
326 msglen = 0xffff;
327 snprintf(header, sizeof(header), "%04x", (unsigned)msglen);
Dan Albert66a91b02015-02-24 21:26:58 -0800328 WriteFdExactly(fd, header, 4);
329 WriteFdExactly(fd, msg, msglen);
David 'Digit' Turner963a4492013-03-21 21:07:42 +0100330}
331#endif
332
Chih-Hung Hsiehf5de7662014-09-05 15:38:15 -0700333#if ADB_HOST
David 'Digit' Turner963a4492013-03-21 21:07:42 +0100334static void send_msg_with_okay(int fd, const char* msg, size_t msglen) {
Snild Dolkow4516a872014-01-30 10:08:38 +0100335 char header[9];
336 if (msglen > 0xffff)
337 msglen = 0xffff;
338 snprintf(header, sizeof(header), "OKAY%04x", (unsigned)msglen);
Dan Albert66a91b02015-02-24 21:26:58 -0800339 WriteFdExactly(fd, header, 8);
340 WriteFdExactly(fd, msg, msglen);
Snild Dolkow4516a872014-01-30 10:08:38 +0100341}
Chih-Hung Hsiehf5de7662014-09-05 15:38:15 -0700342#endif // ADB_HOST
Snild Dolkow4516a872014-01-30 10:08:38 +0100343
Dan Albert056ad0e2015-02-18 17:47:33 -0800344void send_connect(atransport *t)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800345{
346 D("Calling send_connect \n");
347 apacket *cp = get_apacket();
348 cp->msg.command = A_CNXN;
349 cp->msg.arg0 = A_VERSION;
350 cp->msg.arg1 = MAX_PAYLOAD;
Scott Andersonfa020922012-05-25 14:10:02 -0700351 cp->msg.data_length = fill_connect_data((char *)cp->data,
352 sizeof(cp->data));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800353 send_packet(cp, t);
Benoit Goby2cc19e42012-04-12 12:23:49 -0700354}
355
Chih-Hung Hsiehf5de7662014-09-05 15:38:15 -0700356#if ADB_HOST
Dan Albertf30d73c2015-02-25 17:51:28 -0800357static const char* connection_state_name(atransport *t)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800358{
359 if (t == NULL) {
360 return "unknown";
361 }
362
363 switch(t->connection_state) {
364 case CS_BOOTLOADER:
365 return "bootloader";
366 case CS_DEVICE:
367 return "device";
trevdd11cfc52013-04-17 14:34:23 +0100368 case CS_RECOVERY:
369 return "recovery";
370 case CS_SIDELOAD:
371 return "sideload";
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800372 case CS_OFFLINE:
373 return "offline";
Nick Kralevich23b39f02013-02-15 10:22:08 -0800374 case CS_UNAUTHORIZED:
375 return "unauthorized";
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800376 default:
377 return "unknown";
378 }
379}
Chih-Hung Hsiehf5de7662014-09-05 15:38:15 -0700380#endif // ADB_HOST
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800381
Scott Andersonfa020922012-05-25 14:10:02 -0700382/* qual_overwrite is used to overwrite a qualifier string. dst is a
383 * pointer to a char pointer. It is assumed that if *dst is non-NULL, it
Scott Anderson27042382012-05-30 18:11:27 -0700384 * was malloc'ed and needs to freed. *dst will be set to a dup of src.
Scott Andersonfa020922012-05-25 14:10:02 -0700385 */
386static void qual_overwrite(char **dst, const char *src)
387{
388 if (!dst)
389 return;
390
391 free(*dst);
392 *dst = NULL;
393
394 if (!src || !*src)
395 return;
396
397 *dst = strdup(src);
398}
399
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800400void parse_banner(char *banner, atransport *t)
401{
Scott Andersonfa020922012-05-25 14:10:02 -0700402 static const char *prop_seps = ";";
403 static const char key_val_sep = '=';
Scott Anderson27042382012-05-30 18:11:27 -0700404 char *cp;
405 char *type;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800406
407 D("parse_banner: %s\n", banner);
408 type = banner;
Scott Andersonfa020922012-05-25 14:10:02 -0700409 cp = strchr(type, ':');
410 if (cp) {
411 *cp++ = 0;
412 /* Nothing is done with second field. */
413 cp = strchr(cp, ':');
414 if (cp) {
415 char *save;
416 char *key;
Scott Anderson0fa59782012-06-05 17:54:27 -0700417 key = adb_strtok_r(cp + 1, prop_seps, &save);
Scott Andersonfa020922012-05-25 14:10:02 -0700418 while (key) {
419 cp = strchr(key, key_val_sep);
420 if (cp) {
421 *cp++ = '\0';
422 if (!strcmp(key, "ro.product.name"))
423 qual_overwrite(&t->product, cp);
424 else if (!strcmp(key, "ro.product.model"))
425 qual_overwrite(&t->model, cp);
426 else if (!strcmp(key, "ro.product.device"))
427 qual_overwrite(&t->device, cp);
428 }
Scott Anderson0fa59782012-06-05 17:54:27 -0700429 key = adb_strtok_r(NULL, prop_seps, &save);
Scott Andersonfa020922012-05-25 14:10:02 -0700430 }
431 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800432 }
433
434 if(!strcmp(type, "bootloader")){
435 D("setting connection_state to CS_BOOTLOADER\n");
436 t->connection_state = CS_BOOTLOADER;
437 update_transports();
438 return;
439 }
440
441 if(!strcmp(type, "device")) {
442 D("setting connection_state to CS_DEVICE\n");
443 t->connection_state = CS_DEVICE;
444 update_transports();
445 return;
446 }
447
448 if(!strcmp(type, "recovery")) {
449 D("setting connection_state to CS_RECOVERY\n");
450 t->connection_state = CS_RECOVERY;
451 update_transports();
452 return;
453 }
454
Doug Zongker6b217ed2012-01-09 14:54:53 -0800455 if(!strcmp(type, "sideload")) {
456 D("setting connection_state to CS_SIDELOAD\n");
457 t->connection_state = CS_SIDELOAD;
458 update_transports();
459 return;
460 }
461
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800462 t->connection_state = CS_HOST;
463}
464
465void handle_packet(apacket *p, atransport *t)
466{
467 asocket *s;
468
Viral Mehta841f9a72010-06-16 18:41:28 +0530469 D("handle_packet() %c%c%c%c\n", ((char*) (&(p->msg.command)))[0],
470 ((char*) (&(p->msg.command)))[1],
471 ((char*) (&(p->msg.command)))[2],
472 ((char*) (&(p->msg.command)))[3]);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800473 print_packet("recv", p);
474
475 switch(p->msg.command){
476 case A_SYNC:
477 if(p->msg.arg0){
478 send_packet(p, t);
479 if(HOST) send_connect(t);
480 } else {
481 t->connection_state = CS_OFFLINE;
482 handle_offline(t);
483 send_packet(p, t);
484 }
485 return;
486
487 case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
488 /* XXX verify version, etc */
489 if(t->connection_state != CS_OFFLINE) {
490 t->connection_state = CS_OFFLINE;
491 handle_offline(t);
492 }
Benoit Goby2cc19e42012-04-12 12:23:49 -0700493
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800494 parse_banner((char*) p->data, t);
Benoit Goby2cc19e42012-04-12 12:23:49 -0700495
496 if (HOST || !auth_enabled) {
497 handle_online(t);
498 if(!HOST) send_connect(t);
499 } else {
500 send_auth_request(t);
501 }
502 break;
503
504 case A_AUTH:
505 if (p->msg.arg0 == ADB_AUTH_TOKEN) {
Nick Kralevich23b39f02013-02-15 10:22:08 -0800506 t->connection_state = CS_UNAUTHORIZED;
Benoit Goby2cc19e42012-04-12 12:23:49 -0700507 t->key = adb_auth_nextkey(t->key);
508 if (t->key) {
509 send_auth_response(p->data, p->msg.data_length, t);
510 } else {
511 /* No more private keys to try, send the public key */
512 send_auth_publickey(t);
513 }
514 } else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) {
515 if (adb_auth_verify(t->token, p->data, p->msg.data_length)) {
516 adb_auth_verified(t);
517 t->failed_auth_attempts = 0;
518 } else {
519 if (t->failed_auth_attempts++ > 10)
520 adb_sleep_ms(1000);
521 send_auth_request(t);
522 }
523 } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) {
524 adb_auth_confirm_key(p->data, p->msg.data_length, t);
525 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800526 break;
527
528 case A_OPEN: /* OPEN(local-id, 0, "destination") */
David 'Digit' Turnere92344d2013-12-13 14:09:44 +0100529 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800530 char *name = (char*) p->data;
531 name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
532 s = create_local_service_socket(name);
533 if(s == 0) {
534 send_close(0, p->msg.arg0, t);
535 } else {
536 s->peer = create_remote_socket(p->msg.arg0, t);
537 s->peer->peer = s;
538 send_ready(s->id, s->peer->id, t);
539 s->ready(s);
540 }
541 }
542 break;
543
544 case A_OKAY: /* READY(local-id, remote-id, "") */
David 'Digit' Turnere92344d2013-12-13 14:09:44 +0100545 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
546 if((s = find_local_socket(p->msg.arg1, 0))) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800547 if(s->peer == 0) {
David 'Digit' Turnere92344d2013-12-13 14:09:44 +0100548 /* On first READY message, create the connection. */
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800549 s->peer = create_remote_socket(p->msg.arg0, t);
550 s->peer->peer = s;
David 'Digit' Turnere92344d2013-12-13 14:09:44 +0100551 s->ready(s);
552 } else if (s->peer->id == p->msg.arg0) {
553 /* Other READY messages must use the same local-id */
554 s->ready(s);
555 } else {
556 D("Invalid A_OKAY(%d,%d), expected A_OKAY(%d,%d) on transport %s\n",
557 p->msg.arg0, p->msg.arg1, s->peer->id, p->msg.arg1, t->serial);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800558 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800559 }
560 }
561 break;
562
David 'Digit' Turnere92344d2013-12-13 14:09:44 +0100563 case A_CLSE: /* CLOSE(local-id, remote-id, "") or CLOSE(0, remote-id, "") */
564 if (t->online && p->msg.arg1 != 0) {
565 if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
566 /* According to protocol.txt, p->msg.arg0 might be 0 to indicate
567 * a failed OPEN only. However, due to a bug in previous ADB
568 * versions, CLOSE(0, remote-id, "") was also used for normal
569 * CLOSE() operations.
570 *
571 * This is bad because it means a compromised adbd could
572 * send packets to close connections between the host and
573 * other devices. To avoid this, only allow this if the local
574 * socket has a peer on the same transport.
575 */
576 if (p->msg.arg0 == 0 && s->peer && s->peer->transport != t) {
577 D("Invalid A_CLSE(0, %u) from transport %s, expected transport %s\n",
578 p->msg.arg1, t->serial, s->peer->transport->serial);
579 } else {
580 s->close(s);
581 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800582 }
583 }
584 break;
585
David 'Digit' Turnere92344d2013-12-13 14:09:44 +0100586 case A_WRTE: /* WRITE(local-id, remote-id, <data>) */
587 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
588 if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800589 unsigned rid = p->msg.arg0;
590 p->len = p->msg.data_length;
591
592 if(s->enqueue(s, p) == 0) {
593 D("Enqueue the socket\n");
594 send_ready(s->id, rid, t);
595 }
596 return;
597 }
598 }
599 break;
600
601 default:
602 printf("handle_packet: what is %08x?!\n", p->msg.command);
603 }
604
605 put_apacket(p);
606}
607
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800608#if ADB_HOST
Nick Kralevich23b39f02013-02-15 10:22:08 -0800609
Stefan Hilzinger92ca4fa2010-04-19 12:21:12 +0100610int launch_server(int server_port)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800611{
Yabin Cui2fa43212014-11-11 09:24:11 -0800612#if defined(_WIN32)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800613 /* we need to start the server in the background */
614 /* we create a PIPE that will be used to wait for the server's "OK" */
615 /* message since the pipe handles must be inheritable, we use a */
616 /* security attribute */
617 HANDLE pipe_read, pipe_write;
Ray Donnellyc0324702012-11-29 01:18:50 +0000618 HANDLE stdout_handle, stderr_handle;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800619 SECURITY_ATTRIBUTES sa;
620 STARTUPINFO startup;
621 PROCESS_INFORMATION pinfo;
622 char program_path[ MAX_PATH ];
623 int ret;
624
625 sa.nLength = sizeof(sa);
626 sa.lpSecurityDescriptor = NULL;
627 sa.bInheritHandle = TRUE;
628
629 /* create pipe, and ensure its read handle isn't inheritable */
630 ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
631 if (!ret) {
632 fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );
633 return -1;
634 }
635
636 SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );
637
Ray Donnellyc0324702012-11-29 01:18:50 +0000638 /* Some programs want to launch an adb command and collect its output by
639 * calling CreateProcess with inheritable stdout/stderr handles, then
640 * using read() to get its output. When this happens, the stdout/stderr
641 * handles passed to the adb client process will also be inheritable.
642 * When starting the adb server here, care must be taken to reset them
643 * to non-inheritable.
644 * Otherwise, something bad happens: even if the adb command completes,
645 * the calling process is stuck while read()-ing from the stdout/stderr
646 * descriptors, because they're connected to corresponding handles in the
647 * adb server process (even if the latter never uses/writes to them).
648 */
649 stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE );
650 stderr_handle = GetStdHandle( STD_ERROR_HANDLE );
651 if (stdout_handle != INVALID_HANDLE_VALUE) {
652 SetHandleInformation( stdout_handle, HANDLE_FLAG_INHERIT, 0 );
653 }
654 if (stderr_handle != INVALID_HANDLE_VALUE) {
655 SetHandleInformation( stderr_handle, HANDLE_FLAG_INHERIT, 0 );
656 }
657
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800658 ZeroMemory( &startup, sizeof(startup) );
659 startup.cb = sizeof(startup);
660 startup.hStdInput = GetStdHandle( STD_INPUT_HANDLE );
661 startup.hStdOutput = pipe_write;
662 startup.hStdError = GetStdHandle( STD_ERROR_HANDLE );
663 startup.dwFlags = STARTF_USESTDHANDLES;
664
665 ZeroMemory( &pinfo, sizeof(pinfo) );
666
667 /* get path of current program */
668 GetModuleFileName( NULL, program_path, sizeof(program_path) );
Wenhao Lie0fa2c52013-11-13 16:23:37 +0800669 char args[64];
670 snprintf(args, sizeof(args), "adb -P %d fork-server server", server_port);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800671 ret = CreateProcess(
672 program_path, /* program path */
Wenhao Lie0fa2c52013-11-13 16:23:37 +0800673 args,
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800674 /* the fork-server argument will set the
675 debug = 2 in the child */
676 NULL, /* process handle is not inheritable */
677 NULL, /* thread handle is not inheritable */
678 TRUE, /* yes, inherit some handles */
679 DETACHED_PROCESS, /* the new process doesn't have a console */
680 NULL, /* use parent's environment block */
681 NULL, /* use parent's starting directory */
682 &startup, /* startup info, i.e. std handles */
683 &pinfo );
684
685 CloseHandle( pipe_write );
686
687 if (!ret) {
688 fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );
689 CloseHandle( pipe_read );
690 return -1;
691 }
692
693 CloseHandle( pinfo.hProcess );
694 CloseHandle( pinfo.hThread );
695
696 /* wait for the "OK\n" message */
697 {
698 char temp[3];
699 DWORD count;
700
701 ret = ReadFile( pipe_read, temp, 3, &count, NULL );
702 CloseHandle( pipe_read );
703 if ( !ret ) {
704 fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() );
705 return -1;
706 }
707 if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
708 fprintf(stderr, "ADB server didn't ACK\n" );
709 return -1;
710 }
711 }
Yabin Cui2fa43212014-11-11 09:24:11 -0800712#else /* !defined(_WIN32) */
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800713 char path[PATH_MAX];
714 int fd[2];
715
716 // set up a pipe so the child can tell us when it is ready.
717 // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child.
718 if (pipe(fd)) {
719 fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
720 return -1;
721 }
Alexey Tarasov857f17a2009-10-22 02:55:00 +1100722 get_my_path(path, PATH_MAX);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800723 pid_t pid = fork();
724 if(pid < 0) return -1;
725
726 if (pid == 0) {
727 // child side of the fork
728
729 // redirect stderr to the pipe
730 // we use stderr instead of stdout due to stdout's buffering behavior.
731 adb_close(fd[0]);
732 dup2(fd[1], STDERR_FILENO);
733 adb_close(fd[1]);
734
Matt Gumbel411775c2012-11-14 10:16:17 -0800735 char str_port[30];
736 snprintf(str_port, sizeof(str_port), "%d", server_port);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800737 // child process
Matt Gumbel411775c2012-11-14 10:16:17 -0800738 int result = execl(path, "adb", "-P", str_port, "fork-server", "server", NULL);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800739 // this should not return
740 fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
741 } else {
742 // parent side of the fork
743
744 char temp[3];
745
746 temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
747 // wait for the "OK\n" message
748 adb_close(fd[1]);
749 int ret = adb_read(fd[0], temp, 3);
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700750 int saved_errno = errno;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800751 adb_close(fd[0]);
752 if (ret < 0) {
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700753 fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800754 return -1;
755 }
756 if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
757 fprintf(stderr, "ADB server didn't ACK\n" );
758 return -1;
759 }
760
761 setsid();
762 }
Yabin Cui2fa43212014-11-11 09:24:11 -0800763#endif /* !defined(_WIN32) */
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800764 return 0;
765}
Yabin Cui2fa43212014-11-11 09:24:11 -0800766#endif /* ADB_HOST */
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800767
David 'Digit' Turner963a4492013-03-21 21:07:42 +0100768// Try to handle a network forwarding request.
769// This returns 1 on success, 0 on failure, and -1 to indicate this is not
770// a forwarding-related request.
771int handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd)
772{
773 if (!strcmp(service, "list-forward")) {
774 // Create the list of forward redirections.
775 int buffer_size = format_listeners(NULL, 0);
776 // Add one byte for the trailing zero.
Dan Albertf30d73c2015-02-25 17:51:28 -0800777 char* buffer = reinterpret_cast<char*>(malloc(buffer_size + 1));
778 if (buffer == nullptr) {
David 'Digit' Turner963a4492013-03-21 21:07:42 +0100779 sendfailmsg(reply_fd, "not enough memory");
780 return 1;
781 }
782 (void) format_listeners(buffer, buffer_size + 1);
783#if ADB_HOST
784 send_msg_with_okay(reply_fd, buffer, buffer_size);
785#else
786 send_msg_with_header(reply_fd, buffer, buffer_size);
787#endif
788 free(buffer);
789 return 1;
790 }
791
792 if (!strcmp(service, "killforward-all")) {
793 remove_all_listeners();
794#if ADB_HOST
795 /* On the host: 1st OKAY is connect, 2nd OKAY is status */
796 adb_write(reply_fd, "OKAY", 4);
797#endif
798 adb_write(reply_fd, "OKAY", 4);
799 return 1;
800 }
801
802 if (!strncmp(service, "forward:",8) ||
803 !strncmp(service, "killforward:",12)) {
Dan Albertf30d73c2015-02-25 17:51:28 -0800804 char *local, *remote;
David 'Digit' Turner963a4492013-03-21 21:07:42 +0100805 int r;
806 atransport *transport;
807
808 int createForward = strncmp(service, "kill", 4);
809 int no_rebind = 0;
810
811 local = strchr(service, ':') + 1;
812
813 // Handle forward:norebind:<local>... here
814 if (createForward && !strncmp(local, "norebind:", 9)) {
815 no_rebind = 1;
816 local = strchr(local, ':') + 1;
817 }
818
819 remote = strchr(local,';');
820
821 if (createForward) {
822 // Check forward: parameter format: '<local>;<remote>'
823 if(remote == 0) {
824 sendfailmsg(reply_fd, "malformed forward spec");
825 return 1;
826 }
827
828 *remote++ = 0;
829 if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) {
830 sendfailmsg(reply_fd, "malformed forward spec");
831 return 1;
832 }
833 } else {
834 // Check killforward: parameter format: '<local>'
835 if (local[0] == 0) {
836 sendfailmsg(reply_fd, "malformed forward spec");
837 return 1;
838 }
839 }
840
Dan Albertf30d73c2015-02-25 17:51:28 -0800841 const char* err;
David 'Digit' Turner963a4492013-03-21 21:07:42 +0100842 transport = acquire_one_transport(CS_ANY, ttype, serial, &err);
843 if (!transport) {
844 sendfailmsg(reply_fd, err);
845 return 1;
846 }
847
848 if (createForward) {
849 r = install_listener(local, remote, transport, no_rebind);
850 } else {
851 r = remove_listener(local, transport);
852 }
853 if(r == 0) {
854#if ADB_HOST
855 /* On the host: 1st OKAY is connect, 2nd OKAY is status */
Dan Albert66a91b02015-02-24 21:26:58 -0800856 WriteFdExactly(reply_fd, "OKAY", 4);
David 'Digit' Turner963a4492013-03-21 21:07:42 +0100857#endif
Dan Albert66a91b02015-02-24 21:26:58 -0800858 WriteFdExactly(reply_fd, "OKAY", 4);
David 'Digit' Turner963a4492013-03-21 21:07:42 +0100859 return 1;
860 }
861
862 if (createForward) {
863 const char* message;
864 switch (r) {
865 case INSTALL_STATUS_CANNOT_BIND:
866 message = "cannot bind to socket";
867 break;
868 case INSTALL_STATUS_CANNOT_REBIND:
869 message = "cannot rebind existing socket";
870 break;
871 default:
872 message = "internal error";
873 }
874 sendfailmsg(reply_fd, message);
875 } else {
876 sendfailmsg(reply_fd, "cannot remove listener");
877 }
878 return 1;
879 }
880 return 0;
881}
882
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800883int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
884{
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800885 if(!strcmp(service, "kill")) {
886 fprintf(stderr,"adb server killed by remote request\n");
887 fflush(stdout);
888 adb_write(reply_fd, "OKAY", 4);
889 usb_cleanup();
890 exit(0);
891 }
892
893#if ADB_HOST
Chih-Hung Hsiehf5de7662014-09-05 15:38:15 -0700894 atransport *transport = NULL;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800895 // "transport:" is used for switching transport with a specified serial number
896 // "transport-usb:" is used for switching transport to the only USB transport
897 // "transport-local:" is used for switching transport to the only local transport
898 // "transport-any:" is used for switching transport to the only transport
899 if (!strncmp(service, "transport", strlen("transport"))) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800900 transport_type type = kTransportAny;
901
902 if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
903 type = kTransportUsb;
904 } else if (!strncmp(service, "transport-local", strlen("transport-local"))) {
905 type = kTransportLocal;
906 } else if (!strncmp(service, "transport-any", strlen("transport-any"))) {
907 type = kTransportAny;
908 } else if (!strncmp(service, "transport:", strlen("transport:"))) {
909 service += strlen("transport:");
Tom Marlin851ee3a2011-07-27 12:56:14 -0500910 serial = service;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800911 }
912
Dan Albertf30d73c2015-02-25 17:51:28 -0800913 const char* error_string = "unknown failure";
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800914 transport = acquire_one_transport(CS_ANY, type, serial, &error_string);
915
916 if (transport) {
917 s->transport = transport;
918 adb_write(reply_fd, "OKAY", 4);
919 } else {
920 sendfailmsg(reply_fd, error_string);
921 }
922 return 1;
923 }
924
925 // return a list of all connected devices
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700926 if (!strncmp(service, "devices", 7)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800927 char buffer[4096];
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700928 int use_long = !strcmp(service+7, "-l");
929 if (use_long || service[7] == 0) {
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700930 memset(buffer, 0, sizeof(buffer));
931 D("Getting device list \n");
932 list_transports(buffer, sizeof(buffer), use_long);
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700933 D("Wrote device list \n");
Snild Dolkow4516a872014-01-30 10:08:38 +0100934 send_msg_with_okay(reply_fd, buffer, strlen(buffer));
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700935 return 0;
936 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800937 }
938
Mike Lockwood5f2c4a12009-10-11 23:04:18 -0400939 // remove TCP transport
940 if (!strncmp(service, "disconnect:", 11)) {
941 char buffer[4096];
942 memset(buffer, 0, sizeof(buffer));
943 char* serial = service + 11;
Mike Lockwood01c2c302010-05-24 10:44:35 -0400944 if (serial[0] == 0) {
945 // disconnect from all TCP devices
946 unregister_all_tcp_transports();
Mike Lockwood5f2c4a12009-10-11 23:04:18 -0400947 } else {
Mike Lockwood01c2c302010-05-24 10:44:35 -0400948 char hostbuf[100];
949 // assume port 5555 if no port is specified
950 if (!strchr(serial, ':')) {
951 snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial);
952 serial = hostbuf;
953 }
954 atransport *t = find_transport(serial);
955
956 if (t) {
957 unregister_transport(t);
958 } else {
959 snprintf(buffer, sizeof(buffer), "No such device %s", serial);
960 }
Mike Lockwood5f2c4a12009-10-11 23:04:18 -0400961 }
962
Snild Dolkow4516a872014-01-30 10:08:38 +0100963 send_msg_with_okay(reply_fd, buffer, strlen(buffer));
Mike Lockwoodb51ae572009-08-24 15:58:40 -0700964 return 0;
965 }
966
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800967 // returns our value for ADB_SERVER_VERSION
968 if (!strcmp(service, "version")) {
969 char version[12];
970 snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION);
Snild Dolkow4516a872014-01-30 10:08:38 +0100971 send_msg_with_okay(reply_fd, version, strlen(version));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800972 return 0;
973 }
974
975 if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {
Dan Albertf30d73c2015-02-25 17:51:28 -0800976 const char *out = "unknown";
977 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800978 if (transport && transport->serial) {
979 out = transport->serial;
980 }
Snild Dolkow4516a872014-01-30 10:08:38 +0100981 send_msg_with_okay(reply_fd, out, strlen(out));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800982 return 0;
983 }
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700984 if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
Dan Albertf30d73c2015-02-25 17:51:28 -0800985 const char *out = "unknown";
986 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700987 if (transport && transport->devpath) {
988 out = transport->devpath;
989 }
Snild Dolkow4516a872014-01-30 10:08:38 +0100990 send_msg_with_okay(reply_fd, out, strlen(out));
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700991 return 0;
992 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800993 // indicates a new emulator instance has started
994 if (!strncmp(service,"emulator:",9)) {
995 int port = atoi(service+9);
996 local_connect(port);
997 /* we don't even need to send a reply */
998 return 0;
999 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001000
1001 if(!strncmp(service,"get-state",strlen("get-state"))) {
1002 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
Dan Albertf30d73c2015-02-25 17:51:28 -08001003 const char *state = connection_state_name(transport);
Snild Dolkow4516a872014-01-30 10:08:38 +01001004 send_msg_with_okay(reply_fd, state, strlen(state));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001005 return 0;
1006 }
Simon Yee51c11e2014-07-14 17:23:06 -07001007#endif // ADB_HOST
1008
1009 int ret = handle_forward_request(service, ttype, serial, reply_fd);
1010 if (ret >= 0)
1011 return ret - 1;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001012 return -1;
1013}