Home | History | Annotate | Download | only in minadbd
      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 #define MAX_DUMP_HEX_LEN 16
     39 static void  dump_hex( const unsigned char*  ptr, size_t  len )
     40 {
     41     int  nn, len2 = len;
     42     // Build a string instead of logging each character.
     43     // MAX chars in 2 digit hex, one space, MAX chars, one '\0'.
     44     char buffer[MAX_DUMP_HEX_LEN *2 + 1 + MAX_DUMP_HEX_LEN + 1 ], *pb = buffer;
     45 
     46     if (len2 > MAX_DUMP_HEX_LEN) len2 = MAX_DUMP_HEX_LEN;
     47 
     48     for (nn = 0; nn < len2; nn++) {
     49         sprintf(pb, "%02x", ptr[nn]);
     50         pb += 2;
     51     }
     52     sprintf(pb++, " ");
     53 
     54     for (nn = 0; nn < len2; nn++) {
     55         int  c = ptr[nn];
     56         if (c < 32 || c > 127)
     57             c = '.';
     58         *pb++ =  c;
     59     }
     60     *pb++ = '\0';
     61     DR("%s\n", buffer);
     62 }
     63 #endif
     64 
     65 void
     66 kick_transport(atransport*  t)
     67 {
     68     if (t && !t->kicked)
     69     {
     70         int  kicked;
     71 
     72         adb_mutex_lock(&transport_lock);
     73         kicked = t->kicked;
     74         if (!kicked)
     75             t->kicked = 1;
     76         adb_mutex_unlock(&transport_lock);
     77 
     78         if (!kicked)
     79             t->kick(t);
     80     }
     81 }
     82 
     83 void
     84 run_transport_disconnects(atransport*  t)
     85 {
     86     adisconnect*  dis = t->disconnects.next;
     87 
     88     D("%s: run_transport_disconnects\n", t->serial);
     89     while (dis != &t->disconnects) {
     90         adisconnect*  next = dis->next;
     91         dis->func( dis->opaque, t );
     92         dis = next;
     93     }
     94 }
     95 
     96 #if ADB_TRACE
     97 static void
     98 dump_packet(const char* name, const char* func, apacket* p)
     99 {
    100     unsigned  command = p->msg.command;
    101     int       len     = p->msg.data_length;
    102     char      cmd[9];
    103     char      arg0[12], arg1[12];
    104     int       n;
    105 
    106     for (n = 0; n < 4; n++) {
    107         int  b = (command >> (n*8)) & 255;
    108         if (b < 32 || b >= 127)
    109             break;
    110         cmd[n] = (char)b;
    111     }
    112     if (n == 4) {
    113         cmd[4] = 0;
    114     } else {
    115         /* There is some non-ASCII name in the command, so dump
    116             * the hexadecimal value instead */
    117         snprintf(cmd, sizeof cmd, "%08x", command);
    118     }
    119 
    120     if (p->msg.arg0 < 256U)
    121         snprintf(arg0, sizeof arg0, "%d", p->msg.arg0);
    122     else
    123         snprintf(arg0, sizeof arg0, "0x%x", p->msg.arg0);
    124 
    125     if (p->msg.arg1 < 256U)
    126         snprintf(arg1, sizeof arg1, "%d", p->msg.arg1);
    127     else
    128         snprintf(arg1, sizeof arg1, "0x%x", p->msg.arg1);
    129 
    130     D("%s: %s: [%s] arg0=%s arg1=%s (len=%d) ",
    131         name, func, cmd, arg0, arg1, len);
    132     dump_hex(p->data, len);
    133 }
    134 #endif /* ADB_TRACE */
    135 
    136 static int
    137 read_packet(int  fd, const char* name, apacket** ppacket)
    138 {
    139     char *p = (char*)ppacket;  /* really read a packet address */
    140     int   r;
    141     int   len = sizeof(*ppacket);
    142     char  buff[8];
    143     if (!name) {
    144         snprintf(buff, sizeof buff, "fd=%d", fd);
    145         name = buff;
    146     }
    147     while(len > 0) {
    148         r = adb_read(fd, p, len);
    149         if(r > 0) {
    150             len -= r;
    151             p   += r;
    152         } else {
    153             D("%s: read_packet (fd=%d), error ret=%d errno=%d: %s\n", name, fd, r, errno, strerror(errno));
    154             if((r < 0) && (errno == EINTR)) continue;
    155             return -1;
    156         }
    157     }
    158 
    159 #if ADB_TRACE
    160     if (ADB_TRACING) {
    161         dump_packet(name, "from remote", *ppacket);
    162     }
    163 #endif
    164     return 0;
    165 }
    166 
    167 static int
    168 write_packet(int  fd, const char* name, apacket** ppacket)
    169 {
    170     char *p = (char*) ppacket;  /* we really write the packet address */
    171     int r, len = sizeof(ppacket);
    172     char buff[8];
    173     if (!name) {
    174         snprintf(buff, sizeof buff, "fd=%d", fd);
    175         name = buff;
    176     }
    177 
    178 #if ADB_TRACE
    179     if (ADB_TRACING) {
    180         dump_packet(name, "to remote", *ppacket);
    181     }
    182 #endif
    183     len = sizeof(ppacket);
    184     while(len > 0) {
    185         r = adb_write(fd, p, len);
    186         if(r > 0) {
    187             len -= r;
    188             p += r;
    189         } else {
    190             D("%s: write_packet (fd=%d) error ret=%d errno=%d: %s\n", name, fd, r, errno, strerror(errno));
    191             if((r < 0) && (errno == EINTR)) continue;
    192             return -1;
    193         }
    194     }
    195     return 0;
    196 }
    197 
    198 static void transport_socket_events(int fd, unsigned events, void *_t)
    199 {
    200     atransport *t = _t;
    201     D("transport_socket_events(fd=%d, events=%04x,...)\n", fd, events);
    202     if(events & FDE_READ){
    203         apacket *p = 0;
    204         if(read_packet(fd, t->serial, &p)){
    205             D("%s: failed to read packet from transport socket on fd %d\n", t->serial, fd);
    206         } else {
    207             handle_packet(p, (atransport *) _t);
    208         }
    209     }
    210 }
    211 
    212 void send_packet(apacket *p, atransport *t)
    213 {
    214     unsigned char *x;
    215     unsigned sum;
    216     unsigned count;
    217 
    218     p->msg.magic = p->msg.command ^ 0xffffffff;
    219 
    220     count = p->msg.data_length;
    221     x = (unsigned char *) p->data;
    222     sum = 0;
    223     while(count-- > 0){
    224         sum += *x++;
    225     }
    226     p->msg.data_check = sum;
    227 
    228     print_packet("send", p);
    229 
    230     if (t == NULL) {
    231         D("Transport is null \n");
    232         // Zap errno because print_packet() and other stuff have errno effect.
    233         errno = 0;
    234         fatal_errno("Transport is null");
    235     }
    236 
    237     if(write_packet(t->transport_socket, t->serial, &p)){
    238         fatal_errno("cannot enqueue packet on transport socket");
    239     }
    240 }
    241 
    242 /* The transport is opened by transport_register_func before
    243 ** the input and output threads are started.
    244 **
    245 ** The output thread issues a SYNC(1, token) message to let
    246 ** the input thread know to start things up.  In the event
    247 ** of transport IO failure, the output thread will post a
    248 ** SYNC(0,0) message to ensure shutdown.
    249 **
    250 ** The transport will not actually be closed until both
    251 ** threads exit, but the input thread will kick the transport
    252 ** on its way out to disconnect the underlying device.
    253 */
    254 
    255 static void *output_thread(void *_t)
    256 {
    257     atransport *t = _t;
    258     apacket *p;
    259 
    260     D("%s: starting transport output thread on fd %d, SYNC online (%d)\n",
    261        t->serial, t->fd, t->sync_token + 1);
    262     p = get_apacket();
    263     p->msg.command = A_SYNC;
    264     p->msg.arg0 = 1;
    265     p->msg.arg1 = ++(t->sync_token);
    266     p->msg.magic = A_SYNC ^ 0xffffffff;
    267     if(write_packet(t->fd, t->serial, &p)) {
    268         put_apacket(p);
    269         D("%s: failed to write SYNC packet\n", t->serial);
    270         goto oops;
    271     }
    272 
    273     D("%s: data pump started\n", t->serial);
    274     for(;;) {
    275         p = get_apacket();
    276 
    277         if(t->read_from_remote(p, t) == 0){
    278             D("%s: received remote packet, sending to transport\n",
    279               t->serial);
    280             if(write_packet(t->fd, t->serial, &p)){
    281                 put_apacket(p);
    282                 D("%s: failed to write apacket to transport\n", t->serial);
    283                 goto oops;
    284             }
    285         } else {
    286             D("%s: remote read failed for transport\n", t->serial);
    287             put_apacket(p);
    288             break;
    289         }
    290     }
    291 
    292     D("%s: SYNC offline for transport\n", t->serial);
    293     p = get_apacket();
    294     p->msg.command = A_SYNC;
    295     p->msg.arg0 = 0;
    296     p->msg.arg1 = 0;
    297     p->msg.magic = A_SYNC ^ 0xffffffff;
    298     if(write_packet(t->fd, t->serial, &p)) {
    299         put_apacket(p);
    300         D("%s: failed to write SYNC apacket to transport", t->serial);
    301     }
    302 
    303 oops:
    304     D("%s: transport output thread is exiting\n", t->serial);
    305     kick_transport(t);
    306     transport_unref(t);
    307     return 0;
    308 }
    309 
    310 static void *input_thread(void *_t)
    311 {
    312     atransport *t = _t;
    313     apacket *p;
    314     int active = 0;
    315 
    316     D("%s: starting transport input thread, reading from fd %d\n",
    317        t->serial, t->fd);
    318 
    319     for(;;){
    320         if(read_packet(t->fd, t->serial, &p)) {
    321             D("%s: failed to read apacket from transport on fd %d\n",
    322                t->serial, t->fd );
    323             break;
    324         }
    325         if(p->msg.command == A_SYNC){
    326             if(p->msg.arg0 == 0) {
    327                 D("%s: transport SYNC offline\n", t->serial);
    328                 put_apacket(p);
    329                 break;
    330             } else {
    331                 if(p->msg.arg1 == t->sync_token) {
    332                     D("%s: transport SYNC online\n", t->serial);
    333                     active = 1;
    334                 } else {
    335                     D("%s: transport ignoring SYNC %d != %d\n",
    336                       t->serial, p->msg.arg1, t->sync_token);
    337                 }
    338             }
    339         } else {
    340             if(active) {
    341                 D("%s: transport got packet, sending to remote\n", t->serial);
    342                 t->write_to_remote(p, t);
    343             } else {
    344                 D("%s: transport ignoring packet while offline\n", t->serial);
    345             }
    346         }
    347 
    348         put_apacket(p);
    349     }
    350 
    351     // this is necessary to avoid a race condition that occured when a transport closes
    352     // while a client socket is still active.
    353     close_all_sockets(t);
    354 
    355     D("%s: transport input thread is exiting, fd %d\n", t->serial, t->fd);
    356     kick_transport(t);
    357     transport_unref(t);
    358     return 0;
    359 }
    360 
    361 
    362 static int transport_registration_send = -1;
    363 static int transport_registration_recv = -1;
    364 static fdevent transport_registration_fde;
    365 
    366 void  update_transports(void)
    367 {
    368     // nothing to do on the device side
    369 }
    370 
    371 typedef struct tmsg tmsg;
    372 struct tmsg
    373 {
    374     atransport *transport;
    375     int         action;
    376 };
    377 
    378 static int
    379 transport_read_action(int  fd, struct tmsg*  m)
    380 {
    381     char *p   = (char*)m;
    382     int   len = sizeof(*m);
    383     int   r;
    384 
    385     while(len > 0) {
    386         r = adb_read(fd, p, len);
    387         if(r > 0) {
    388             len -= r;
    389             p   += r;
    390         } else {
    391             if((r < 0) && (errno == EINTR)) continue;
    392             D("transport_read_action: on fd %d, error %d: %s\n",
    393               fd, errno, strerror(errno));
    394             return -1;
    395         }
    396     }
    397     return 0;
    398 }
    399 
    400 static int
    401 transport_write_action(int  fd, struct tmsg*  m)
    402 {
    403     char *p   = (char*)m;
    404     int   len = sizeof(*m);
    405     int   r;
    406 
    407     while(len > 0) {
    408         r = adb_write(fd, p, len);
    409         if(r > 0) {
    410             len -= r;
    411             p   += r;
    412         } else {
    413             if((r < 0) && (errno == EINTR)) continue;
    414             D("transport_write_action: on fd %d, error %d: %s\n",
    415               fd, errno, strerror(errno));
    416             return -1;
    417         }
    418     }
    419     return 0;
    420 }
    421 
    422 static void transport_registration_func(int _fd, unsigned ev, void *data)
    423 {
    424     tmsg m;
    425     adb_thread_t output_thread_ptr;
    426     adb_thread_t input_thread_ptr;
    427     int s[2];
    428     atransport *t;
    429 
    430     if(!(ev & FDE_READ)) {
    431         return;
    432     }
    433 
    434     if(transport_read_action(_fd, &m)) {
    435         fatal_errno("cannot read transport registration socket");
    436     }
    437 
    438     t = m.transport;
    439 
    440     if(m.action == 0){
    441         D("transport: %s removing and free'ing %d\n", t->serial, t->transport_socket);
    442 
    443             /* IMPORTANT: the remove closes one half of the
    444             ** socket pair.  The close closes the other half.
    445             */
    446         fdevent_remove(&(t->transport_fde));
    447         adb_close(t->fd);
    448 
    449         adb_mutex_lock(&transport_lock);
    450         t->next->prev = t->prev;
    451         t->prev->next = t->next;
    452         adb_mutex_unlock(&transport_lock);
    453 
    454         run_transport_disconnects(t);
    455 
    456         if (t->product)
    457             free(t->product);
    458         if (t->serial)
    459             free(t->serial);
    460 
    461         memset(t,0xee,sizeof(atransport));
    462         free(t);
    463 
    464         update_transports();
    465         return;
    466     }
    467 
    468     /* don't create transport threads for inaccessible devices */
    469     if (t->connection_state != CS_NOPERM) {
    470         /* initial references are the two threads */
    471         t->ref_count = 2;
    472 
    473         if(adb_socketpair(s)) {
    474             fatal_errno("cannot open transport socketpair");
    475         }
    476 
    477         D("transport: %s (%d,%d) starting\n", t->serial, s[0], s[1]);
    478 
    479         t->transport_socket = s[0];
    480         t->fd = s[1];
    481 
    482         fdevent_install(&(t->transport_fde),
    483                         t->transport_socket,
    484                         transport_socket_events,
    485                         t);
    486 
    487         fdevent_set(&(t->transport_fde), FDE_READ);
    488 
    489         if(adb_thread_create(&input_thread_ptr, input_thread, t)){
    490             fatal_errno("cannot create input thread");
    491         }
    492 
    493         if(adb_thread_create(&output_thread_ptr, output_thread, t)){
    494             fatal_errno("cannot create output thread");
    495         }
    496     }
    497 
    498         /* put us on the master device list */
    499     adb_mutex_lock(&transport_lock);
    500     t->next = &transport_list;
    501     t->prev = transport_list.prev;
    502     t->next->prev = t;
    503     t->prev->next = t;
    504     adb_mutex_unlock(&transport_lock);
    505 
    506     t->disconnects.next = t->disconnects.prev = &t->disconnects;
    507 
    508     update_transports();
    509 }
    510 
    511 void init_transport_registration(void)
    512 {
    513     int s[2];
    514 
    515     if(adb_socketpair(s)){
    516         fatal_errno("cannot open transport registration socketpair");
    517     }
    518 
    519     transport_registration_send = s[0];
    520     transport_registration_recv = s[1];
    521 
    522     fdevent_install(&transport_registration_fde,
    523                     transport_registration_recv,
    524                     transport_registration_func,
    525                     0);
    526 
    527     fdevent_set(&transport_registration_fde, FDE_READ);
    528 }
    529 
    530 /* the fdevent select pump is single threaded */
    531 static void register_transport(atransport *transport)
    532 {
    533     tmsg m;
    534     m.transport = transport;
    535     m.action = 1;
    536     D("transport: %s registered\n", transport->serial);
    537     if(transport_write_action(transport_registration_send, &m)) {
    538         fatal_errno("cannot write transport registration socket\n");
    539     }
    540 }
    541 
    542 static void remove_transport(atransport *transport)
    543 {
    544     tmsg m;
    545     m.transport = transport;
    546     m.action = 0;
    547     D("transport: %s removed\n", transport->serial);
    548     if(transport_write_action(transport_registration_send, &m)) {
    549         fatal_errno("cannot write transport registration socket\n");
    550     }
    551 }
    552 
    553 
    554 static void transport_unref_locked(atransport *t)
    555 {
    556     t->ref_count--;
    557     if (t->ref_count == 0) {
    558         D("transport: %s unref (kicking and closing)\n", t->serial);
    559         if (!t->kicked) {
    560             t->kicked = 1;
    561             t->kick(t);
    562         }
    563         t->close(t);
    564         remove_transport(t);
    565     } else {
    566         D("transport: %s unref (count=%d)\n", t->serial, t->ref_count);
    567     }
    568 }
    569 
    570 static void transport_unref(atransport *t)
    571 {
    572     if (t) {
    573         adb_mutex_lock(&transport_lock);
    574         transport_unref_locked(t);
    575         adb_mutex_unlock(&transport_lock);
    576     }
    577 }
    578 
    579 void add_transport_disconnect(atransport*  t, adisconnect*  dis)
    580 {
    581     adb_mutex_lock(&transport_lock);
    582     dis->next       = &t->disconnects;
    583     dis->prev       = dis->next->prev;
    584     dis->prev->next = dis;
    585     dis->next->prev = dis;
    586     adb_mutex_unlock(&transport_lock);
    587 }
    588 
    589 void remove_transport_disconnect(atransport*  t, adisconnect*  dis)
    590 {
    591     dis->prev->next = dis->next;
    592     dis->next->prev = dis->prev;
    593     dis->next = dis->prev = dis;
    594 }
    595 
    596 
    597 atransport *acquire_one_transport(int state, transport_type ttype, const char* serial, char** error_out)
    598 {
    599     atransport *t;
    600     atransport *result = NULL;
    601     int ambiguous = 0;
    602 
    603 retry:
    604     if (error_out)
    605         *error_out = "device not found";
    606 
    607     adb_mutex_lock(&transport_lock);
    608     for (t = transport_list.next; t != &transport_list; t = t->next) {
    609         if (t->connection_state == CS_NOPERM) {
    610         if (error_out)
    611             *error_out = "insufficient permissions for device";
    612             continue;
    613         }
    614 
    615         /* check for matching serial number */
    616         if (serial) {
    617             if (t->serial && !strcmp(serial, t->serial)) {
    618                 result = t;
    619                 break;
    620             }
    621         } else {
    622             if (ttype == kTransportUsb && t->type == kTransportUsb) {
    623                 if (result) {
    624                     if (error_out)
    625                         *error_out = "more than one device";
    626                     ambiguous = 1;
    627                     result = NULL;
    628                     break;
    629                 }
    630                 result = t;
    631             } else if (ttype == kTransportLocal && t->type == kTransportLocal) {
    632                 if (result) {
    633                     if (error_out)
    634                         *error_out = "more than one emulator";
    635                     ambiguous = 1;
    636                     result = NULL;
    637                     break;
    638                 }
    639                 result = t;
    640             } else if (ttype == kTransportAny) {
    641                 if (result) {
    642                     if (error_out)
    643                         *error_out = "more than one device and emulator";
    644                     ambiguous = 1;
    645                     result = NULL;
    646                     break;
    647                 }
    648                 result = t;
    649             }
    650         }
    651     }
    652     adb_mutex_unlock(&transport_lock);
    653 
    654     if (result) {
    655          /* offline devices are ignored -- they are either being born or dying */
    656         if (result && result->connection_state == CS_OFFLINE) {
    657             if (error_out)
    658                 *error_out = "device offline";
    659             result = NULL;
    660         }
    661          /* check for required connection state */
    662         if (result && state != CS_ANY && result->connection_state != state) {
    663             if (error_out)
    664                 *error_out = "invalid device state";
    665             result = NULL;
    666         }
    667     }
    668 
    669     if (result) {
    670         /* found one that we can take */
    671         if (error_out)
    672             *error_out = NULL;
    673     } else if (state != CS_ANY && (serial || !ambiguous)) {
    674         adb_sleep_ms(1000);
    675         goto retry;
    676     }
    677 
    678     return result;
    679 }
    680 
    681 void register_socket_transport(int s, const char *serial, int port, int local)
    682 {
    683     atransport *t = calloc(1, sizeof(atransport));
    684     char buff[32];
    685 
    686     if (!serial) {
    687         snprintf(buff, sizeof buff, "T-%p", t);
    688         serial = buff;
    689     }
    690     D("transport: %s init'ing for socket %d, on port %d\n", serial, s, port);
    691     if ( init_socket_transport(t, s, port, local) < 0 ) {
    692         adb_close(s);
    693         free(t);
    694         return;
    695     }
    696     if(serial) {
    697         t->serial = strdup(serial);
    698     }
    699     register_transport(t);
    700 }
    701 
    702 void register_usb_transport(usb_handle *usb, const char *serial, unsigned writeable)
    703 {
    704     atransport *t = calloc(1, sizeof(atransport));
    705     D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb,
    706       serial ? serial : "");
    707     init_usb_transport(t, usb, (writeable ? CS_OFFLINE : CS_NOPERM));
    708     if(serial) {
    709         t->serial = strdup(serial);
    710     }
    711     register_transport(t);
    712 }
    713 
    714 /* this should only be used for transports with connection_state == CS_NOPERM */
    715 void unregister_usb_transport(usb_handle *usb)
    716 {
    717     atransport *t;
    718     adb_mutex_lock(&transport_lock);
    719     for(t = transport_list.next; t != &transport_list; t = t->next) {
    720         if (t->usb == usb && t->connection_state == CS_NOPERM) {
    721             t->next->prev = t->prev;
    722             t->prev->next = t->next;
    723             break;
    724         }
    725      }
    726     adb_mutex_unlock(&transport_lock);
    727 }
    728 
    729 #undef TRACE_TAG
    730 #define TRACE_TAG  TRACE_RWX
    731 
    732 int readx(int fd, void *ptr, size_t len)
    733 {
    734     char *p = ptr;
    735     int r;
    736 #if ADB_TRACE
    737     int  len0 = len;
    738 #endif
    739     D("readx: fd=%d wanted=%d\n", fd, (int)len);
    740     while(len > 0) {
    741         r = adb_read(fd, p, len);
    742         if(r > 0) {
    743             len -= r;
    744             p += r;
    745         } else {
    746             if (r < 0) {
    747                 D("readx: fd=%d error %d: %s\n", fd, errno, strerror(errno));
    748                 if (errno == EINTR)
    749                     continue;
    750             } else {
    751                 D("readx: fd=%d disconnected\n", fd);
    752             }
    753             return -1;
    754         }
    755     }
    756 
    757 #if ADB_TRACE
    758     D("readx: fd=%d wanted=%d got=%d\n", fd, len0, len0 - len);
    759     dump_hex( ptr, len0 );
    760 #endif
    761     return 0;
    762 }
    763 
    764 int writex(int fd, const void *ptr, size_t len)
    765 {
    766     char *p = (char*) ptr;
    767     int r;
    768 
    769 #if ADB_TRACE
    770     D("writex: fd=%d len=%d: ", fd, (int)len);
    771     dump_hex( ptr, len );
    772 #endif
    773     while(len > 0) {
    774         r = adb_write(fd, p, len);
    775         if(r > 0) {
    776             len -= r;
    777             p += r;
    778         } else {
    779             if (r < 0) {
    780                 D("writex: fd=%d error %d: %s\n", fd, errno, strerror(errno));
    781                 if (errno == EINTR)
    782                     continue;
    783             } else {
    784                 D("writex: fd=%d disconnected\n", fd);
    785             }
    786             return -1;
    787         }
    788     }
    789     return 0;
    790 }
    791 
    792 int check_header(apacket *p)
    793 {
    794     if(p->msg.magic != (p->msg.command ^ 0xffffffff)) {
    795         D("check_header(): invalid magic\n");
    796         return -1;
    797     }
    798 
    799     if(p->msg.data_length > MAX_PAYLOAD) {
    800         D("check_header(): %d > MAX_PAYLOAD\n", p->msg.data_length);
    801         return -1;
    802     }
    803 
    804     return 0;
    805 }
    806 
    807 int check_data(apacket *p)
    808 {
    809     unsigned count, sum;
    810     unsigned char *x;
    811 
    812     count = p->msg.data_length;
    813     x = p->data;
    814     sum = 0;
    815     while(count-- > 0) {
    816         sum += *x++;
    817     }
    818 
    819     if(sum != p->msg.data_check) {
    820         return -1;
    821     } else {
    822         return 0;
    823     }
    824 }
    825