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