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