blob: c09aee3575f3c495a1fcdd99ae231ae51c0cb7e5 [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 Hughesd81f75a2015-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
Elliott Hughese1a55002015-05-01 17:04:38 -070092 std::string path = android::base::StringPrintf("/data/adb/adb-%s-%d", timestamp, getpid());
93 int fd = unix_open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640);
Dan Albertea2175a2015-03-08 21:12:08 -070094 if (fd == -1) {
95 return;
96 }
97
98 // redirect stdout and stderr to the log file
99 dup2(fd, STDOUT_FILENO);
100 dup2(fd, STDERR_FILENO);
101 fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid());
102 adb_close(fd);
Dan Albertea2175a2015-03-08 21:12:08 -0700103}
104#endif
105
106int adb_trace_mask;
107
108std::string get_trace_setting_from_env() {
109 const char* setting = getenv("ADB_TRACE");
110 if (setting == nullptr) {
111 setting = "";
112 }
113
114 return std::string(setting);
115}
116
117#if !ADB_HOST
118std::string get_trace_setting_from_prop() {
119 char buf[PROPERTY_VALUE_MAX];
120 property_get("persist.adb.trace_mask", buf, "");
121 return std::string(buf);
122}
123#endif
124
125std::string get_trace_setting() {
126#if ADB_HOST
127 return get_trace_setting_from_env();
128#else
129 return get_trace_setting_from_prop();
130#endif
131}
132
133// Split the comma/space/colum/semi-column separated list of tags from the trace
134// setting and build the trace mask from it. note that '1' and 'all' are special
135// cases to enable all tracing.
136//
137// adb's trace setting comes from the ADB_TRACE environment variable, whereas
138// adbd's comes from the system property persist.adb.trace_mask.
139void adb_trace_init() {
140 const std::string trace_setting = get_trace_setting();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800141
142 static const struct {
143 const char* tag;
144 int flag;
145 } tags[] = {
146 { "1", 0 },
147 { "all", 0 },
148 { "adb", TRACE_ADB },
149 { "sockets", TRACE_SOCKETS },
150 { "packets", TRACE_PACKETS },
151 { "rwx", TRACE_RWX },
152 { "usb", TRACE_USB },
153 { "sync", TRACE_SYNC },
154 { "sysdeps", TRACE_SYSDEPS },
155 { "transport", TRACE_TRANSPORT },
156 { "jdwp", TRACE_JDWP },
JP Abgrall408fa572011-03-16 15:57:42 -0700157 { "services", TRACE_SERVICES },
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700158 { "auth", TRACE_AUTH },
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800159 { NULL, 0 }
160 };
161
Dan Albertea2175a2015-03-08 21:12:08 -0700162 if (trace_setting.empty()) {
163 return;
164 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800165
Dan Albertea2175a2015-03-08 21:12:08 -0700166 // Use a comma/colon/semi-colon/space separated list
167 const char* p = trace_setting.c_str();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800168 while (*p) {
169 int len, tagn;
170
Dan Albertea2175a2015-03-08 21:12:08 -0700171 const char* q = strpbrk(p, " ,:;");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800172 if (q == NULL) {
173 q = p + strlen(p);
174 }
175 len = q - p;
176
Dan Albertea2175a2015-03-08 21:12:08 -0700177 for (tagn = 0; tags[tagn].tag != NULL; tagn++) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800178 int taglen = strlen(tags[tagn].tag);
179
Dan Albertea2175a2015-03-08 21:12:08 -0700180 if (len == taglen && !memcmp(tags[tagn].tag, p, len)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800181 int flag = tags[tagn].flag;
182 if (flag == 0) {
183 adb_trace_mask = ~0;
184 return;
185 }
186 adb_trace_mask |= (1 << flag);
187 break;
188 }
189 }
190 p = q;
191 if (*p)
192 p++;
193 }
Dan Albertea2175a2015-03-08 21:12:08 -0700194
195#if !ADB_HOST
196 start_device_log();
197#endif
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800198}
199
Dan Albertbac34742015-02-25 17:51:28 -0800200apacket* get_apacket(void)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800201{
Dan Albertbac34742015-02-25 17:51:28 -0800202 apacket* p = reinterpret_cast<apacket*>(malloc(sizeof(apacket)));
203 if (p == nullptr) {
204 fatal("failed to allocate an apacket");
205 }
206
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800207 memset(p, 0, sizeof(apacket) - MAX_PAYLOAD);
208 return p;
209}
210
211void put_apacket(apacket *p)
212{
213 free(p);
214}
215
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700216void handle_online(atransport *t)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800217{
218 D("adb: online\n");
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700219 t->online = 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800220}
221
222void handle_offline(atransport *t)
223{
224 D("adb: offline\n");
225 //Close the associated usb
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700226 t->online = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800227 run_transport_disconnects(t);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800228}
229
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700230#if DEBUG_PACKETS
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800231#define DUMPMAX 32
232void print_packet(const char *label, apacket *p)
233{
234 char *tag;
235 char *x;
236 unsigned count;
237
238 switch(p->msg.command){
239 case A_SYNC: tag = "SYNC"; break;
240 case A_CNXN: tag = "CNXN" ; break;
241 case A_OPEN: tag = "OPEN"; break;
242 case A_OKAY: tag = "OKAY"; break;
243 case A_CLSE: tag = "CLSE"; break;
244 case A_WRTE: tag = "WRTE"; break;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700245 case A_AUTH: tag = "AUTH"; break;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800246 default: tag = "????"; break;
247 }
248
249 fprintf(stderr, "%s: %s %08x %08x %04x \"",
250 label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length);
251 count = p->msg.data_length;
252 x = (char*) p->data;
253 if(count > DUMPMAX) {
254 count = DUMPMAX;
255 tag = "\n";
256 } else {
257 tag = "\"\n";
258 }
259 while(count-- > 0){
260 if((*x >= ' ') && (*x < 127)) {
261 fputc(*x, stderr);
262 } else {
263 fputc('.', stderr);
264 }
265 x++;
266 }
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700267 fputs(tag, stderr);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800268}
269#endif
270
271static void send_ready(unsigned local, unsigned remote, atransport *t)
272{
273 D("Calling send_ready \n");
274 apacket *p = get_apacket();
275 p->msg.command = A_OKAY;
276 p->msg.arg0 = local;
277 p->msg.arg1 = remote;
278 send_packet(p, t);
279}
280
281static void send_close(unsigned local, unsigned remote, atransport *t)
282{
283 D("Calling send_close \n");
284 apacket *p = get_apacket();
285 p->msg.command = A_CLSE;
286 p->msg.arg0 = local;
287 p->msg.arg1 = remote;
288 send_packet(p, t);
289}
290
Scott Andersone82c2db2012-05-25 14:10:02 -0700291static size_t fill_connect_data(char *buf, size_t bufsize)
292{
293#if ADB_HOST
294 return snprintf(buf, bufsize, "host::") + 1;
295#else
296 static const char *cnxn_props[] = {
297 "ro.product.name",
298 "ro.product.model",
299 "ro.product.device",
300 };
301 static const int num_cnxn_props = ARRAY_SIZE(cnxn_props);
302 int i;
303 size_t remaining = bufsize;
304 size_t len;
305
306 len = snprintf(buf, remaining, "%s::", adb_device_banner);
307 remaining -= len;
308 buf += len;
309 for (i = 0; i < num_cnxn_props; i++) {
310 char value[PROPERTY_VALUE_MAX];
311 property_get(cnxn_props[i], value, "");
312 len = snprintf(buf, remaining, "%s=%s;", cnxn_props[i], value);
313 remaining -= len;
314 buf += len;
315 }
316
317 return bufsize - remaining + 1;
318#endif
319}
320
Dan Albertba3a2512015-02-18 17:47:33 -0800321void send_connect(atransport *t)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800322{
323 D("Calling send_connect \n");
324 apacket *cp = get_apacket();
325 cp->msg.command = A_CNXN;
326 cp->msg.arg0 = A_VERSION;
327 cp->msg.arg1 = MAX_PAYLOAD;
Scott Andersone82c2db2012-05-25 14:10:02 -0700328 cp->msg.data_length = fill_connect_data((char *)cp->data,
329 sizeof(cp->data));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800330 send_packet(cp, t);
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700331}
332
Elliott Hughesd81f75a2015-04-24 23:02:00 -0700333// qual_overwrite is used to overwrite a qualifier string. dst is a
334// pointer to a char pointer. It is assumed that if *dst is non-NULL, it
335// was malloc'ed and needs to freed. *dst will be set to a dup of src.
336// TODO: switch to std::string for these atransport fields instead.
337static void qual_overwrite(char** dst, const std::string& src) {
Scott Andersone82c2db2012-05-25 14:10:02 -0700338 free(*dst);
Elliott Hughesd81f75a2015-04-24 23:02:00 -0700339 *dst = strdup(src.c_str());
Scott Andersone82c2db2012-05-25 14:10:02 -0700340}
341
Elliott Hughesd81f75a2015-04-24 23:02:00 -0700342void parse_banner(const char* banner, atransport* t) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800343 D("parse_banner: %s\n", banner);
Elliott Hughesd81f75a2015-04-24 23:02:00 -0700344
345 // The format is something like:
346 // "device::ro.product.name=x;ro.product.model=y;ro.product.device=z;".
347 std::vector<std::string> pieces = android::base::Split(banner, ":");
348
349 if (pieces.size() > 2) {
350 const std::string& props = pieces[2];
351 for (auto& prop : android::base::Split(props, ";")) {
352 // The list of properties was traditionally ;-terminated rather than ;-separated.
353 if (prop.empty()) continue;
354
355 std::vector<std::string> key_value = android::base::Split(prop, "=");
356 if (key_value.size() != 2) continue;
357
358 const std::string& key = key_value[0];
359 const std::string& value = key_value[1];
360 if (key == "ro.product.name") {
361 qual_overwrite(&t->product, value);
362 } else if (key == "ro.product.model") {
363 qual_overwrite(&t->model, value);
364 } else if (key == "ro.product.device") {
365 qual_overwrite(&t->device, value);
Scott Andersone82c2db2012-05-25 14:10:02 -0700366 }
367 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800368 }
369
Elliott Hughesd81f75a2015-04-24 23:02:00 -0700370 const std::string& type = pieces[0];
371 if (type == "bootloader") {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800372 D("setting connection_state to CS_BOOTLOADER\n");
373 t->connection_state = CS_BOOTLOADER;
374 update_transports();
Elliott Hughesd81f75a2015-04-24 23:02:00 -0700375 } else if (type == "device") {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800376 D("setting connection_state to CS_DEVICE\n");
377 t->connection_state = CS_DEVICE;
378 update_transports();
Elliott Hughesd81f75a2015-04-24 23:02:00 -0700379 } else if (type == "recovery") {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800380 D("setting connection_state to CS_RECOVERY\n");
381 t->connection_state = CS_RECOVERY;
382 update_transports();
Elliott Hughesd81f75a2015-04-24 23:02:00 -0700383 } else if (type == "sideload") {
Doug Zongker447f0612012-01-09 14:54:53 -0800384 D("setting connection_state to CS_SIDELOAD\n");
385 t->connection_state = CS_SIDELOAD;
386 update_transports();
Elliott Hughes01565892015-04-29 22:37:25 -0700387 } else {
388 D("setting connection_state to CS_HOST\n");
389 t->connection_state = CS_HOST;
Doug Zongker447f0612012-01-09 14:54:53 -0800390 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800391}
392
393void handle_packet(apacket *p, atransport *t)
394{
395 asocket *s;
396
Viral Mehta899913f2010-06-16 18:41:28 +0530397 D("handle_packet() %c%c%c%c\n", ((char*) (&(p->msg.command)))[0],
398 ((char*) (&(p->msg.command)))[1],
399 ((char*) (&(p->msg.command)))[2],
400 ((char*) (&(p->msg.command)))[3]);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800401 print_packet("recv", p);
402
403 switch(p->msg.command){
404 case A_SYNC:
405 if(p->msg.arg0){
406 send_packet(p, t);
407 if(HOST) send_connect(t);
408 } else {
409 t->connection_state = CS_OFFLINE;
410 handle_offline(t);
411 send_packet(p, t);
412 }
413 return;
414
415 case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
416 /* XXX verify version, etc */
417 if(t->connection_state != CS_OFFLINE) {
418 t->connection_state = CS_OFFLINE;
419 handle_offline(t);
420 }
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700421
Elliott Hughesd81f75a2015-04-24 23:02:00 -0700422 parse_banner(reinterpret_cast<const char*>(p->data), t);
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700423
Elliott Hughes1cddc202015-06-17 15:23:42 -0700424 if (HOST || !auth_required) {
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700425 handle_online(t);
Elliott Hughes1cddc202015-06-17 15:23:42 -0700426 if (!HOST) send_connect(t);
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700427 } else {
428 send_auth_request(t);
429 }
430 break;
431
432 case A_AUTH:
433 if (p->msg.arg0 == ADB_AUTH_TOKEN) {
Benoit Goby77e8e582013-01-15 12:36:47 -0800434 t->connection_state = CS_UNAUTHORIZED;
Benoit Gobyd5fcafa2012-04-12 12:23:49 -0700435 t->key = adb_auth_nextkey(t->key);
436 if (t->key) {
437 send_auth_response(p->data, p->msg.data_length, t);
438 } else {
439 /* No more private keys to try, send the public key */
440 send_auth_publickey(t);
441 }
442 } else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) {
443 if (adb_auth_verify(t->token, p->data, p->msg.data_length)) {
444 adb_auth_verified(t);
445 t->failed_auth_attempts = 0;
446 } else {
447 if (t->failed_auth_attempts++ > 10)
448 adb_sleep_ms(1000);
449 send_auth_request(t);
450 }
451 } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) {
452 adb_auth_confirm_key(p->data, p->msg.data_length, t);
453 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800454 break;
455
456 case A_OPEN: /* OPEN(local-id, 0, "destination") */
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100457 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800458 char *name = (char*) p->data;
459 name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
460 s = create_local_service_socket(name);
461 if(s == 0) {
462 send_close(0, p->msg.arg0, t);
463 } else {
464 s->peer = create_remote_socket(p->msg.arg0, t);
465 s->peer->peer = s;
466 send_ready(s->id, s->peer->id, t);
467 s->ready(s);
468 }
469 }
470 break;
471
472 case A_OKAY: /* READY(local-id, remote-id, "") */
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100473 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
474 if((s = find_local_socket(p->msg.arg1, 0))) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800475 if(s->peer == 0) {
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100476 /* On first READY message, create the connection. */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800477 s->peer = create_remote_socket(p->msg.arg0, t);
478 s->peer->peer = s;
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100479 s->ready(s);
480 } else if (s->peer->id == p->msg.arg0) {
481 /* Other READY messages must use the same local-id */
482 s->ready(s);
483 } else {
484 D("Invalid A_OKAY(%d,%d), expected A_OKAY(%d,%d) on transport %s\n",
485 p->msg.arg0, p->msg.arg1, s->peer->id, p->msg.arg1, t->serial);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800486 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800487 }
488 }
489 break;
490
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100491 case A_CLSE: /* CLOSE(local-id, remote-id, "") or CLOSE(0, remote-id, "") */
492 if (t->online && p->msg.arg1 != 0) {
493 if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
494 /* According to protocol.txt, p->msg.arg0 might be 0 to indicate
495 * a failed OPEN only. However, due to a bug in previous ADB
496 * versions, CLOSE(0, remote-id, "") was also used for normal
497 * CLOSE() operations.
498 *
499 * This is bad because it means a compromised adbd could
500 * send packets to close connections between the host and
501 * other devices. To avoid this, only allow this if the local
502 * socket has a peer on the same transport.
503 */
504 if (p->msg.arg0 == 0 && s->peer && s->peer->transport != t) {
505 D("Invalid A_CLSE(0, %u) from transport %s, expected transport %s\n",
506 p->msg.arg1, t->serial, s->peer->transport->serial);
507 } else {
508 s->close(s);
509 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800510 }
511 }
512 break;
513
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100514 case A_WRTE: /* WRITE(local-id, remote-id, <data>) */
515 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
516 if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800517 unsigned rid = p->msg.arg0;
518 p->len = p->msg.data_length;
519
520 if(s->enqueue(s, p) == 0) {
521 D("Enqueue the socket\n");
522 send_ready(s->id, rid, t);
523 }
524 return;
525 }
526 }
527 break;
528
529 default:
530 printf("handle_packet: what is %08x?!\n", p->msg.command);
531 }
532
533 put_apacket(p);
534}
535
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800536#if ADB_HOST
JP Abgrall571c1362012-12-06 18:18:12 -0800537
Stefan Hilzingera84a42e2010-04-19 12:21:12 +0100538int launch_server(int server_port)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800539{
Yabin Cuie77b6a02014-11-11 09:24:11 -0800540#if defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800541 /* we need to start the server in the background */
542 /* we create a PIPE that will be used to wait for the server's "OK" */
543 /* message since the pipe handles must be inheritable, we use a */
544 /* security attribute */
545 HANDLE pipe_read, pipe_write;
Ray Donnelly267aa8b2012-11-29 01:18:50 +0000546 HANDLE stdout_handle, stderr_handle;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800547 SECURITY_ATTRIBUTES sa;
548 STARTUPINFO startup;
549 PROCESS_INFORMATION pinfo;
550 char program_path[ MAX_PATH ];
551 int ret;
552
553 sa.nLength = sizeof(sa);
554 sa.lpSecurityDescriptor = NULL;
555 sa.bInheritHandle = TRUE;
556
557 /* create pipe, and ensure its read handle isn't inheritable */
558 ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
559 if (!ret) {
560 fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );
561 return -1;
562 }
563
564 SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );
565
Ray Donnelly267aa8b2012-11-29 01:18:50 +0000566 /* Some programs want to launch an adb command and collect its output by
567 * calling CreateProcess with inheritable stdout/stderr handles, then
568 * using read() to get its output. When this happens, the stdout/stderr
569 * handles passed to the adb client process will also be inheritable.
570 * When starting the adb server here, care must be taken to reset them
571 * to non-inheritable.
572 * Otherwise, something bad happens: even if the adb command completes,
573 * the calling process is stuck while read()-ing from the stdout/stderr
574 * descriptors, because they're connected to corresponding handles in the
575 * adb server process (even if the latter never uses/writes to them).
576 */
577 stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE );
578 stderr_handle = GetStdHandle( STD_ERROR_HANDLE );
579 if (stdout_handle != INVALID_HANDLE_VALUE) {
580 SetHandleInformation( stdout_handle, HANDLE_FLAG_INHERIT, 0 );
581 }
582 if (stderr_handle != INVALID_HANDLE_VALUE) {
583 SetHandleInformation( stderr_handle, HANDLE_FLAG_INHERIT, 0 );
584 }
585
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800586 ZeroMemory( &startup, sizeof(startup) );
587 startup.cb = sizeof(startup);
588 startup.hStdInput = GetStdHandle( STD_INPUT_HANDLE );
589 startup.hStdOutput = pipe_write;
590 startup.hStdError = GetStdHandle( STD_ERROR_HANDLE );
591 startup.dwFlags = STARTF_USESTDHANDLES;
592
593 ZeroMemory( &pinfo, sizeof(pinfo) );
594
595 /* get path of current program */
596 GetModuleFileName( NULL, program_path, sizeof(program_path) );
Wenhao Lia09558c2013-11-13 16:23:37 +0800597 char args[64];
598 snprintf(args, sizeof(args), "adb -P %d fork-server server", server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800599 ret = CreateProcess(
600 program_path, /* program path */
Wenhao Lia09558c2013-11-13 16:23:37 +0800601 args,
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800602 /* the fork-server argument will set the
603 debug = 2 in the child */
604 NULL, /* process handle is not inheritable */
605 NULL, /* thread handle is not inheritable */
606 TRUE, /* yes, inherit some handles */
607 DETACHED_PROCESS, /* the new process doesn't have a console */
608 NULL, /* use parent's environment block */
609 NULL, /* use parent's starting directory */
610 &startup, /* startup info, i.e. std handles */
611 &pinfo );
612
613 CloseHandle( pipe_write );
614
615 if (!ret) {
616 fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );
617 CloseHandle( pipe_read );
618 return -1;
619 }
620
621 CloseHandle( pinfo.hProcess );
622 CloseHandle( pinfo.hThread );
623
624 /* wait for the "OK\n" message */
625 {
626 char temp[3];
627 DWORD count;
628
629 ret = ReadFile( pipe_read, temp, 3, &count, NULL );
630 CloseHandle( pipe_read );
631 if ( !ret ) {
632 fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() );
633 return -1;
634 }
635 if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
636 fprintf(stderr, "ADB server didn't ACK\n" );
637 return -1;
638 }
639 }
Yabin Cuie77b6a02014-11-11 09:24:11 -0800640#else /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800641 char path[PATH_MAX];
642 int fd[2];
643
644 // set up a pipe so the child can tell us when it is ready.
645 // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child.
646 if (pipe(fd)) {
647 fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
648 return -1;
649 }
Alexey Tarasov31664102009-10-22 02:55:00 +1100650 get_my_path(path, PATH_MAX);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800651 pid_t pid = fork();
652 if(pid < 0) return -1;
653
654 if (pid == 0) {
655 // child side of the fork
656
657 // redirect stderr to the pipe
658 // we use stderr instead of stdout due to stdout's buffering behavior.
659 adb_close(fd[0]);
660 dup2(fd[1], STDERR_FILENO);
661 adb_close(fd[1]);
662
Matt Gumbeld7b33082012-11-14 10:16:17 -0800663 char str_port[30];
664 snprintf(str_port, sizeof(str_port), "%d", server_port);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800665 // child process
Matt Gumbeld7b33082012-11-14 10:16:17 -0800666 int result = execl(path, "adb", "-P", str_port, "fork-server", "server", NULL);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800667 // this should not return
668 fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
669 } else {
670 // parent side of the fork
671
672 char temp[3];
673
674 temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
675 // wait for the "OK\n" message
676 adb_close(fd[1]);
677 int ret = adb_read(fd[0], temp, 3);
JP Abgrall408fa572011-03-16 15:57:42 -0700678 int saved_errno = errno;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800679 adb_close(fd[0]);
680 if (ret < 0) {
JP Abgrall408fa572011-03-16 15:57:42 -0700681 fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800682 return -1;
683 }
684 if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
685 fprintf(stderr, "ADB server didn't ACK\n" );
686 return -1;
687 }
688
689 setsid();
690 }
Yabin Cuie77b6a02014-11-11 09:24:11 -0800691#endif /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800692 return 0;
693}
Yabin Cuie77b6a02014-11-11 09:24:11 -0800694#endif /* ADB_HOST */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800695
David 'Digit' Turner25258692013-03-21 21:07:42 +0100696// Try to handle a network forwarding request.
697// This returns 1 on success, 0 on failure, and -1 to indicate this is not
698// a forwarding-related request.
699int handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd)
700{
701 if (!strcmp(service, "list-forward")) {
702 // Create the list of forward redirections.
Elliott Hughes92af7332015-04-30 17:32:03 -0700703 std::string listeners = format_listeners();
David 'Digit' Turner25258692013-03-21 21:07:42 +0100704#if ADB_HOST
Elliott Hughes92af7332015-04-30 17:32:03 -0700705 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100706#endif
Elliott Hughes92af7332015-04-30 17:32:03 -0700707 SendProtocolString(reply_fd, listeners);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100708 return 1;
709 }
710
711 if (!strcmp(service, "killforward-all")) {
712 remove_all_listeners();
713#if ADB_HOST
714 /* On the host: 1st OKAY is connect, 2nd OKAY is status */
Elliott Hughes92af7332015-04-30 17:32:03 -0700715 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100716#endif
Elliott Hughes92af7332015-04-30 17:32:03 -0700717 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100718 return 1;
719 }
720
721 if (!strncmp(service, "forward:",8) ||
722 !strncmp(service, "killforward:",12)) {
Dan Albertbac34742015-02-25 17:51:28 -0800723 char *local, *remote;
David 'Digit' Turner25258692013-03-21 21:07:42 +0100724 atransport *transport;
725
726 int createForward = strncmp(service, "kill", 4);
727 int no_rebind = 0;
728
729 local = strchr(service, ':') + 1;
730
731 // Handle forward:norebind:<local>... here
732 if (createForward && !strncmp(local, "norebind:", 9)) {
733 no_rebind = 1;
734 local = strchr(local, ':') + 1;
735 }
736
737 remote = strchr(local,';');
738
739 if (createForward) {
740 // Check forward: parameter format: '<local>;<remote>'
741 if(remote == 0) {
Elliott Hughes92af7332015-04-30 17:32:03 -0700742 SendFail(reply_fd, "malformed forward spec");
David 'Digit' Turner25258692013-03-21 21:07:42 +0100743 return 1;
744 }
745
746 *remote++ = 0;
747 if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) {
Elliott Hughes92af7332015-04-30 17:32:03 -0700748 SendFail(reply_fd, "malformed forward spec");
David 'Digit' Turner25258692013-03-21 21:07:42 +0100749 return 1;
750 }
751 } else {
752 // Check killforward: parameter format: '<local>'
753 if (local[0] == 0) {
Elliott Hughes92af7332015-04-30 17:32:03 -0700754 SendFail(reply_fd, "malformed forward spec");
David 'Digit' Turner25258692013-03-21 21:07:42 +0100755 return 1;
756 }
757 }
758
Elliott Hughes7be29c82015-04-16 22:54:44 -0700759 std::string error_msg;
760 transport = acquire_one_transport(CS_ANY, ttype, serial, &error_msg);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100761 if (!transport) {
Elliott Hughes92af7332015-04-30 17:32:03 -0700762 SendFail(reply_fd, error_msg);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100763 return 1;
764 }
765
Elliott Hughes7b506092015-04-20 08:09:20 -0700766 install_status_t r;
David 'Digit' Turner25258692013-03-21 21:07:42 +0100767 if (createForward) {
768 r = install_listener(local, remote, transport, no_rebind);
769 } else {
770 r = remove_listener(local, transport);
771 }
Elliott Hughes7b506092015-04-20 08:09:20 -0700772 if (r == INSTALL_STATUS_OK) {
David 'Digit' Turner25258692013-03-21 21:07:42 +0100773#if ADB_HOST
774 /* On the host: 1st OKAY is connect, 2nd OKAY is status */
Elliott Hughes92af7332015-04-30 17:32:03 -0700775 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100776#endif
Elliott Hughes92af7332015-04-30 17:32:03 -0700777 SendOkay(reply_fd);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100778 return 1;
779 }
780
Elliott Hughes7b506092015-04-20 08:09:20 -0700781 std::string message;
782 switch (r) {
783 case INSTALL_STATUS_OK: message = " "; break;
784 case INSTALL_STATUS_INTERNAL_ERROR: message = "internal error"; break;
785 case INSTALL_STATUS_CANNOT_BIND:
786 message = android::base::StringPrintf("cannot bind to socket: %s", strerror(errno));
787 break;
788 case INSTALL_STATUS_CANNOT_REBIND:
789 message = android::base::StringPrintf("cannot rebind existing socket: %s", strerror(errno));
790 break;
791 case INSTALL_STATUS_LISTENER_NOT_FOUND: message = "listener not found"; break;
David 'Digit' Turner25258692013-03-21 21:07:42 +0100792 }
Elliott Hughes92af7332015-04-30 17:32:03 -0700793 SendFail(reply_fd, message);
David 'Digit' Turner25258692013-03-21 21:07:42 +0100794 return 1;
795 }
796 return 0;
797}
798
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800799int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
800{
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800801 if(!strcmp(service, "kill")) {
802 fprintf(stderr,"adb server killed by remote request\n");
803 fflush(stdout);
Elliott Hughes92af7332015-04-30 17:32:03 -0700804 SendOkay(reply_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800805 usb_cleanup();
806 exit(0);
807 }
808
809#if ADB_HOST
Chih-Hung Hsiehf787b382014-09-05 15:38:15 -0700810 atransport *transport = NULL;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800811 // "transport:" is used for switching transport with a specified serial number
812 // "transport-usb:" is used for switching transport to the only USB transport
813 // "transport-local:" is used for switching transport to the only local transport
814 // "transport-any:" is used for switching transport to the only transport
815 if (!strncmp(service, "transport", strlen("transport"))) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800816 transport_type type = kTransportAny;
817
818 if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
819 type = kTransportUsb;
820 } else if (!strncmp(service, "transport-local", strlen("transport-local"))) {
821 type = kTransportLocal;
822 } else if (!strncmp(service, "transport-any", strlen("transport-any"))) {
823 type = kTransportAny;
824 } else if (!strncmp(service, "transport:", strlen("transport:"))) {
825 service += strlen("transport:");
Tom Marlin3175c8e2011-07-27 12:56:14 -0500826 serial = service;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800827 }
828
Elliott Hughes7be29c82015-04-16 22:54:44 -0700829 std::string error_msg = "unknown failure";
830 transport = acquire_one_transport(CS_ANY, type, serial, &error_msg);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800831
832 if (transport) {
833 s->transport = transport;
Elliott Hughes92af7332015-04-30 17:32:03 -0700834 SendOkay(reply_fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800835 } else {
Elliott Hughes92af7332015-04-30 17:32:03 -0700836 SendFail(reply_fd, error_msg);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800837 }
838 return 1;
839 }
840
841 // return a list of all connected devices
Scott Andersone109d262012-04-20 11:21:14 -0700842 if (!strncmp(service, "devices", 7)) {
Elliott Hughes92af7332015-04-30 17:32:03 -0700843 bool long_listing = (strcmp(service+7, "-l") == 0);
844 if (long_listing || service[7] == 0) {
845 D("Getting device list...\n");
846 std::string device_list = list_transports(long_listing);
847 D("Sending device list...\n");
848 SendOkay(reply_fd);
849 SendProtocolString(reply_fd, device_list);
Scott Andersone109d262012-04-20 11:21:14 -0700850 return 0;
851 }
Elliott Hughes92af7332015-04-30 17:32:03 -0700852 return 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800853 }
854
Mike Lockwood74d7ff82009-10-11 23:04:18 -0400855 // remove TCP transport
856 if (!strncmp(service, "disconnect:", 11)) {
857 char buffer[4096];
858 memset(buffer, 0, sizeof(buffer));
859 char* serial = service + 11;
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -0400860 if (serial[0] == 0) {
861 // disconnect from all TCP devices
862 unregister_all_tcp_transports();
Mike Lockwood74d7ff82009-10-11 23:04:18 -0400863 } else {
Mike Lockwoodcbbe79a2010-05-24 10:44:35 -0400864 char hostbuf[100];
865 // assume port 5555 if no port is specified
866 if (!strchr(serial, ':')) {
867 snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial);
868 serial = hostbuf;
869 }
870 atransport *t = find_transport(serial);
871
872 if (t) {
873 unregister_transport(t);
874 } else {
875 snprintf(buffer, sizeof(buffer), "No such device %s", serial);
876 }
Mike Lockwood74d7ff82009-10-11 23:04:18 -0400877 }
878
Elliott Hughes92af7332015-04-30 17:32:03 -0700879 SendOkay(reply_fd);
880 SendProtocolString(reply_fd, buffer);
Mike Lockwood2f38b692009-08-24 15:58:40 -0700881 return 0;
882 }
883
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800884 // returns our value for ADB_SERVER_VERSION
885 if (!strcmp(service, "version")) {
Elliott Hughes92af7332015-04-30 17:32:03 -0700886 SendOkay(reply_fd);
887 SendProtocolString(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800888 return 0;
889 }
890
891 if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {
Dan Albertbac34742015-02-25 17:51:28 -0800892 const char *out = "unknown";
893 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
Elliott Hughes7be29c82015-04-16 22:54:44 -0700894 if (transport && transport->serial) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800895 out = transport->serial;
896 }
Elliott Hughes92af7332015-04-30 17:32:03 -0700897 SendOkay(reply_fd);
898 SendProtocolString(reply_fd, out);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800899 return 0;
900 }
Scott Andersone109d262012-04-20 11:21:14 -0700901 if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
Dan Albertbac34742015-02-25 17:51:28 -0800902 const char *out = "unknown";
903 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
Elliott Hughes7be29c82015-04-16 22:54:44 -0700904 if (transport && transport->devpath) {
Scott Andersone109d262012-04-20 11:21:14 -0700905 out = transport->devpath;
906 }
Elliott Hughes92af7332015-04-30 17:32:03 -0700907 SendOkay(reply_fd);
908 SendProtocolString(reply_fd, out);
Scott Andersone109d262012-04-20 11:21:14 -0700909 return 0;
910 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800911 // indicates a new emulator instance has started
912 if (!strncmp(service,"emulator:",9)) {
913 int port = atoi(service+9);
914 local_connect(port);
915 /* we don't even need to send a reply */
916 return 0;
917 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800918
919 if(!strncmp(service,"get-state",strlen("get-state"))) {
920 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
Elliott Hughes92af7332015-04-30 17:32:03 -0700921 SendOkay(reply_fd);
Elliott Hughes5b65f862015-09-01 12:54:21 -0700922 SendProtocolString(reply_fd, transport ? transport->connection_state_name() : "unknown");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800923 return 0;
924 }
Simon Yedc22c3c2014-07-14 17:23:06 -0700925#endif // ADB_HOST
926
927 int ret = handle_forward_request(service, ttype, serial, reply_fd);
928 if (ret >= 0)
929 return ret - 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800930 return -1;
931}