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