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