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 { FdConnectionFdConnection81 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 { UsbConnectionUsbConnection93 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) id(NextTransportId ())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 } ~atransport()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 IsTcpDevice()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 serial_name()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 features()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