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