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