transport.cpp revision 2e83684537326b027ef042d5712d2b861af8e626
1/* 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 17#define TRACE_TAG TRANSPORT 18 19#include "sysdeps.h" 20#include "transport.h" 21 22#include <ctype.h> 23#include <errno.h> 24#include <stdio.h> 25#include <stdlib.h> 26#include <string.h> 27#include <unistd.h> 28 29#include <algorithm> 30#include <list> 31 32#include <android-base/logging.h> 33#include <android-base/stringprintf.h> 34#include <android-base/strings.h> 35 36#include "adb.h" 37#include "adb_utils.h" 38#include "diagnose_usb.h" 39 40static void transport_unref(atransport *t); 41 42static auto& transport_list = *new std::list<atransport*>(); 43static auto& pending_list = *new std::list<atransport*>(); 44 45ADB_MUTEX_DEFINE( transport_lock ); 46 47const char* const kFeatureShell2 = "shell_v2"; 48const char* const kFeatureCmd = "cmd"; 49 50static std::string dump_packet(const char* name, const char* func, apacket* p) { 51 unsigned command = p->msg.command; 52 int len = p->msg.data_length; 53 char cmd[9]; 54 char arg0[12], arg1[12]; 55 int n; 56 57 for (n = 0; n < 4; n++) { 58 int b = (command >> (n*8)) & 255; 59 if (b < 32 || b >= 127) 60 break; 61 cmd[n] = (char)b; 62 } 63 if (n == 4) { 64 cmd[4] = 0; 65 } else { 66 /* There is some non-ASCII name in the command, so dump 67 * the hexadecimal value instead */ 68 snprintf(cmd, sizeof cmd, "%08x", command); 69 } 70 71 if (p->msg.arg0 < 256U) 72 snprintf(arg0, sizeof arg0, "%d", p->msg.arg0); 73 else 74 snprintf(arg0, sizeof arg0, "0x%x", p->msg.arg0); 75 76 if (p->msg.arg1 < 256U) 77 snprintf(arg1, sizeof arg1, "%d", p->msg.arg1); 78 else 79 snprintf(arg1, sizeof arg1, "0x%x", p->msg.arg1); 80 81 std::string result = android::base::StringPrintf("%s: %s: [%s] arg0=%s arg1=%s (len=%d) ", 82 name, func, cmd, arg0, arg1, len); 83 result += dump_hex(p->data, len); 84 return result; 85} 86 87static int 88read_packet(int fd, const char* name, apacket** ppacket) 89{ 90 char buff[8]; 91 if (!name) { 92 snprintf(buff, sizeof buff, "fd=%d", fd); 93 name = buff; 94 } 95 char* p = reinterpret_cast<char*>(ppacket); /* really read a packet address */ 96 int len = sizeof(apacket*); 97 while(len > 0) { 98 int r = adb_read(fd, p, len); 99 if(r > 0) { 100 len -= r; 101 p += r; 102 } else { 103 D("%s: read_packet (fd=%d), error ret=%d: %s", name, fd, r, strerror(errno)); 104 return -1; 105 } 106 } 107 108 VLOG(TRANSPORT) << dump_packet(name, "from remote", *ppacket); 109 return 0; 110} 111 112static int 113write_packet(int fd, const char* name, apacket** ppacket) 114{ 115 char buff[8]; 116 if (!name) { 117 snprintf(buff, sizeof buff, "fd=%d", fd); 118 name = buff; 119 } 120 VLOG(TRANSPORT) << dump_packet(name, "to remote", *ppacket); 121 char* p = reinterpret_cast<char*>(ppacket); /* we really write the packet address */ 122 int len = sizeof(apacket*); 123 while(len > 0) { 124 int r = adb_write(fd, p, len); 125 if(r > 0) { 126 len -= r; 127 p += r; 128 } else { 129 D("%s: write_packet (fd=%d) error ret=%d: %s", name, fd, r, strerror(errno)); 130 return -1; 131 } 132 } 133 return 0; 134} 135 136static void transport_socket_events(int fd, unsigned events, void *_t) 137{ 138 atransport *t = reinterpret_cast<atransport*>(_t); 139 D("transport_socket_events(fd=%d, events=%04x,...)", fd, events); 140 if(events & FDE_READ){ 141 apacket *p = 0; 142 if(read_packet(fd, t->serial, &p)){ 143 D("%s: failed to read packet from transport socket on fd %d", t->serial, fd); 144 } else { 145 handle_packet(p, (atransport *) _t); 146 } 147 } 148} 149 150void send_packet(apacket *p, atransport *t) 151{ 152 unsigned char *x; 153 unsigned sum; 154 unsigned count; 155 156 p->msg.magic = p->msg.command ^ 0xffffffff; 157 158 count = p->msg.data_length; 159 x = (unsigned char *) p->data; 160 sum = 0; 161 while(count-- > 0){ 162 sum += *x++; 163 } 164 p->msg.data_check = sum; 165 166 print_packet("send", p); 167 168 if (t == NULL) { 169 D("Transport is null"); 170 // Zap errno because print_packet() and other stuff have errno effect. 171 errno = 0; 172 fatal_errno("Transport is null"); 173 } 174 175 if(write_packet(t->transport_socket, t->serial, &p)){ 176 fatal_errno("cannot enqueue packet on transport socket"); 177 } 178} 179 180// The transport is opened by transport_register_func before 181// the read_transport and write_transport threads are started. 182// 183// The read_transport thread issues a SYNC(1, token) message to let 184// the write_transport thread know to start things up. In the event 185// of transport IO failure, the read_transport thread will post a 186// SYNC(0,0) message to ensure shutdown. 187// 188// The transport will not actually be closed until both threads exit, but the threads 189// will kick the transport on their way out to disconnect the underlying device. 190// 191// read_transport thread reads data from a transport (representing a usb/tcp connection), 192// and makes the main thread call handle_packet(). 193static void *read_transport_thread(void *_t) 194{ 195 atransport *t = reinterpret_cast<atransport*>(_t); 196 apacket *p; 197 198 adb_thread_setname(android::base::StringPrintf("<-%s", 199 (t->serial != nullptr ? t->serial : "transport"))); 200 D("%s: starting read_transport thread on fd %d, SYNC online (%d)", 201 t->serial, t->fd, t->sync_token + 1); 202 p = get_apacket(); 203 p->msg.command = A_SYNC; 204 p->msg.arg0 = 1; 205 p->msg.arg1 = ++(t->sync_token); 206 p->msg.magic = A_SYNC ^ 0xffffffff; 207 if(write_packet(t->fd, t->serial, &p)) { 208 put_apacket(p); 209 D("%s: failed to write SYNC packet", t->serial); 210 goto oops; 211 } 212 213 D("%s: data pump started", t->serial); 214 for(;;) { 215 p = get_apacket(); 216 217 if(t->read_from_remote(p, t) == 0){ 218 D("%s: received remote packet, sending to transport", 219 t->serial); 220 if(write_packet(t->fd, t->serial, &p)){ 221 put_apacket(p); 222 D("%s: failed to write apacket to transport", t->serial); 223 goto oops; 224 } 225 } else { 226 D("%s: remote read failed for transport", t->serial); 227 put_apacket(p); 228 break; 229 } 230 } 231 232 D("%s: SYNC offline for transport", t->serial); 233 p = get_apacket(); 234 p->msg.command = A_SYNC; 235 p->msg.arg0 = 0; 236 p->msg.arg1 = 0; 237 p->msg.magic = A_SYNC ^ 0xffffffff; 238 if(write_packet(t->fd, t->serial, &p)) { 239 put_apacket(p); 240 D("%s: failed to write SYNC apacket to transport", t->serial); 241 } 242 243oops: 244 D("%s: read_transport thread is exiting", t->serial); 245 kick_transport(t); 246 transport_unref(t); 247 return 0; 248} 249 250// write_transport thread gets packets sent by the main thread (through send_packet()), 251// and writes to a transport (representing a usb/tcp connection). 252static void *write_transport_thread(void *_t) 253{ 254 atransport *t = reinterpret_cast<atransport*>(_t); 255 apacket *p; 256 int active = 0; 257 258 adb_thread_setname(android::base::StringPrintf("->%s", 259 (t->serial != nullptr ? t->serial : "transport"))); 260 D("%s: starting write_transport thread, reading from fd %d", 261 t->serial, t->fd); 262 263 for(;;){ 264 if(read_packet(t->fd, t->serial, &p)) { 265 D("%s: failed to read apacket from transport on fd %d", 266 t->serial, t->fd ); 267 break; 268 } 269 if(p->msg.command == A_SYNC){ 270 if(p->msg.arg0 == 0) { 271 D("%s: transport SYNC offline", t->serial); 272 put_apacket(p); 273 break; 274 } else { 275 if(p->msg.arg1 == t->sync_token) { 276 D("%s: transport SYNC online", t->serial); 277 active = 1; 278 } else { 279 D("%s: transport ignoring SYNC %d != %d", 280 t->serial, p->msg.arg1, t->sync_token); 281 } 282 } 283 } else { 284 if(active) { 285 D("%s: transport got packet, sending to remote", t->serial); 286 t->write_to_remote(p, t); 287 } else { 288 D("%s: transport ignoring packet while offline", t->serial); 289 } 290 } 291 292 put_apacket(p); 293 } 294 295 D("%s: write_transport thread is exiting, fd %d", t->serial, t->fd); 296 kick_transport(t); 297 transport_unref(t); 298 return 0; 299} 300 301static void kick_transport_locked(atransport* t) { 302 CHECK(t != nullptr); 303 if (!t->kicked) { 304 t->kicked = true; 305 t->kick(t); 306 } 307} 308 309void kick_transport(atransport* t) { 310 adb_mutex_lock(&transport_lock); 311 kick_transport_locked(t); 312 adb_mutex_unlock(&transport_lock); 313} 314 315static int transport_registration_send = -1; 316static int transport_registration_recv = -1; 317static fdevent transport_registration_fde; 318 319 320#if ADB_HOST 321 322/* this adds support required by the 'track-devices' service. 323 * this is used to send the content of "list_transport" to any 324 * number of client connections that want it through a single 325 * live TCP connection 326 */ 327struct device_tracker { 328 asocket socket; 329 int update_needed; 330 device_tracker* next; 331}; 332 333/* linked list of all device trackers */ 334static device_tracker* device_tracker_list; 335 336static void 337device_tracker_remove( device_tracker* tracker ) 338{ 339 device_tracker** pnode = &device_tracker_list; 340 device_tracker* node = *pnode; 341 342 adb_mutex_lock( &transport_lock ); 343 while (node) { 344 if (node == tracker) { 345 *pnode = node->next; 346 break; 347 } 348 pnode = &node->next; 349 node = *pnode; 350 } 351 adb_mutex_unlock( &transport_lock ); 352} 353 354static void 355device_tracker_close( asocket* socket ) 356{ 357 device_tracker* tracker = (device_tracker*) socket; 358 asocket* peer = socket->peer; 359 360 D( "device tracker %p removed", tracker); 361 if (peer) { 362 peer->peer = NULL; 363 peer->close(peer); 364 } 365 device_tracker_remove(tracker); 366 free(tracker); 367} 368 369static int 370device_tracker_enqueue( asocket* socket, apacket* p ) 371{ 372 /* you can't read from a device tracker, close immediately */ 373 put_apacket(p); 374 device_tracker_close(socket); 375 return -1; 376} 377 378static int device_tracker_send(device_tracker* tracker, const std::string& string) { 379 apacket* p = get_apacket(); 380 asocket* peer = tracker->socket.peer; 381 382 snprintf(reinterpret_cast<char*>(p->data), 5, "%04x", static_cast<int>(string.size())); 383 memcpy(&p->data[4], string.data(), string.size()); 384 p->len = 4 + string.size(); 385 return peer->enqueue(peer, p); 386} 387 388static void device_tracker_ready(asocket* socket) { 389 device_tracker* tracker = reinterpret_cast<device_tracker*>(socket); 390 391 // We want to send the device list when the tracker connects 392 // for the first time, even if no update occurred. 393 if (tracker->update_needed > 0) { 394 tracker->update_needed = 0; 395 396 std::string transports = list_transports(false); 397 device_tracker_send(tracker, transports); 398 } 399} 400 401asocket* 402create_device_tracker(void) 403{ 404 device_tracker* tracker = reinterpret_cast<device_tracker*>(calloc(1, sizeof(*tracker))); 405 if (tracker == nullptr) fatal("cannot allocate device tracker"); 406 407 D( "device tracker %p created", tracker); 408 409 tracker->socket.enqueue = device_tracker_enqueue; 410 tracker->socket.ready = device_tracker_ready; 411 tracker->socket.close = device_tracker_close; 412 tracker->update_needed = 1; 413 414 tracker->next = device_tracker_list; 415 device_tracker_list = tracker; 416 417 return &tracker->socket; 418} 419 420 421// Call this function each time the transport list has changed. 422void update_transports() { 423 std::string transports = list_transports(false); 424 425 device_tracker* tracker = device_tracker_list; 426 while (tracker != nullptr) { 427 device_tracker* next = tracker->next; 428 // This may destroy the tracker if the connection is closed. 429 device_tracker_send(tracker, transports); 430 tracker = next; 431 } 432} 433 434#else 435 436void update_transports() { 437 // Nothing to do on the device side. 438} 439 440#endif // ADB_HOST 441 442struct tmsg 443{ 444 atransport *transport; 445 int action; 446}; 447 448static int 449transport_read_action(int fd, struct tmsg* m) 450{ 451 char *p = (char*)m; 452 int len = sizeof(*m); 453 int r; 454 455 while(len > 0) { 456 r = adb_read(fd, p, len); 457 if(r > 0) { 458 len -= r; 459 p += r; 460 } else { 461 D("transport_read_action: on fd %d: %s", fd, strerror(errno)); 462 return -1; 463 } 464 } 465 return 0; 466} 467 468static int 469transport_write_action(int fd, struct tmsg* m) 470{ 471 char *p = (char*)m; 472 int len = sizeof(*m); 473 int r; 474 475 while(len > 0) { 476 r = adb_write(fd, p, len); 477 if(r > 0) { 478 len -= r; 479 p += r; 480 } else { 481 D("transport_write_action: on fd %d: %s", fd, strerror(errno)); 482 return -1; 483 } 484 } 485 return 0; 486} 487 488static void transport_registration_func(int _fd, unsigned ev, void *data) 489{ 490 tmsg m; 491 int s[2]; 492 atransport *t; 493 494 if(!(ev & FDE_READ)) { 495 return; 496 } 497 498 if(transport_read_action(_fd, &m)) { 499 fatal_errno("cannot read transport registration socket"); 500 } 501 502 t = m.transport; 503 504 if (m.action == 0) { 505 D("transport: %s removing and free'ing %d", t->serial, t->transport_socket); 506 507 /* IMPORTANT: the remove closes one half of the 508 ** socket pair. The close closes the other half. 509 */ 510 fdevent_remove(&(t->transport_fde)); 511 adb_close(t->fd); 512 513 adb_mutex_lock(&transport_lock); 514 transport_list.remove(t); 515 adb_mutex_unlock(&transport_lock); 516 517 if (t->product) 518 free(t->product); 519 if (t->serial) 520 free(t->serial); 521 if (t->model) 522 free(t->model); 523 if (t->device) 524 free(t->device); 525 if (t->devpath) 526 free(t->devpath); 527 528 delete t; 529 530 update_transports(); 531 return; 532 } 533 534 /* don't create transport threads for inaccessible devices */ 535 if (t->connection_state != kCsNoPerm) { 536 /* initial references are the two threads */ 537 t->ref_count = 2; 538 539 if (adb_socketpair(s)) { 540 fatal_errno("cannot open transport socketpair"); 541 } 542 543 D("transport: %s socketpair: (%d,%d) starting", t->serial, s[0], s[1]); 544 545 t->transport_socket = s[0]; 546 t->fd = s[1]; 547 548 fdevent_install(&(t->transport_fde), 549 t->transport_socket, 550 transport_socket_events, 551 t); 552 553 fdevent_set(&(t->transport_fde), FDE_READ); 554 555 if (!adb_thread_create(write_transport_thread, t)) { 556 fatal_errno("cannot create write_transport thread"); 557 } 558 559 if (!adb_thread_create(read_transport_thread, t)) { 560 fatal_errno("cannot create read_transport thread"); 561 } 562 } 563 564 adb_mutex_lock(&transport_lock); 565 pending_list.remove(t); 566 transport_list.push_front(t); 567 adb_mutex_unlock(&transport_lock); 568 569 update_transports(); 570} 571 572void init_transport_registration(void) 573{ 574 int s[2]; 575 576 if(adb_socketpair(s)){ 577 fatal_errno("cannot open transport registration socketpair"); 578 } 579 D("socketpair: (%d,%d)", s[0], s[1]); 580 581 transport_registration_send = s[0]; 582 transport_registration_recv = s[1]; 583 584 fdevent_install(&transport_registration_fde, 585 transport_registration_recv, 586 transport_registration_func, 587 0); 588 589 fdevent_set(&transport_registration_fde, FDE_READ); 590} 591 592/* the fdevent select pump is single threaded */ 593static void register_transport(atransport *transport) 594{ 595 tmsg m; 596 m.transport = transport; 597 m.action = 1; 598 D("transport: %s registered", transport->serial); 599 if(transport_write_action(transport_registration_send, &m)) { 600 fatal_errno("cannot write transport registration socket\n"); 601 } 602} 603 604static void remove_transport(atransport *transport) 605{ 606 tmsg m; 607 m.transport = transport; 608 m.action = 0; 609 D("transport: %s removed", transport->serial); 610 if(transport_write_action(transport_registration_send, &m)) { 611 fatal_errno("cannot write transport registration socket\n"); 612 } 613} 614 615 616static void transport_unref(atransport* t) { 617 CHECK(t != nullptr); 618 adb_mutex_lock(&transport_lock); 619 CHECK_GT(t->ref_count, 0u); 620 t->ref_count--; 621 if (t->ref_count == 0) { 622 D("transport: %s unref (kicking and closing)", t->serial); 623 kick_transport_locked(t); 624 t->close(t); 625 remove_transport(t); 626 } else { 627 D("transport: %s unref (count=%zu)", t->serial, t->ref_count); 628 } 629 adb_mutex_unlock(&transport_lock); 630} 631 632static int qual_match(const char *to_test, 633 const char *prefix, const char *qual, bool sanitize_qual) 634{ 635 if (!to_test || !*to_test) 636 /* Return true if both the qual and to_test are null strings. */ 637 return !qual || !*qual; 638 639 if (!qual) 640 return 0; 641 642 if (prefix) { 643 while (*prefix) { 644 if (*prefix++ != *to_test++) 645 return 0; 646 } 647 } 648 649 while (*qual) { 650 char ch = *qual++; 651 if (sanitize_qual && !isalnum(ch)) 652 ch = '_'; 653 if (ch != *to_test++) 654 return 0; 655 } 656 657 /* Everything matched so far. Return true if *to_test is a NUL. */ 658 return !*to_test; 659} 660 661atransport* acquire_one_transport(TransportType type, const char* serial, 662 bool* is_ambiguous, std::string* error_out) { 663 atransport* result = nullptr; 664 665 if (serial) { 666 *error_out = android::base::StringPrintf("device '%s' not found", serial); 667 } else if (type == kTransportLocal) { 668 *error_out = "no emulators found"; 669 } else if (type == kTransportAny) { 670 *error_out = "no devices/emulators found"; 671 } else { 672 *error_out = "no devices found"; 673 } 674 675 adb_mutex_lock(&transport_lock); 676 for (const auto& t : transport_list) { 677 if (t->connection_state == kCsNoPerm) { 678#if ADB_HOST 679 *error_out = UsbNoPermissionsLongHelpText(); 680#endif 681 continue; 682 } 683 684 // Check for matching serial number. 685 if (serial) { 686 if ((t->serial && !strcmp(serial, t->serial)) || 687 (t->devpath && !strcmp(serial, t->devpath)) || 688 qual_match(serial, "product:", t->product, false) || 689 qual_match(serial, "model:", t->model, true) || 690 qual_match(serial, "device:", t->device, false)) { 691 if (result) { 692 *error_out = "more than one device"; 693 if (is_ambiguous) *is_ambiguous = true; 694 result = nullptr; 695 break; 696 } 697 result = t; 698 } 699 } else { 700 if (type == kTransportUsb && t->type == kTransportUsb) { 701 if (result) { 702 *error_out = "more than one device"; 703 if (is_ambiguous) *is_ambiguous = true; 704 result = nullptr; 705 break; 706 } 707 result = t; 708 } else if (type == kTransportLocal && t->type == kTransportLocal) { 709 if (result) { 710 *error_out = "more than one emulator"; 711 if (is_ambiguous) *is_ambiguous = true; 712 result = nullptr; 713 break; 714 } 715 result = t; 716 } else if (type == kTransportAny) { 717 if (result) { 718 *error_out = "more than one device/emulator"; 719 if (is_ambiguous) *is_ambiguous = true; 720 result = nullptr; 721 break; 722 } 723 result = t; 724 } 725 } 726 } 727 adb_mutex_unlock(&transport_lock); 728 729 // Don't return unauthorized devices; the caller can't do anything with them. 730 if (result && result->connection_state == kCsUnauthorized) { 731 *error_out = "device unauthorized.\n"; 732 char* ADB_VENDOR_KEYS = getenv("ADB_VENDOR_KEYS"); 733 *error_out += "This adb server's $ADB_VENDOR_KEYS is "; 734 *error_out += ADB_VENDOR_KEYS ? ADB_VENDOR_KEYS : "not set"; 735 *error_out += "\n"; 736 *error_out += "Try 'adb kill-server' if that seems wrong.\n"; 737 *error_out += "Otherwise check for a confirmation dialog on your device."; 738 result = nullptr; 739 } 740 741 // Don't return offline devices; the caller can't do anything with them. 742 if (result && result->connection_state == kCsOffline) { 743 *error_out = "device offline"; 744 result = nullptr; 745 } 746 747 if (result) { 748 *error_out = "success"; 749 } 750 751 return result; 752} 753 754const std::string atransport::connection_state_name() const { 755 switch (connection_state) { 756 case kCsOffline: return "offline"; 757 case kCsBootloader: return "bootloader"; 758 case kCsDevice: return "device"; 759 case kCsHost: return "host"; 760 case kCsRecovery: return "recovery"; 761 case kCsNoPerm: return UsbNoPermissionsShortHelpText(); 762 case kCsSideload: return "sideload"; 763 case kCsUnauthorized: return "unauthorized"; 764 default: return "unknown"; 765 } 766} 767 768void atransport::update_version(int version, size_t payload) { 769 protocol_version = std::min(version, A_VERSION); 770 max_payload = std::min(payload, MAX_PAYLOAD); 771} 772 773int atransport::get_protocol_version() const { 774 return protocol_version; 775} 776 777size_t atransport::get_max_payload() const { 778 return max_payload; 779} 780 781namespace { 782 783constexpr char kFeatureStringDelimiter = ','; 784 785} // namespace 786 787const FeatureSet& supported_features() { 788 // Local static allocation to avoid global non-POD variables. 789 static const FeatureSet* features = new FeatureSet{ 790 kFeatureShell2, 791 kFeatureCmd 792 // Increment ADB_SERVER_VERSION whenever the feature list changes to 793 // make sure that the adb client and server features stay in sync 794 // (http://b/24370690). 795 }; 796 797 return *features; 798} 799 800std::string FeatureSetToString(const FeatureSet& features) { 801 return android::base::Join(features, kFeatureStringDelimiter); 802} 803 804FeatureSet StringToFeatureSet(const std::string& features_string) { 805 if (features_string.empty()) { 806 return FeatureSet(); 807 } 808 809 auto names = android::base::Split(features_string, 810 {kFeatureStringDelimiter}); 811 return FeatureSet(names.begin(), names.end()); 812} 813 814bool CanUseFeature(const FeatureSet& feature_set, const std::string& feature) { 815 return feature_set.count(feature) > 0 && 816 supported_features().count(feature) > 0; 817} 818 819bool atransport::has_feature(const std::string& feature) const { 820 return features_.count(feature) > 0; 821} 822 823void atransport::SetFeatures(const std::string& features_string) { 824 features_ = StringToFeatureSet(features_string); 825} 826 827void atransport::AddDisconnect(adisconnect* disconnect) { 828 disconnects_.push_back(disconnect); 829} 830 831void atransport::RemoveDisconnect(adisconnect* disconnect) { 832 disconnects_.remove(disconnect); 833} 834 835void atransport::RunDisconnects() { 836 for (const auto& disconnect : disconnects_) { 837 disconnect->func(disconnect->opaque, this); 838 } 839 disconnects_.clear(); 840} 841 842#if ADB_HOST 843 844static void append_transport_info(std::string* result, const char* key, 845 const char* value, bool sanitize) { 846 if (value == nullptr || *value == '\0') { 847 return; 848 } 849 850 *result += ' '; 851 *result += key; 852 853 for (const char* p = value; *p; ++p) { 854 result->push_back((!sanitize || isalnum(*p)) ? *p : '_'); 855 } 856} 857 858static void append_transport(const atransport* t, std::string* result, 859 bool long_listing) { 860 const char* serial = t->serial; 861 if (!serial || !serial[0]) { 862 serial = "(no serial number)"; 863 } 864 865 if (!long_listing) { 866 *result += serial; 867 *result += '\t'; 868 *result += t->connection_state_name(); 869 } else { 870 android::base::StringAppendF(result, "%-22s %s", serial, 871 t->connection_state_name().c_str()); 872 873 append_transport_info(result, "", t->devpath, false); 874 append_transport_info(result, "product:", t->product, false); 875 append_transport_info(result, "model:", t->model, true); 876 append_transport_info(result, "device:", t->device, false); 877 } 878 *result += '\n'; 879} 880 881std::string list_transports(bool long_listing) { 882 std::string result; 883 adb_mutex_lock(&transport_lock); 884 for (const auto& t : transport_list) { 885 append_transport(t, &result, long_listing); 886 } 887 adb_mutex_unlock(&transport_lock); 888 return result; 889} 890 891/* hack for osx */ 892void close_usb_devices() { 893 adb_mutex_lock(&transport_lock); 894 for (const auto& t : transport_list) { 895 if (!t->kicked) { 896 t->kicked = 1; 897 t->kick(t); 898 } 899 } 900 adb_mutex_unlock(&transport_lock); 901} 902#endif // ADB_HOST 903 904int register_socket_transport(int s, const char *serial, int port, int local) { 905 atransport* t = new atransport(); 906 907 if (!serial) { 908 char buf[32]; 909 snprintf(buf, sizeof(buf), "T-%p", t); 910 serial = buf; 911 } 912 913 D("transport: %s init'ing for socket %d, on port %d", serial, s, port); 914 if (init_socket_transport(t, s, port, local) < 0) { 915 delete t; 916 return -1; 917 } 918 919 adb_mutex_lock(&transport_lock); 920 for (const auto& transport : pending_list) { 921 if (transport->serial && strcmp(serial, transport->serial) == 0) { 922 adb_mutex_unlock(&transport_lock); 923 delete t; 924 return -1; 925 } 926 } 927 928 for (const auto& transport : transport_list) { 929 if (transport->serial && strcmp(serial, transport->serial) == 0) { 930 adb_mutex_unlock(&transport_lock); 931 delete t; 932 return -1; 933 } 934 } 935 936 pending_list.push_front(t); 937 t->serial = strdup(serial); 938 adb_mutex_unlock(&transport_lock); 939 940 register_transport(t); 941 return 0; 942} 943 944#if ADB_HOST 945atransport *find_transport(const char *serial) { 946 atransport* result = nullptr; 947 948 adb_mutex_lock(&transport_lock); 949 for (auto& t : transport_list) { 950 if (t->serial && strcmp(serial, t->serial) == 0) { 951 result = t; 952 break; 953 } 954 } 955 adb_mutex_unlock(&transport_lock); 956 957 return result; 958} 959 960void kick_all_tcp_devices() { 961 adb_mutex_lock(&transport_lock); 962 for (auto& t : transport_list) { 963 // TCP/IP devices have adb_port == 0. 964 if (t->type == kTransportLocal && t->adb_port == 0) { 965 // Kicking breaks the read_transport thread of this transport out of any read, then 966 // the read_transport thread will notify the main thread to make this transport 967 // offline. Then the main thread will notify the write_transport thread to exit. 968 // Finally, this transport will be closed and freed in the main thread. 969 kick_transport_locked(t); 970 } 971 } 972 adb_mutex_unlock(&transport_lock); 973} 974 975#endif 976 977void register_usb_transport(usb_handle* usb, const char* serial, 978 const char* devpath, unsigned writeable) { 979 atransport* t = new atransport(); 980 981 D("transport: %p init'ing for usb_handle %p (sn='%s')", t, usb, 982 serial ? serial : ""); 983 init_usb_transport(t, usb, (writeable ? kCsOffline : kCsNoPerm)); 984 if(serial) { 985 t->serial = strdup(serial); 986 } 987 988 if (devpath) { 989 t->devpath = strdup(devpath); 990 } 991 992 adb_mutex_lock(&transport_lock); 993 pending_list.push_front(t); 994 adb_mutex_unlock(&transport_lock); 995 996 register_transport(t); 997} 998 999// This should only be used for transports with connection_state == kCsNoPerm. 1000void unregister_usb_transport(usb_handle *usb) { 1001 adb_mutex_lock(&transport_lock); 1002 transport_list.remove_if([usb](atransport* t) { 1003 return t->usb == usb && t->connection_state == kCsNoPerm; 1004 }); 1005 adb_mutex_unlock(&transport_lock); 1006} 1007 1008int check_header(apacket *p, atransport *t) 1009{ 1010 if(p->msg.magic != (p->msg.command ^ 0xffffffff)) { 1011 VLOG(RWX) << "check_header(): invalid magic"; 1012 return -1; 1013 } 1014 1015 if(p->msg.data_length > t->get_max_payload()) { 1016 VLOG(RWX) << "check_header(): " << p->msg.data_length << " atransport::max_payload = " 1017 << t->get_max_payload(); 1018 return -1; 1019 } 1020 1021 return 0; 1022} 1023 1024int check_data(apacket *p) 1025{ 1026 unsigned count, sum; 1027 unsigned char *x; 1028 1029 count = p->msg.data_length; 1030 x = p->data; 1031 sum = 0; 1032 while(count-- > 0) { 1033 sum += *x++; 1034 } 1035 1036 if(sum != p->msg.data_check) { 1037 return -1; 1038 } else { 1039 return 0; 1040 } 1041} 1042