OLD | NEW |
| (Empty) |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef COMPONENTS_PROXIMITY_AUTH_BLE_BLUETOOTH_LOW_ENERGY_WEAVE_CLIENT_CONNECTI
ON_H_ | |
6 #define COMPONENTS_PROXIMITY_AUTH_BLE_BLUETOOTH_LOW_ENERGY_WEAVE_CLIENT_CONNECTI
ON_H_ | |
7 | |
8 #include <stddef.h> | |
9 #include <stdint.h> | |
10 | |
11 #include <map> | |
12 #include <memory> | |
13 #include <queue> | |
14 #include <string> | |
15 | |
16 #include "base/macros.h" | |
17 #include "base/memory/ref_counted.h" | |
18 #include "base/memory/weak_ptr.h" | |
19 #include "base/time/time.h" | |
20 #include "components/proximity_auth/ble/bluetooth_low_energy_characteristics_fin
der.h" | |
21 #include "components/proximity_auth/ble/bluetooth_low_energy_weave_packet_genera
tor.h" | |
22 #include "components/proximity_auth/ble/bluetooth_low_energy_weave_packet_receiv
er.h" | |
23 #include "components/proximity_auth/ble/fake_wire_message.h" | |
24 #include "components/proximity_auth/ble/remote_attribute.h" | |
25 #include "components/proximity_auth/connection.h" | |
26 #include "device/bluetooth/bluetooth_adapter.h" | |
27 #include "device/bluetooth/bluetooth_device.h" | |
28 #include "device/bluetooth/bluetooth_gatt_notify_session.h" | |
29 #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h" | |
30 #include "device/bluetooth/bluetooth_uuid.h" | |
31 | |
32 namespace base { | |
33 class TaskRunner; | |
34 } | |
35 | |
36 namespace proximity_auth { | |
37 class BluetoothThrottler; | |
38 | |
39 namespace weave { | |
40 // Creates GATT connection on top of the BLE connection and act as a Client. | |
41 // uWeave communication follows the flow: | |
42 // Client | Server | |
43 // ---------------------------------|-------------------------------- | |
44 // send connection request | | |
45 // | receive connection request | |
46 // | send connection response | |
47 // receive connection response | | |
48 // opt: send data | opt: send data | |
49 // receive data | receive data | |
50 // opt: close connection | opt: close connection | |
51 class BluetoothLowEnergyWeaveClientConnection | |
52 : public Connection, | |
53 public device::BluetoothAdapter::Observer { | |
54 public: | |
55 class Factory { | |
56 public: | |
57 static std::unique_ptr<BluetoothLowEnergyWeaveClientConnection> | |
58 NewInstance(); | |
59 | |
60 // Exposed for testing. | |
61 static void SetInstanceForTesting(Factory* factory); | |
62 | |
63 protected: | |
64 // Exposed for testing. | |
65 virtual std::unique_ptr<BluetoothLowEnergyWeaveClientConnection> | |
66 BuildInstance(); | |
67 | |
68 private: | |
69 static Factory* factory_instance_; | |
70 }; | |
71 | |
72 // The sub-state of a proximity_auth::BluetoothLowEnergyWeaveClientConnection | |
73 // extends the IN_PROGRESS state of proximity_auth::Connection::Status. | |
74 enum SubStatus { | |
75 DISCONNECTED, | |
76 WAITING_GATT_CONNECTION, | |
77 WAITING_CHARACTERISTICS, | |
78 CHARACTERISTICS_FOUND, | |
79 WAITING_NOTIFY_SESSION, | |
80 NOTIFY_SESSION_READY, | |
81 WAITING_CONNECTION_RESPONSE, | |
82 CONNECTED, | |
83 }; | |
84 | |
85 // Constructs a Bluetooth low energy connection to the service with | |
86 // |remote_service_| on the |remote_device|. The |adapter| must be already | |
87 // initialized and ready. The GATT connection may alreaady be established and | |
88 // pass through |gatt_connection|. A subsequent call to Connect() must be | |
89 // made. | |
90 BluetoothLowEnergyWeaveClientConnection( | |
91 const RemoteDevice& remote_device, | |
92 scoped_refptr<device::BluetoothAdapter> adapter, | |
93 const device::BluetoothUUID remote_service_uuid, | |
94 BluetoothThrottler* bluetooth_throttler, | |
95 int max_number_of_write_attempts); | |
96 | |
97 ~BluetoothLowEnergyWeaveClientConnection() override; | |
98 | |
99 // proximity_auth::Connection: | |
100 void Connect() override; | |
101 void Disconnect() override; | |
102 std::string GetDeviceAddress() override; | |
103 | |
104 protected: | |
105 // Exposed for testing. | |
106 void DestroyConnection(); | |
107 | |
108 // Exposed for testing. | |
109 SubStatus sub_status() { return sub_status_; } | |
110 | |
111 // Sets |task_runner_| for testing. | |
112 void SetTaskRunnerForTesting(scoped_refptr<base::TaskRunner> task_runner); | |
113 | |
114 // Virtual for testing. | |
115 virtual BluetoothLowEnergyCharacteristicsFinder* CreateCharacteristicsFinder( | |
116 const BluetoothLowEnergyCharacteristicsFinder::SuccessCallback& | |
117 success_callback, | |
118 const BluetoothLowEnergyCharacteristicsFinder::ErrorCallback& | |
119 error_callback); | |
120 | |
121 // proximity_auth::Connection: | |
122 void SendMessageImpl(std::unique_ptr<WireMessage> message) override; | |
123 | |
124 // device::BluetoothAdapter::Observer: | |
125 void DeviceChanged(device::BluetoothAdapter* adapter, | |
126 device::BluetoothDevice* device) override; | |
127 void DeviceRemoved(device::BluetoothAdapter* adapter, | |
128 device::BluetoothDevice* device) override; | |
129 void GattCharacteristicValueChanged( | |
130 device::BluetoothAdapter* adapter, | |
131 device::BluetoothRemoteGattCharacteristic* characteristic, | |
132 const Packet& value) override; | |
133 | |
134 private: | |
135 enum WriteRequestType { | |
136 REGULAR, | |
137 MESSAGE_COMPLETE, | |
138 CONNECTION_REQUEST, | |
139 CONNECTION_CLOSE | |
140 }; | |
141 | |
142 // Represents a request to write |value| to a some characteristic. | |
143 // |is_last_write_for_wire_messsage| indicates whether this request | |
144 // corresponds to the last write request for some wire message. | |
145 struct WriteRequest { | |
146 WriteRequest(const Packet& val, | |
147 WriteRequestType request_type, | |
148 std::shared_ptr<WireMessage> message); | |
149 WriteRequest(const Packet& val, WriteRequestType request_type); | |
150 WriteRequest(const WriteRequest& other); | |
151 ~WriteRequest(); | |
152 | |
153 Packet value; | |
154 WriteRequestType request_type; | |
155 std::shared_ptr<WireMessage> message; | |
156 int number_of_failed_attempts; | |
157 }; | |
158 | |
159 void SetSubStatus(SubStatus status); | |
160 | |
161 // Creates the GATT connection with |remote_device|. | |
162 void CreateGattConnection(); | |
163 | |
164 // Called when a GATT connection is created. | |
165 void OnGattConnectionCreated( | |
166 std::unique_ptr<device::BluetoothGattConnection> gatt_connection); | |
167 | |
168 // Callback called when there is an error creating the GATT connection. | |
169 void OnCreateGattConnectionError( | |
170 device::BluetoothDevice::ConnectErrorCode error_code); | |
171 | |
172 // Callback called when |tx_characteristic_| and |rx_characteristic_| were | |
173 // found. | |
174 void OnCharacteristicsFound(const RemoteAttribute& service, | |
175 const RemoteAttribute& tx_characteristic, | |
176 const RemoteAttribute& rx_characteristic); | |
177 | |
178 // Callback called there was an error finding the characteristics. | |
179 void OnCharacteristicsFinderError(const RemoteAttribute& tx_characteristic, | |
180 const RemoteAttribute& rx_characteristic); | |
181 | |
182 // Starts a notify session for |rx_characteristic_| when ready | |
183 // (SubStatus::CHARACTERISTICS_FOUND). | |
184 void StartNotifySession(); | |
185 | |
186 // Called when a notification session is successfully started for | |
187 // |rx_characteristic_| characteristic. | |
188 void OnNotifySessionStarted( | |
189 std::unique_ptr<device::BluetoothGattNotifySession> notify_session); | |
190 | |
191 // Called when there is an error starting a notification session for | |
192 // |rx_characteristic_| characteristic. | |
193 void OnNotifySessionError(device::BluetoothGattService::GattErrorCode); | |
194 | |
195 // Stops |notify_session_|. | |
196 void StopNotifySession(); | |
197 | |
198 // Sends a connection request to server if ready | |
199 // (SubStatus::NOTIFY_SESSION_READY). | |
200 void SendConnectionRequest(); | |
201 | |
202 // Completes and updates the status accordingly. | |
203 void CompleteConnection(); | |
204 | |
205 // This is the only entry point for WriteRequests, which are processed | |
206 // accordingly the following flow: | |
207 // 1) |request| is enqueued; | |
208 // 2) |request| will be processed by ProcessNextWriteRequest() when there is | |
209 // no pending write request; | |
210 // 3) |request| will be dequeued when it's successfully processed | |
211 // (OnRemoteCharacteristicWritten()); | |
212 // 4) |request| is not dequeued if it fails | |
213 // (OnWriteRemoteCharacteristicError()), it remains on the queue and will be | |
214 // retried. |request| will remain on the queue until it succeeds or it | |
215 // triggers a Disconnect() call (after |max_number_of_tries_|). | |
216 void WriteRemoteCharacteristic(const WriteRequest& request); | |
217 | |
218 // Processes the next request in |write_requests_queue_|. | |
219 void ProcessNextWriteRequest(); | |
220 | |
221 // Called when the | |
222 // BluetoothRemoteGattCharacteristic::RemoteCharacteristicWrite() is | |
223 // successfully complete. | |
224 void OnRemoteCharacteristicWritten(); | |
225 | |
226 // Called when there is an error writing to the remote characteristic | |
227 // |tx_characteristic_|. | |
228 void OnWriteRemoteCharacteristicError( | |
229 device::BluetoothRemoteGattService::GattErrorCode error); | |
230 | |
231 void OnPacketReceiverError(); | |
232 | |
233 // Prints the time elapsed since |Connect()| was called. | |
234 void PrintTimeElapsed(); | |
235 | |
236 // Returns the device corresponding to |remote_device_address_|. | |
237 device::BluetoothDevice* GetRemoteDevice(); | |
238 | |
239 // Returns the service corresponding to |remote_service_| in the current | |
240 // device. | |
241 device::BluetoothRemoteGattService* GetRemoteService(); | |
242 | |
243 // Returns the characteristic corresponding to |identifier| in the current | |
244 // service. | |
245 device::BluetoothRemoteGattCharacteristic* GetGattCharacteristic( | |
246 const std::string& identifier); | |
247 | |
248 // Get the reason that the other side of the connection decided to close the | |
249 // connection. | |
250 // Will crash if the receiver is not in CONNECTION_CLOSED state. | |
251 std::string GetReasonForClose(); | |
252 | |
253 // The Bluetooth adapter over which the Bluetooth connection will be made. | |
254 scoped_refptr<device::BluetoothAdapter> adapter_; | |
255 | |
256 // Remote service the |gatt_connection_| was established with. | |
257 RemoteAttribute remote_service_; | |
258 | |
259 // uWeave packet generator. | |
260 std::unique_ptr<BluetoothLowEnergyWeavePacketGenerator> packet_generator_; | |
261 | |
262 // uWeave packet receiver. | |
263 std::unique_ptr<BluetoothLowEnergyWeavePacketReceiver> packet_receiver_; | |
264 | |
265 // Characteristic used to send data to the remote device. | |
266 RemoteAttribute tx_characteristic_; | |
267 | |
268 // Characteristic used to receive data from the remote device. | |
269 RemoteAttribute rx_characteristic_; | |
270 | |
271 // Throttles repeated connection attempts to the same device. This is a | |
272 // workaround for crbug.com/508919. Not owned, must outlive this instance. | |
273 BluetoothThrottler* bluetooth_throttler_; | |
274 | |
275 scoped_refptr<base::TaskRunner> task_runner_; | |
276 | |
277 // The GATT connection with the remote device. | |
278 std::unique_ptr<device::BluetoothGattConnection> gatt_connection_; | |
279 | |
280 // The characteristics finder for remote device. | |
281 std::unique_ptr<BluetoothLowEnergyCharacteristicsFinder> | |
282 characteristic_finder_; | |
283 | |
284 // The notify session for |rx_characteristic|. | |
285 std::unique_ptr<device::BluetoothGattNotifySession> notify_session_; | |
286 | |
287 // Internal connection status | |
288 SubStatus sub_status_; | |
289 | |
290 // Bytes already received for the current receive operation. | |
291 std::string incoming_bytes_buffer_; | |
292 | |
293 // Indicates there is a | |
294 // BluetoothRemoteGattCharacteristic::WriteRemoteCharacteristic | |
295 // operation pending. | |
296 bool write_remote_characteristic_pending_; | |
297 | |
298 std::queue<WriteRequest> write_requests_queue_; | |
299 | |
300 // Maximum number of tries to send any write request. | |
301 int max_number_of_write_attempts_; | |
302 | |
303 // Stores when the instace was created. | |
304 base::TimeTicks start_time_; | |
305 | |
306 base::WeakPtrFactory<BluetoothLowEnergyWeaveClientConnection> | |
307 weak_ptr_factory_; | |
308 | |
309 DISALLOW_COPY_AND_ASSIGN(BluetoothLowEnergyWeaveClientConnection); | |
310 }; | |
311 | |
312 } // namespace weave | |
313 | |
314 } // namespace proximity_auth | |
315 | |
316 #endif // COMPONENTS_PROXIMITY_AUTH_BLE_BLUETOOTH_LOW_ENERGY_WEAVE_CLIENT_CONNE
CTION_H_ | |
OLD | NEW |