blob: 11c65da494123f1e0d199a5b69723cccd2c6d363 [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>
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -070036#include <base/strings.h>
Elliott Hughes7b506092015-04-20 08:09:20 -070037
Benoit Gobyd5fcafa2012-04-12 12:23:49 -070038#include "adb_auth.h"
Dan Albertcc731cc2015-02-24 21:26:58 -080039#include "adb_io.h"
Dan Alberte9fca142015-02-18 18:03:26 -080040#include "adb_listeners.h"
Dan Albert76649012015-02-24 15:51:19 -080041#include "transport.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080042
Scott Andersone82c2db2012-05-25 14:10:02 -070043#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
44
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080045#if !ADB_HOST
Nick Kralevich893a4a42013-05-23 09:54:13 -070046#include <cutils/properties.h>
Nick Kraleviche2864bf2013-02-28 14:12:58 -080047#include <sys/capability.h>
Jeff Sharkey885342a2012-08-14 21:00:22 -070048#include <sys/mount.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080049#endif
50
JP Abgrall408fa572011-03-16 15:57:42 -070051ADB_MUTEX_DEFINE( D_lock );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080052
53int HOST = 0;
54
Scott Andersone82c2db2012-05-25 14:10:02 -070055#if !ADB_HOST
Dan Albertbd0b7502015-02-18 18:22:45 -080056const char *adb_device_banner = "device";
Scott Andersone82c2db2012-05-25 14:10:02 -070057#endif
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080058
59void fatal(const char *fmt, ...)
60{
61 va_list ap;
62 va_start(ap, fmt);
63 fprintf(stderr, "error: ");
64 vfprintf(stderr, fmt, ap);
65 fprintf(stderr, "\n");
66 va_end(ap);
67 exit(-1);
68}
69
70void fatal_errno(const char *fmt, ...)
71{
72 va_list ap;
73 va_start(ap, fmt);
74 fprintf(stderr, "error: %s: ", strerror(errno));
75 vfprintf(stderr, fmt, ap);
76 fprintf(stderr, "\n");
77 va_end(ap);
78 exit(-1);
79}
80
Dan Albertea2175a2015-03-08 21:12:08 -070081#if !ADB_HOST
82void start_device_log(void) {
Dan Albertea2175a2015-03-08 21:12:08 -070083 struct tm now;
84 time_t t;
85 tzset();
86 time(&t);
87 localtime_r(&t, &now);
88
Dan Albert8743ef92015-03-19 22:53:30 -070089 char timestamp[PATH_MAX];
90 strftime(timestamp, sizeof(timestamp), "%Y-%m-%d-%H-%M-%S", &now);
Dan Albertea2175a2015-03-08 21:12:08 -070091
Dan Albert8743ef92015-03-19 22:53:30 -070092 char path[PATH_MAX];
93 snprintf(path, sizeof(path), "/data/adb/adb-%s-%d", timestamp, getpid());
94
95 int fd = unix_open(path, 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
135// Split the comma/space/colum/semi-column separated list of tags from the trace
136// setting and build the trace mask from it. note that '1' and 'all' are special
137// cases to enable all tracing.
138//
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
144 static const struct {
145 const char* tag;
146 int flag;
147 } tags[] = {
148 { "1", 0 },
149 { "all", 0 },
150 { "adb", TRACE_ADB },
151 { "sockets", TRACE_SOCKETS },
152 { "packets", TRACE_PACKETS },
153 { "rwx", TRACE_RWX },
154 { "usb", TRACE_USB },
155 { "sync", TRACE_SYNC },
156 { "sysdeps", TRACE_SYSDEPS },
157 { "transport", TRACE_TRANSPORT },
158 { "jdwp", TRACE_JDWP },
JP Abgrall408fa572011-03-16 15:57:42 -0700159 { "services", TRACE_SERVICES },
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700160 { "auth", TRACE_AUTH },
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800161 { NULL, 0 }
162 };
163
Dan Albertea2175a2015-03-08 21:12:08 -0700164 if (trace_setting.empty()) {
165 return;
166 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800167
Dan Albertea2175a2015-03-08 21:12:08 -0700168 // Use a comma/colon/semi-colon/space separated list
169 const char* p = trace_setting.c_str();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800170 while (*p) {
171 int len, tagn;
172
Dan Albertea2175a2015-03-08 21:12:08 -0700173 const char* q = strpbrk(p, " ,:;");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800174 if (q == NULL) {
175 q = p + strlen(p);
176 }
177 len = q - p;
178
Dan Albertea2175a2015-03-08 21:12:08 -0700179 for (tagn = 0; tags[tagn].tag != NULL; tagn++) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800180 int taglen = strlen(tags[tagn].tag);
181
Dan Albertea2175a2015-03-08 21:12:08 -0700182 if (len == taglen && !memcmp(tags[tagn].tag, p, len)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800183 int flag = tags[tagn].flag;
184 if (flag == 0) {
185 adb_trace_mask = ~0;
186 return;
187 }
188 adb_trace_mask |= (1 << flag);
189 break;
190 }
191 }
192 p = q;
193 if (*p)
194 p++;
195 }
Dan Albertea2175a2015-03-08 21:12:08 -0700196
197#if !ADB_HOST
198 start_device_log();
199#endif
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800200}
201
Dan Albertbac34742015-02-25 17:51:28 -0800202apacket* get_apacket(void)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800203{
Dan Albertbac34742015-02-25 17:51:28 -0800204 apacket* p = reinterpret_cast<apacket*>(malloc(sizeof(apacket)));
205 if (p == nullptr) {
206 fatal("failed to allocate an apacket");
207 }
208
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800209 memset(p, 0, sizeof(apacket) - MAX_PAYLOAD);
210 return p;
211}
212
213void put_apacket(apacket *p)
214{
215 free(p);
216}
217
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700218void handle_online(atransport *t)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800219{
220 D("adb: online\n");
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700221 t->online = 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800222}
223
224void handle_offline(atransport *t)
225{
226 D("adb: offline\n");
227 //Close the associated usb
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700228 t->online = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800229 run_transport_disconnects(t);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800230}
231
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700232#if DEBUG_PACKETS
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800233#define DUMPMAX 32
234void print_packet(const char *label, apacket *p)
235{
236 char *tag;
237 char *x;
238 unsigned count;
239
240 switch(p->msg.command){
241 case A_SYNC: tag = "SYNC"; break;
242 case A_CNXN: tag = "CNXN" ; break;
243 case A_OPEN: tag = "OPEN"; break;
244 case A_OKAY: tag = "OKAY"; break;
245 case A_CLSE: tag = "CLSE"; break;
246 case A_WRTE: tag = "WRTE"; break;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700247 case A_AUTH: tag = "AUTH"; break;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800248 default: tag = "????"; break;
249 }
250
251 fprintf(stderr, "%s: %s %08x %08x %04x \"",
252 label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length);
253 count = p->msg.data_length;
254 x = (char*) p->data;
255 if(count > DUMPMAX) {
256 count = DUMPMAX;
257 tag = "\n";
258 } else {
259 tag = "\"\n";
260 }
261 while(count-- > 0){
262 if((*x >= ' ') && (*x < 127)) {
263 fputc(*x, stderr);
264 } else {
265 fputc('.', stderr);
266 }
267 x++;
268 }
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700269 fputs(tag, stderr);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800270}
271#endif
272
273static void send_ready(unsigned local, unsigned remote, atransport *t)
274{
275 D("Calling send_ready \n");
276 apacket *p = get_apacket();
277 p->msg.command = A_OKAY;
278 p->msg.arg0 = local;
279 p->msg.arg1 = remote;
280 send_packet(p, t);
281}
282
283static void send_close(unsigned local, unsigned remote, atransport *t)
284{
285 D("Calling send_close \n");
286 apacket *p = get_apacket();
287 p->msg.command = A_CLSE;
288 p->msg.arg0 = local;
289 p->msg.arg1 = remote;
290 send_packet(p, t);
291}
292
Scott Andersone82c2db2012-05-25 14:10:02 -0700293static size_t fill_connect_data(char *buf, size_t bufsize)
294{
295#if ADB_HOST
296 return snprintf(buf, bufsize, "host::") + 1;
297#else
298 static const char *cnxn_props[] = {
299 "ro.product.name",
300 "ro.product.model",
301 "ro.product.device",
302 };
303 static const int num_cnxn_props = ARRAY_SIZE(cnxn_props);
304 int i;
305 size_t remaining = bufsize;
306 size_t len;
307
308 len = snprintf(buf, remaining, "%s::", adb_device_banner);
309 remaining -= len;
310 buf += len;
311 for (i = 0; i < num_cnxn_props; i++) {
312 char value[PROPERTY_VALUE_MAX];
313 property_get(cnxn_props[i], value, "");
314 len = snprintf(buf, remaining, "%s=%s;", cnxn_props[i], value);
315 remaining -= len;
316 buf += len;
317 }
318
319 return bufsize - remaining + 1;
320#endif
321}
322
Dan Albertba3a2512015-02-18 17:47:33 -0800323void send_connect(atransport *t)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800324{
325 D("Calling send_connect \n");
326 apacket *cp = get_apacket();
327 cp->msg.command = A_CNXN;
328 cp->msg.arg0 = A_VERSION;
329 cp->msg.arg1 = MAX_PAYLOAD;
Scott Andersone82c2db2012-05-25 14:10:02 -0700330 cp->msg.data_length = fill_connect_data((char *)cp->data,
331 sizeof(cp->data));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800332 send_packet(cp, t);
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700333}
334
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700335// qual_overwrite is used to overwrite a qualifier string. dst is a
336// pointer to a char pointer. It is assumed that if *dst is non-NULL, it
337// was malloc'ed and needs to freed. *dst will be set to a dup of src.
338// TODO: switch to std::string for these atransport fields instead.
339static void qual_overwrite(char** dst, const std::string& src) {
Scott Andersone82c2db2012-05-25 14:10:02 -0700340 free(*dst);
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700341 *dst = strdup(src.c_str());
Scott Andersone82c2db2012-05-25 14:10:02 -0700342}
343
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700344void parse_banner(const char* banner, atransport* t) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800345 D("parse_banner: %s\n", banner);
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700346
347 // The format is something like:
348 // "device::ro.product.name=x;ro.product.model=y;ro.product.device=z;".
349 std::vector<std::string> pieces = android::base::Split(banner, ":");
350
351 if (pieces.size() > 2) {
352 const std::string& props = pieces[2];
353 for (auto& prop : android::base::Split(props, ";")) {
354 // The list of properties was traditionally ;-terminated rather than ;-separated.
355 if (prop.empty()) continue;
356
357 std::vector<std::string> key_value = android::base::Split(prop, "=");
358 if (key_value.size() != 2) continue;
359
360 const std::string& key = key_value[0];
361 const std::string& value = key_value[1];
362 if (key == "ro.product.name") {
363 qual_overwrite(&t->product, value);
364 } else if (key == "ro.product.model") {
365 qual_overwrite(&t->model, value);
366 } else if (key == "ro.product.device") {
367 qual_overwrite(&t->device, value);
Scott Andersone82c2db2012-05-25 14:10:02 -0700368 }
369 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800370 }
371
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700372 const std::string& type = pieces[0];
373 if (type == "bootloader") {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800374 D("setting connection_state to CS_BOOTLOADER\n");
375 t->connection_state = CS_BOOTLOADER;
376 update_transports();
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700377 } else if (type == "device") {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800378 D("setting connection_state to CS_DEVICE\n");
379 t->connection_state = CS_DEVICE;
380 update_transports();
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700381 } else if (type == "recovery") {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800382 D("setting connection_state to CS_RECOVERY\n");
383 t->connection_state = CS_RECOVERY;
384 update_transports();
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700385 } else if (type == "sideload") {
Doug Zongker447f0612012-01-09 14:54:53 -0800386 D("setting connection_state to CS_SIDELOAD\n");
387 t->connection_state = CS_SIDELOAD;
388 update_transports();
Elliott Hughes3ce95752015-04-29 22:37:25 -0700389 } else {
390 D("setting connection_state to CS_HOST\n");
391 t->connection_state = CS_HOST;
Doug Zongker447f0612012-01-09 14:54:53 -0800392 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800393}
394
395void handle_packet(apacket *p, atransport *t)
396{
397 asocket *s;
398
Viral Mehta899913f2010-06-16 18:41:28 +0530399 D("handle_packet() %c%c%c%c\n", ((char*) (&(p->msg.command)))[0],
400 ((char*) (&(p->msg.command)))[1],
401 ((char*) (&(p->msg.command)))[2],
402 ((char*) (&(p->msg.command)))[3]);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800403 print_packet("recv", p);
404
405 switch(p->msg.command){
406 case A_SYNC:
407 if(p->msg.arg0){
408 send_packet(p, t);
409 if(HOST) send_connect(t);
410 } else {
411 t->connection_state = CS_OFFLINE;
412 handle_offline(t);
413 send_packet(p, t);
414 }
415 return;
416
417 case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
418 /* XXX verify version, etc */
419 if(t->connection_state != CS_OFFLINE) {
420 t->connection_state = CS_OFFLINE;
421 handle_offline(t);
422 }
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700423
Elliott Hughes8d5fa6d2015-04-24 23:02:00 -0700424 parse_banner(reinterpret_cast<const char*>(p->data), t);
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700425
426 if (HOST || !auth_enabled) {
427 handle_online(t);
428 if(!HOST) send_connect(t);
429 } else {
430 send_auth_request(t);
431 }
432 break;
433
434 case A_AUTH:
435 if (p->msg.arg0 == ADB_AUTH_TOKEN) {
Benoit Goby77e8e582013-01-15 12:36:47 -0800436 t->connection_state = CS_UNAUTHORIZED;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700437 t->key = adb_auth_nextkey(t->key);
438 if (t->key) {
439 send_auth_response(p->data, p->msg.data_length, t);
440 } else {
441 /* No more private keys to try, send the public key */
442 send_auth_publickey(t);
443 }
444 } else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) {
445 if (adb_auth_verify(t->token, p->data, p->msg.data_length)) {
446 adb_auth_verified(t);
447 t->failed_auth_attempts = 0;
448 } else {
449 if (t->failed_auth_attempts++ > 10)
450 adb_sleep_ms(1000);
451 send_auth_request(t);
452 }
453 } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) {
454 adb_auth_confirm_key(p->data, p->msg.data_length, t);
455 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800456 break;
457
458 case A_OPEN: /* OPEN(local-id, 0, "destination") */
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100459 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800460 char *name = (char*) p->data;
461 name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
462 s = create_local_service_socket(name);
463 if(s == 0) {
464 send_close(0, p->msg.arg0, t);
465 } else {
466 s->peer = create_remote_socket(p->msg.arg0, t);
467 s->peer->peer = s;
468 send_ready(s->id, s->peer->id, t);
469 s->ready(s);
470 }
471 }
472 break;
473
474 case A_OKAY: /* READY(local-id, remote-id, "") */
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100475 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
476 if((s = find_local_socket(p->msg.arg1, 0))) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800477 if(s->peer == 0) {
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100478 /* On first READY message, create the connection. */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800479 s->peer = create_remote_socket(p->msg.arg0, t);
480 s->peer->peer = s;
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100481 s->ready(s);
482 } else if (s->peer->id == p->msg.arg0) {
483 /* Other READY messages must use the same local-id */
484 s->ready(s);
485 } else {
486 D("Invalid A_OKAY(%d,%d), expected A_OKAY(%d,%d) on transport %s\n",
487 p->msg.arg0, p->msg.arg1, s->peer->id, p->msg.arg1, t->serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800488 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800489 }
490 }
491 break;
492
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100493 case A_CLSE: /* CLOSE(local-id, remote-id, "") or CLOSE(0, remote-id, "") */
494 if (t->online && p->msg.arg1 != 0) {
495 if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
496 /* According to protocol.txt, p->msg.arg0 might be 0 to indicate
497 * a failed OPEN only. However, due to a bug in previous ADB
498 * versions, CLOSE(0, remote-id, "") was also used for normal
499 * CLOSE() operations.
500 *
501 * This is bad because it means a compromised adbd could
502 * send packets to close connections between the host and
503 * other devices. To avoid this, only allow this if the local
504 * socket has a peer on the same transport.
505 */
506 if (p->msg.arg0 == 0 && s->peer && s->peer->transport != t) {
507 D("Invalid A_CLSE(0, %u) from transport %s, expected transport %s\n",
508 p->msg.arg1, t->serial, s->peer->transport->serial);
509 } else {
510 s->close(s);
511 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800512 }
513 }
514 break;
515
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100516 case A_WRTE: /* WRITE(local-id, remote-id, <data>) */
517 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
518 if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800519 unsigned rid = p->msg.arg0;
520 p->len = p->msg.data_length;
521
522 if(s->enqueue(s, p) == 0) {
523 D("Enqueue the socket\n");
524 send_ready(s->id, rid, t);
525 }
526 return;
527 }
528 }
529 break;
530
531 default:
532 printf("handle_packet: what is %08x?!\n", p->msg.command);
533 }
534
535 put_apacket(p);
536}
537
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800538#if ADB_HOST
JP Abgrall571c1362012-12-06 18:18:12 -0800539
Stefan Hilzingera84a42e2010-04-19 12:21:12 +0100540int launch_server(int server_port)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800541{
Yabin Cuie77b6a02014-11-11 09:24:11 -0800542#if defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800543 /* we need to start the server in the background */
544 /* we create a PIPE that will be used to wait for the server's "OK" */
545 /* message since the pipe handles must be inheritable, we use a */
546 /* security attribute */
547 HANDLE pipe_read, pipe_write;
Ray Donnelly267aa8b2012-11-29 01:18:50 +0000548 HANDLE stdout_handle, stderr_handle;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800549 SECURITY_ATTRIBUTES sa;
550 STARTUPINFO startup;
551 PROCESS_INFORMATION pinfo;
552 char program_path[ MAX_PATH ];
553 int ret;
554
555 sa.nLength = sizeof(sa);
556 sa.lpSecurityDescriptor = NULL;
557 sa.bInheritHandle = TRUE;
558
559 /* create pipe, and ensure its read handle isn't inheritable */
560 ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
561 if (!ret) {
562 fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );
563 return -1;
564 }
565
566 SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );
567
Ray Donnelly267aa8b2012-11-29 01:18:50 +0000568 /* Some programs want to launch an adb command and collect its output by
569 * calling CreateProcess with inheritable stdout/stderr handles, then
570 * using read() to get its output. When this happens, the stdout/stderr
571 * handles passed to the adb client process will also be inheritable.
572 * When starting the adb server here, care must be taken to reset them
573 * to non-inheritable.
574 * Otherwise, something bad happens: even if the adb command completes,
575 * the calling process is stuck while read()-ing from the stdout/stderr
576 * descriptors, because they're connected to corresponding handles in the
577 * adb server process (even if the latter never uses/writes to them).
578 */
579 stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE );
580 stderr_handle = GetStdHandle( STD_ERROR_HANDLE );
581 if (stdout_handle != INVALID_HANDLE_VALUE) {
582 SetHandleInformation( stdout_handle, HANDLE_FLAG_INHERIT, 0 );
583 }
584 if (stderr_handle != INVALID_HANDLE_VALUE) {
585 SetHandleInformation( stderr_handle, HANDLE_FLAG_INHERIT, 0 );
586 }
587
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800588 ZeroMemory( &startup, sizeof(startup) );
589 startup.cb = sizeof(startup);
590 startup.hStdInput = GetStdHandle( STD_INPUT_HANDLE );
591 startup.hStdOutput = pipe_write;
592 startup.hStdError = GetStdHandle( STD_ERROR_HANDLE );
593 startup.dwFlags = STARTF_USESTDHANDLES;
594
595 ZeroMemory( &pinfo, sizeof(pinfo) );
596
597 /* get path of current program */
598 GetModuleFileName( NULL, program_path, sizeof(program_path) );
Wenhao Lia09558c2013-11-13 16:23:37 +0800599 char args[64];
600 snprintf(args, sizeof(args), "adb -P %d fork-server server", server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800601 ret = CreateProcess(
602 program_path, /* program path */
Wenhao Lia09558c2013-11-13 16:23:37 +0800603 args,
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800604 /* the fork-server argument will set the
605 debug = 2 in the child */
606 NULL, /* process handle is not inheritable */
607 NULL, /* thread handle is not inheritable */
608 TRUE, /* yes, inherit some handles */
609 DETACHED_PROCESS, /* the new process doesn't have a console */
610 NULL, /* use parent's environment block */
611 NULL, /* use parent's starting directory */
612 &startup, /* startup info, i.e. std handles */
613 &pinfo );
614
615 CloseHandle( pipe_write );
616
617 if (!ret) {
618 fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );
619 CloseHandle( pipe_read );
620 return -1;
621 }
622
623 CloseHandle( pinfo.hProcess );
624 CloseHandle( pinfo.hThread );
625
626 /* wait for the "OK\n" message */
627 {
628 char temp[3];
629 DWORD count;
630
631 ret = ReadFile( pipe_read, temp, 3, &count, NULL );
632 CloseHandle( pipe_read );
633 if ( !ret ) {
634 fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() );
635 return -1;
636 }
637 if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
638 fprintf(stderr, "ADB server didn't ACK\n" );
639 return -1;
640 }
641 }
Yabin Cuie77b6a02014-11-11 09:24:11 -0800642#else /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800643 char path[PATH_MAX];
644 int fd[2];
645
646 // set up a pipe so the child can tell us when it is ready.
647 // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child.
648 if (pipe(fd)) {
649 fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
650 return -1;
651 }
Alexey Tarasov31664102009-10-22 02:55:00 +1100652 get_my_path(path, PATH_MAX);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800653 pid_t pid = fork();
654 if(pid < 0) return -1;
655
656 if (pid == 0) {
657 // child side of the fork
658
659 // redirect stderr to the pipe
660 // we use stderr instead of stdout due to stdout's buffering behavior.
661 adb_close(fd[0]);
662 dup2(fd[1], STDERR_FILENO);
663 adb_close(fd[1]);
664
Matt Gumbeld7b33082012-11-14 10:16:17 -0800665 char str_port[30];
666 snprintf(str_port, sizeof(str_port), "%d", server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800667 // child process
Matt Gumbeld7b33082012-11-14 10:16:17 -0800668 int result = execl(path, "adb", "-P", str_port, "fork-server", "server", NULL);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800669 // this should not return
670 fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
671 } else {
672 // parent side of the fork
673
674 char temp[3];
675
676 temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
677 // wait for the "OK\n" message
678 adb_close(fd[1]);
679 int ret = adb_read(fd[0], temp, 3);
JP Abgrall408fa572011-03-16 15:57:42 -0700680 int saved_errno = errno;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800681 adb_close(fd[0]);
682 if (ret < 0) {
JP Abgrall408fa572011-03-16 15:57:42 -0700683 fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800684 return -1;
685 }
686 if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
687 fprintf(stderr, "ADB server didn't ACK\n" );
688 return -1;
689 }
690
691 setsid();
692 }
Yabin Cuie77b6a02014-11-11 09:24:11 -0800693#endif /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800694 return 0;
695}
Yabin Cuie77b6a02014-11-11 09:24:11 -0800696#endif /* ADB_HOST */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800697
David 'Digit' Turner25258692013-03-21 21:07:42 +0100698// Try to handle a network forwarding request.
699// This returns 1 on success, 0 on failure, and -1 to indicate this is not
700// a forwarding-related request.
701int handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd)
702{
703 if (!strcmp(service, "list-forward")) {
704 // Create the list of forward redirections.
Elliott Hughese67f1f82015-04-30 17:32:03 -0700705 std::string listeners = format_listeners();
David 'Digit' Turner25258692013-03-21 21:07:42 +0100706#if ADB_HOST
Elliott Hughese67f1f82015-04-30 17:32:03 -0700707 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100708#endif
Elliott Hughese67f1f82015-04-30 17:32:03 -0700709 SendProtocolString(reply_fd, listeners);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100710 return 1;
711 }
712
713 if (!strcmp(service, "killforward-all")) {
714 remove_all_listeners();
715#if ADB_HOST
716 /* On the host: 1st OKAY is connect, 2nd OKAY is status */
Elliott Hughese67f1f82015-04-30 17:32:03 -0700717 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100718#endif
Elliott Hughese67f1f82015-04-30 17:32:03 -0700719 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100720 return 1;
721 }
722
723 if (!strncmp(service, "forward:",8) ||
724 !strncmp(service, "killforward:",12)) {
Dan Albertbac34742015-02-25 17:51:28 -0800725 char *local, *remote;
David 'Digit' Turner25258692013-03-21 21:07:42 +0100726 atransport *transport;
727
728 int createForward = strncmp(service, "kill", 4);
729 int no_rebind = 0;
730
731 local = strchr(service, ':') + 1;
732
733 // Handle forward:norebind:<local>... here
734 if (createForward && !strncmp(local, "norebind:", 9)) {
735 no_rebind = 1;
736 local = strchr(local, ':') + 1;
737 }
738
739 remote = strchr(local,';');
740
741 if (createForward) {
742 // Check forward: parameter format: '<local>;<remote>'
743 if(remote == 0) {
Elliott Hughese67f1f82015-04-30 17:32:03 -0700744 SendFail(reply_fd, "malformed forward spec");
David 'Digit' Turner25258692013-03-21 21:07:42 +0100745 return 1;
746 }
747
748 *remote++ = 0;
749 if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) {
Elliott Hughese67f1f82015-04-30 17:32:03 -0700750 SendFail(reply_fd, "malformed forward spec");
David 'Digit' Turner25258692013-03-21 21:07:42 +0100751 return 1;
752 }
753 } else {
754 // Check killforward: parameter format: '<local>'
755 if (local[0] == 0) {
Elliott Hughese67f1f82015-04-30 17:32:03 -0700756 SendFail(reply_fd, "malformed forward spec");
David 'Digit' Turner25258692013-03-21 21:07:42 +0100757 return 1;
758 }
759 }
760
Elliott Hughes7be29c82015-04-16 22:54:44 -0700761 std::string error_msg;
762 transport = acquire_one_transport(CS_ANY, ttype, serial, &error_msg);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100763 if (!transport) {
Elliott Hughese67f1f82015-04-30 17:32:03 -0700764 SendFail(reply_fd, error_msg);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100765 return 1;
766 }
767
Elliott Hughes7b506092015-04-20 08:09:20 -0700768 install_status_t r;
David 'Digit' Turner25258692013-03-21 21:07:42 +0100769 if (createForward) {
770 r = install_listener(local, remote, transport, no_rebind);
771 } else {
772 r = remove_listener(local, transport);
773 }
Elliott Hughes7b506092015-04-20 08:09:20 -0700774 if (r == INSTALL_STATUS_OK) {
David 'Digit' Turner25258692013-03-21 21:07:42 +0100775#if ADB_HOST
776 /* On the host: 1st OKAY is connect, 2nd OKAY is status */
Elliott Hughese67f1f82015-04-30 17:32:03 -0700777 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100778#endif
Elliott Hughese67f1f82015-04-30 17:32:03 -0700779 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100780 return 1;
781 }
782
Elliott Hughes7b506092015-04-20 08:09:20 -0700783 std::string message;
784 switch (r) {
785 case INSTALL_STATUS_OK: message = " "; break;
786 case INSTALL_STATUS_INTERNAL_ERROR: message = "internal error"; break;
787 case INSTALL_STATUS_CANNOT_BIND:
788 message = android::base::StringPrintf("cannot bind to socket: %s", strerror(errno));
789 break;
790 case INSTALL_STATUS_CANNOT_REBIND:
791 message = android::base::StringPrintf("cannot rebind existing socket: %s", strerror(errno));
792 break;
793 case INSTALL_STATUS_LISTENER_NOT_FOUND: message = "listener not found"; break;
David 'Digit' Turner25258692013-03-21 21:07:42 +0100794 }
Elliott Hughese67f1f82015-04-30 17:32:03 -0700795 SendFail(reply_fd, message);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100796 return 1;
797 }
798 return 0;
799}
800
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800801int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
802{
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800803 if(!strcmp(service, "kill")) {
804 fprintf(stderr,"adb server killed by remote request\n");
805 fflush(stdout);
Elliott Hughese67f1f82015-04-30 17:32:03 -0700806 SendOkay(reply_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800807 usb_cleanup();
808 exit(0);
809 }
810
811#if ADB_HOST
Chih-Hung Hsiehf787b382014-09-05 15:38:15 -0700812 atransport *transport = NULL;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800813 // "transport:" is used for switching transport with a specified serial number
814 // "transport-usb:" is used for switching transport to the only USB transport
815 // "transport-local:" is used for switching transport to the only local transport
816 // "transport-any:" is used for switching transport to the only transport
817 if (!strncmp(service, "transport", strlen("transport"))) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800818 transport_type type = kTransportAny;
819
820 if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
821 type = kTransportUsb;
822 } else if (!strncmp(service, "transport-local", strlen("transport-local"))) {
823 type = kTransportLocal;
824 } else if (!strncmp(service, "transport-any", strlen("transport-any"))) {
825 type = kTransportAny;
826 } else if (!strncmp(service, "transport:", strlen("transport:"))) {
827 service += strlen("transport:");
Tom Marlin3175c8e2011-07-27 12:56:14 -0500828 serial = service;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800829 }
830
Elliott Hughes7be29c82015-04-16 22:54:44 -0700831 std::string error_msg = "unknown failure";
832 transport = acquire_one_transport(CS_ANY, type, serial, &error_msg);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800833
834 if (transport) {
835 s->transport = transport;
Elliott Hughese67f1f82015-04-30 17:32:03 -0700836 SendOkay(reply_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800837 } else {
Elliott Hughese67f1f82015-04-30 17:32:03 -0700838 SendFail(reply_fd, error_msg);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800839 }
840 return 1;
841 }
842
843 // return a list of all connected devices
Scott Andersone109d262012-04-20 11:21:14 -0700844 if (!strncmp(service, "devices", 7)) {
Elliott Hughese67f1f82015-04-30 17:32:03 -0700845 bool long_listing = (strcmp(service+7, "-l") == 0);
846 if (long_listing || service[7] == 0) {
847 D("Getting device list...\n");
848 std::string device_list = list_transports(long_listing);
849 D("Sending device list...\n");
850 SendOkay(reply_fd);
851 SendProtocolString(reply_fd, device_list);
Scott Andersone109d262012-04-20 11:21:14 -0700852 return 0;
853 }
Elliott Hughese67f1f82015-04-30 17:32:03 -0700854 return 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800855 }
856
Mike Lockwood74d7ff82009-10-11 23:04:18 -0400857 // remove TCP transport
858 if (!strncmp(service, "disconnect:", 11)) {
859 char buffer[4096];
860 memset(buffer, 0, sizeof(buffer));
861 char* serial = service + 11;
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -0400862 if (serial[0] == 0) {
863 // disconnect from all TCP devices
864 unregister_all_tcp_transports();
Mike Lockwood74d7ff82009-10-11 23:04:18 -0400865 } else {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -0400866 char hostbuf[100];
867 // assume port 5555 if no port is specified
868 if (!strchr(serial, ':')) {
869 snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial);
870 serial = hostbuf;
871 }
872 atransport *t = find_transport(serial);
873
874 if (t) {
875 unregister_transport(t);
876 } else {
877 snprintf(buffer, sizeof(buffer), "No such device %s", serial);
878 }
Mike Lockwood74d7ff82009-10-11 23:04:18 -0400879 }
880
Elliott Hughese67f1f82015-04-30 17:32:03 -0700881 SendOkay(reply_fd);
882 SendProtocolString(reply_fd, buffer);
Mike Lockwood2f38b692009-08-24 15:58:40 -0700883 return 0;
884 }
885
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800886 // returns our value for ADB_SERVER_VERSION
887 if (!strcmp(service, "version")) {
Elliott Hughese67f1f82015-04-30 17:32:03 -0700888 SendOkay(reply_fd);
889 SendProtocolString(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800890 return 0;
891 }
892
893 if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {
Dan Albertbac34742015-02-25 17:51:28 -0800894 const char *out = "unknown";
895 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
Elliott Hughes7be29c82015-04-16 22:54:44 -0700896 if (transport && transport->serial) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800897 out = transport->serial;
898 }
Elliott Hughese67f1f82015-04-30 17:32:03 -0700899 SendOkay(reply_fd);
900 SendProtocolString(reply_fd, out);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800901 return 0;
902 }
Scott Andersone109d262012-04-20 11:21:14 -0700903 if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
Dan Albertbac34742015-02-25 17:51:28 -0800904 const char *out = "unknown";
905 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
Elliott Hughes7be29c82015-04-16 22:54:44 -0700906 if (transport && transport->devpath) {
Scott Andersone109d262012-04-20 11:21:14 -0700907 out = transport->devpath;
908 }
Elliott Hughese67f1f82015-04-30 17:32:03 -0700909 SendOkay(reply_fd);
910 SendProtocolString(reply_fd, out);
Scott Andersone109d262012-04-20 11:21:14 -0700911 return 0;
912 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800913 // indicates a new emulator instance has started
914 if (!strncmp(service,"emulator:",9)) {
915 int port = atoi(service+9);
916 local_connect(port);
917 /* we don't even need to send a reply */
918 return 0;
919 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800920
921 if(!strncmp(service,"get-state",strlen("get-state"))) {
922 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
Elliott Hughese67f1f82015-04-30 17:32:03 -0700923 SendOkay(reply_fd);
924 SendProtocolString(reply_fd, transport->connection_state_name());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800925 return 0;
926 }
Simon Yedc22c3c2014-07-14 17:23:06 -0700927#endif // ADB_HOST
928
929 int ret = handle_forward_request(service, ttype, serial, reply_fd);
930 if (ret >= 0)
931 return ret - 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800932 return -1;
933}