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