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_locked(atransport *t)
    675 {
    676     t->ref_count--;
    677     D("transport: %p R- (ref=%d)\n", t, t->ref_count);
    678     if (t->ref_count == 0) {
    679         D("transport: %p kicking and closing\n", t);
    680         if (!t->kicked) {
    681             t->kicked = 1;
    682             t->kick(t);
    683         }
    684         t->close(t);
    685         remove_transport(t);
    686     }
    687 }
    688 
    689 static void transport_unref(atransport *t)
    690 {
    691     if (t) {
    692         adb_mutex_lock(&transport_lock);
    693         transport_unref_locked(t);
    694         adb_mutex_unlock(&transport_lock);
    695     }
    696 }
    697 
    698 void add_transport_disconnect(atransport*  t, adisconnect*  dis)
    699 {
    700     adb_mutex_lock(&transport_lock);
    701     dis->next       = &t->disconnects;
    702     dis->prev       = dis->next->prev;
    703     dis->prev->next = dis;
    704     dis->next->prev = dis;
    705     adb_mutex_unlock(&transport_lock);
    706 }
    707 
    708 void remove_transport_disconnect(atransport*  t, adisconnect*  dis)
    709 {
    710     dis->prev->next = dis->next;
    711     dis->next->prev = dis->prev;
    712     dis->next = dis->prev = dis;
    713 }
    714 
    715 
    716 atransport *acquire_one_transport(int state, transport_type ttype, const char* serial, char** error_out)
    717 {
    718     atransport *t;
    719     atransport *result = NULL;
    720     int ambiguous = 0;
    721 
    722 retry:
    723     if (error_out)
    724         *error_out = "device not found";
    725 
    726     adb_mutex_lock(&transport_lock);
    727     for (t = transport_list.next; t != &transport_list; t = t->next) {
    728         if (t->connection_state == CS_NOPERM) {
    729         if (error_out)
    730             *error_out = "insufficient permissions for device";
    731             continue;
    732         }
    733 
    734         /* check for matching serial number */
    735         if (serial) {
    736             if (t->serial && !strcmp(serial, t->serial)) {
    737                 result = t;
    738                 break;
    739             }
    740         } else {
    741             if (ttype == kTransportUsb && t->type == kTransportUsb) {
    742                 if (result) {
    743                     if (error_out)
    744                         *error_out = "more than one device";
    745                     ambiguous = 1;
    746                     result = NULL;
    747                     break;
    748                 }
    749                 result = t;
    750             } else if (ttype == kTransportLocal && t->type == kTransportLocal) {
    751                 if (result) {
    752                     if (error_out)
    753                         *error_out = "more than one emulator";
    754                     ambiguous = 1;
    755                     result = NULL;
    756                     break;
    757                 }
    758                 result = t;
    759             } else if (ttype == kTransportAny) {
    760                 if (result) {
    761                     if (error_out)
    762                         *error_out = "more than one device and emulator";
    763                     ambiguous = 1;
    764                     result = NULL;
    765                     break;
    766                 }
    767                 result = t;
    768             }
    769         }
    770     }
    771     adb_mutex_unlock(&transport_lock);
    772 
    773     if (result) {
    774          /* offline devices are ignored -- they are either being born or dying */
    775         if (result && result->connection_state == CS_OFFLINE) {
    776             if (error_out)
    777                 *error_out = "device offline";
    778             result = NULL;
    779         }
    780          /* check for required connection state */
    781         if (result && state != CS_ANY && result->connection_state != state) {
    782             if (error_out)
    783                 *error_out = "invalid device state";
    784             result = NULL;
    785         }
    786     }
    787 
    788     if (result) {
    789         /* found one that we can take */
    790         if (error_out)
    791             *error_out = NULL;
    792     } else if (state != CS_ANY && (serial || !ambiguous)) {
    793         adb_sleep_ms(1000);
    794         goto retry;
    795     }
    796 
    797     return result;
    798 }
    799 
    800 #if ADB_HOST
    801 static const char *statename(atransport *t)
    802 {
    803     switch(t->connection_state){
    804     case CS_OFFLINE: return "offline";
    805     case CS_BOOTLOADER: return "bootloader";
    806     case CS_DEVICE: return "device";
    807     case CS_HOST: return "host";
    808     case CS_RECOVERY: return "recovery";
    809     case CS_NOPERM: return "no permissions";
    810     default: return "unknown";
    811     }
    812 }
    813 
    814 int list_transports(char *buf, size_t  bufsize)
    815 {
    816     char*       p   = buf;
    817     char*       end = buf + bufsize;
    818     int         len;
    819     atransport *t;
    820 
    821         /* XXX OVERRUN PROBLEMS XXX */
    822     adb_mutex_lock(&transport_lock);
    823     for(t = transport_list.next; t != &transport_list; t = t->next) {
    824         const char* serial = t->serial;
    825         if (!serial || !serial[0])
    826             serial = "????????????";
    827         len = snprintf(p, end - p, "%s\t%s\n", serial, statename(t));
    828 
    829         if (p + len >= end) {
    830             /* discard last line if buffer is too short */
    831             break;
    832         }
    833         p += len;
    834     }
    835     p[0] = 0;
    836     adb_mutex_unlock(&transport_lock);
    837     return p - buf;
    838 }
    839 
    840 
    841 /* hack for osx */
    842 void close_usb_devices()
    843 {
    844     atransport *t;
    845 
    846     adb_mutex_lock(&transport_lock);
    847     for(t = transport_list.next; t != &transport_list; t = t->next) {
    848         if ( !t->kicked ) {
    849             t->kicked = 1;
    850             t->kick(t);
    851         }
    852     }
    853     adb_mutex_unlock(&transport_lock);
    854 }
    855 #endif // ADB_HOST
    856 
    857 void register_socket_transport(int s, const char *serial, int port, int local)
    858 {
    859     atransport *t = calloc(1, sizeof(atransport));
    860     D("transport: %p init'ing for socket %d, on port %d\n", t, s, port);
    861     if ( init_socket_transport(t, s, port, local) < 0 ) {
    862         adb_close(s);
    863         free(t);
    864         return;
    865     }
    866     if(serial) {
    867         t->serial = strdup(serial);
    868     }
    869     register_transport(t);
    870 }
    871 
    872 #if ADB_HOST
    873 atransport *find_transport(const char *serial)
    874 {
    875     atransport *t;
    876 
    877     adb_mutex_lock(&transport_lock);
    878     for(t = transport_list.next; t != &transport_list; t = t->next) {
    879         if (t->serial && !strcmp(serial, t->serial)) {
    880             break;
    881         }
    882      }
    883     adb_mutex_unlock(&transport_lock);
    884 
    885     if (t != &transport_list)
    886         return t;
    887     else
    888         return 0;
    889 }
    890 
    891 void unregister_transport(atransport *t)
    892 {
    893     adb_mutex_lock(&transport_lock);
    894     t->next->prev = t->prev;
    895     t->prev->next = t->next;
    896     adb_mutex_unlock(&transport_lock);
    897 
    898     kick_transport(t);
    899     transport_unref(t);
    900 }
    901 
    902 // unregisters all non-emulator TCP transports
    903 void unregister_all_tcp_transports()
    904 {
    905     atransport *t, *next;
    906     adb_mutex_lock(&transport_lock);
    907     for (t = transport_list.next; t != &transport_list; t = next) {
    908         next = t->next;
    909         if (t->type == kTransportLocal && t->adb_port == 0) {
    910             t->next->prev = t->prev;
    911             t->prev->next = next;
    912             // we cannot call kick_transport when holding transport_lock
    913             if (!t->kicked)
    914             {
    915                 t->kicked = 1;
    916                 t->kick(t);
    917             }
    918             transport_unref_locked(t);
    919         }
    920      }
    921 
    922     adb_mutex_unlock(&transport_lock);
    923 }
    924 
    925 #endif
    926 
    927 void register_usb_transport(usb_handle *usb, const char *serial, unsigned writeable)
    928 {
    929     atransport *t = calloc(1, sizeof(atransport));
    930     D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb,
    931       serial ? serial : "");
    932     init_usb_transport(t, usb, (writeable ? CS_OFFLINE : CS_NOPERM));
    933     if(serial) {
    934         t->serial = strdup(serial);
    935     }
    936     register_transport(t);
    937 }
    938 
    939 /* this should only be used for transports with connection_state == CS_NOPERM */
    940 void unregister_usb_transport(usb_handle *usb)
    941 {
    942     atransport *t;
    943     adb_mutex_lock(&transport_lock);
    944     for(t = transport_list.next; t != &transport_list; t = t->next) {
    945         if (t->usb == usb && t->connection_state == CS_NOPERM) {
    946             t->next->prev = t->prev;
    947             t->prev->next = t->next;
    948             break;
    949         }
    950      }
    951     adb_mutex_unlock(&transport_lock);
    952 }
    953 
    954 #undef TRACE_TAG
    955 #define TRACE_TAG  TRACE_RWX
    956 
    957 int readx(int fd, void *ptr, size_t len)
    958 {
    959     char *p = ptr;
    960     int r;
    961 #if ADB_TRACE
    962     int  len0 = len;
    963 #endif
    964     D("readx: %d %p %d\n", fd, ptr, (int)len);
    965     while(len > 0) {
    966         r = adb_read(fd, p, len);
    967         if(r > 0) {
    968             len -= r;
    969             p += r;
    970         } else {
    971             D("readx: %d %d %s\n", fd, r, strerror(errno));
    972             if((r < 0) && (errno == EINTR)) continue;
    973             return -1;
    974         }
    975     }
    976 
    977 #if ADB_TRACE
    978     D("readx: %d ok: ", fd);
    979     dump_hex( ptr, len0 );
    980 #endif
    981     return 0;
    982 }
    983 
    984 int writex(int fd, const void *ptr, size_t len)
    985 {
    986     char *p = (char*) ptr;
    987     int r;
    988 
    989 #if ADB_TRACE
    990     D("writex: %d %p %d: ", fd, ptr, (int)len);
    991     dump_hex( ptr, len );
    992 #endif
    993     while(len > 0) {
    994         r = adb_write(fd, p, len);
    995         if(r > 0) {
    996             len -= r;
    997             p += r;
    998         } else {
    999             D("writex: %d %d %s\n", fd, r, strerror(errno));
   1000             if((r < 0) && (errno == EINTR)) continue;
   1001             return -1;
   1002         }
   1003     }
   1004 
   1005     D("writex: %d ok\n", fd);
   1006     return 0;
   1007 }
   1008 
   1009 int check_header(apacket *p)
   1010 {
   1011     if(p->msg.magic != (p->msg.command ^ 0xffffffff)) {
   1012         D("check_header(): invalid magic\n");
   1013         return -1;
   1014     }
   1015 
   1016     if(p->msg.data_length > MAX_PAYLOAD) {
   1017         D("check_header(): %d > MAX_PAYLOAD\n", p->msg.data_length);
   1018         return -1;
   1019     }
   1020 
   1021     return 0;
   1022 }
   1023 
   1024 int 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 
   1043