Home | History | Annotate | Download | only in adb
      1 /*
      2  * Copyright (C) 2011 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 #ifndef __TRANSPORT_H
     18 #define __TRANSPORT_H
     19 
     20 #include <sys/types.h>
     21 
     22 #include <atomic>
     23 #include <deque>
     24 #include <functional>
     25 #include <list>
     26 #include <memory>
     27 #include <mutex>
     28 #include <string>
     29 #include <unordered_set>
     30 
     31 #include <openssl/rsa.h>
     32 
     33 #include "adb.h"
     34 #include "adb_unique_fd.h"
     35 
     36 typedef std::unordered_set<std::string> FeatureSet;
     37 
     38 const FeatureSet& supported_features();
     39 
     40 // Encodes and decodes FeatureSet objects into human-readable strings.
     41 std::string FeatureSetToString(const FeatureSet& features);
     42 FeatureSet StringToFeatureSet(const std::string& features_string);
     43 
     44 // Returns true if both local features and |feature_set| support |feature|.
     45 bool CanUseFeature(const FeatureSet& feature_set, const std::string& feature);
     46 
     47 // Do not use any of [:;=,] in feature strings, they have special meaning
     48 // in the connection banner.
     49 extern const char* const kFeatureShell2;
     50 // The 'cmd' command is available
     51 extern const char* const kFeatureCmd;
     52 extern const char* const kFeatureStat2;
     53 // The server is running with libusb enabled.
     54 extern const char* const kFeatureLibusb;
     55 // The server supports `push --sync`.
     56 extern const char* const kFeaturePushSync;
     57 
     58 TransportId NextTransportId();
     59 
     60 // Abstraction for a blocking packet transport.
     61 struct Connection {
     62     Connection() = default;
     63     Connection(const Connection& copy) = delete;
     64     Connection(Connection&& move) = delete;
     65 
     66     // Destroy a Connection. Formerly known as 'Close' in atransport.
     67     virtual ~Connection() = default;
     68 
     69     // Read/Write a packet. These functions are concurrently called from a transport's reader/writer
     70     // threads.
     71     virtual bool Read(apacket* packet) = 0;
     72     virtual bool Write(apacket* packet) = 0;
     73 
     74     // Terminate a connection.
     75     // This method must be thread-safe, and must cause concurrent Reads/Writes to terminate.
     76     // Formerly known as 'Kick' in atransport.
     77     virtual void Close() = 0;
     78 };
     79 
     80 struct FdConnection : public Connection {
     81     explicit FdConnection(unique_fd fd) : fd_(std::move(fd)) {}
     82 
     83     bool Read(apacket* packet) override final;
     84     bool Write(apacket* packet) override final;
     85 
     86     void Close() override;
     87 
     88   private:
     89     unique_fd fd_;
     90 };
     91 
     92 struct UsbConnection : public Connection {
     93     explicit UsbConnection(usb_handle* handle) : handle_(handle) {}
     94     ~UsbConnection();
     95 
     96     bool Read(apacket* packet) override final;
     97     bool Write(apacket* packet) override final;
     98 
     99     void Close() override final;
    100 
    101     usb_handle* handle_;
    102 };
    103 
    104 class atransport {
    105   public:
    106     // TODO(danalbert): We expose waaaaaaay too much stuff because this was
    107     // historically just a struct, but making the whole thing a more idiomatic
    108     // class in one go is a very large change. Given how bad our testing is,
    109     // it's better to do this piece by piece.
    110 
    111     atransport(ConnectionState state = kCsOffline)
    112         : id(NextTransportId()), connection_state_(state) {
    113         transport_fde = {};
    114         // Initialize protocol to min version for compatibility with older versions.
    115         // Version will be updated post-connect.
    116         protocol_version = A_VERSION_MIN;
    117         max_payload = MAX_PAYLOAD;
    118     }
    119     virtual ~atransport() {}
    120 
    121     int Write(apacket* p);
    122     void Kick();
    123 
    124     // ConnectionState can be read by all threads, but can only be written in the main thread.
    125     ConnectionState GetConnectionState() const;
    126     void SetConnectionState(ConnectionState state);
    127 
    128     const TransportId id;
    129     int fd = -1;
    130     int transport_socket = -1;
    131     fdevent transport_fde;
    132     size_t ref_count = 0;
    133     uint32_t sync_token = 0;
    134     bool online = false;
    135     TransportType type = kTransportAny;
    136 
    137     std::unique_ptr<Connection> connection;
    138 
    139     // Used to identify transports for clients.
    140     char* serial = nullptr;
    141     char* product = nullptr;
    142     char* model = nullptr;
    143     char* device = nullptr;
    144     char* devpath = nullptr;
    145 
    146     bool IsTcpDevice() const { return type == kTransportLocal; }
    147 
    148 #if ADB_HOST
    149     std::shared_ptr<RSA> NextKey();
    150 #endif
    151 
    152     char token[TOKEN_SIZE] = {};
    153     size_t failed_auth_attempts = 0;
    154 
    155     const std::string serial_name() const { return serial ? serial : "<unknown>"; }
    156     const std::string connection_state_name() const;
    157 
    158     void update_version(int version, size_t payload);
    159     int get_protocol_version() const;
    160     size_t get_max_payload() const;
    161 
    162     const FeatureSet& features() const {
    163         return features_;
    164     }
    165 
    166     bool has_feature(const std::string& feature) const;
    167 
    168     // Loads the transport's feature set from the given string.
    169     void SetFeatures(const std::string& features_string);
    170 
    171     void AddDisconnect(adisconnect* disconnect);
    172     void RemoveDisconnect(adisconnect* disconnect);
    173     void RunDisconnects();
    174 
    175     // Returns true if |target| matches this transport. A matching |target| can be any of:
    176     //   * <serial>
    177     //   * <devpath>
    178     //   * product:<product>
    179     //   * model:<model>
    180     //   * device:<device>
    181     //
    182     // If this is a local transport, serial will also match [tcp:|udp:]<hostname>[:port] targets.
    183     // For example, serial "100.100.100.100:5555" would match any of:
    184     //   * 100.100.100.100
    185     //   * tcp:100.100.100.100
    186     //   * udp:100.100.100.100:5555
    187     // This is to make it easier to use the same network target for both fastboot and adb.
    188     bool MatchesTarget(const std::string& target) const;
    189 
    190 private:
    191     bool kicked_ = false;
    192 
    193     // A set of features transmitted in the banner with the initial connection.
    194     // This is stored in the banner as 'features=feature0,feature1,etc'.
    195     FeatureSet features_;
    196     int protocol_version;
    197     size_t max_payload;
    198 
    199     // A list of adisconnect callbacks called when the transport is kicked.
    200     std::list<adisconnect*> disconnects_;
    201 
    202     std::atomic<ConnectionState> connection_state_;
    203 #if ADB_HOST
    204     std::deque<std::shared_ptr<RSA>> keys_;
    205 #endif
    206 
    207     DISALLOW_COPY_AND_ASSIGN(atransport);
    208 };
    209 
    210 /*
    211  * Obtain a transport from the available transports.
    212  * If serial is non-null then only the device with that serial will be chosen.
    213  * If transport_id is non-zero then only the device with that transport ID will be chosen.
    214  * If multiple devices/emulators would match, *is_ambiguous (if non-null)
    215  * is set to true and nullptr returned.
    216  * If no suitable transport is found, error is set and nullptr returned.
    217  */
    218 atransport* acquire_one_transport(TransportType type, const char* serial, TransportId transport_id,
    219                                   bool* is_ambiguous, std::string* error_out,
    220                                   bool accept_any_state = false);
    221 void kick_transport(atransport* t);
    222 void update_transports(void);
    223 
    224 // Iterates across all of the current and pending transports.
    225 // Stops iteration and returns false if fn returns false, otherwise returns true.
    226 bool iterate_transports(std::function<bool(const atransport*)> fn);
    227 
    228 void init_transport_registration(void);
    229 void init_mdns_transport_discovery(void);
    230 std::string list_transports(bool long_listing);
    231 atransport* find_transport(const char* serial);
    232 void kick_all_tcp_devices();
    233 void kick_all_transports();
    234 
    235 void register_usb_transport(usb_handle* h, const char* serial,
    236                             const char* devpath, unsigned writeable);
    237 
    238 /* Connect to a network address and register it as a device */
    239 void connect_device(const std::string& address, std::string* response);
    240 
    241 /* cause new transports to be init'd and added to the list */
    242 int register_socket_transport(int s, const char* serial, int port, int local);
    243 
    244 // This should only be used for transports with connection_state == kCsNoPerm.
    245 void unregister_usb_transport(usb_handle* usb);
    246 
    247 bool check_header(apacket* p, atransport* t);
    248 
    249 void close_usb_devices();
    250 void close_usb_devices(std::function<bool(const atransport*)> predicate);
    251 
    252 void send_packet(apacket* p, atransport* t);
    253 
    254 asocket* create_device_tracker(bool long_output);
    255 
    256 #endif   /* __TRANSPORT_H */
    257