Connecting only to paired devices in BLE connection finder.
[chromium-blink-merge.git] / components / proximity_auth / ble / bluetooth_low_energy_connection.h
blob6b7a67aa84b8a72d3d9c16bcb2e51bf1f7d5bba3
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.
5 #ifndef COMPONENTS_PROXIMITY_AUTH_BLUETOOTH_LOW_ENERGY_CONNECTION_H
6 #define COMPONENTS_PROXIMITY_AUTH_BLUETOOTH_LOW_ENERGY_CONNECTION_H
8 #include <queue>
9 #include <string>
11 #include "base/macros.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/time/time.h"
16 #include "components/proximity_auth/ble/bluetooth_low_energy_characteristics_finder.h"
17 #include "components/proximity_auth/ble/fake_wire_message.h"
18 #include "components/proximity_auth/ble/remote_attribute.h"
19 #include "components/proximity_auth/connection.h"
20 #include "device/bluetooth/bluetooth_adapter.h"
21 #include "device/bluetooth/bluetooth_device.h"
22 #include "device/bluetooth/bluetooth_gatt_characteristic.h"
23 #include "device/bluetooth/bluetooth_gatt_notify_session.h"
24 #include "device/bluetooth/bluetooth_uuid.h"
26 namespace proximity_auth {
28 // Represents a connection with a remote device over Bluetooth low energy. The
29 // connection is a persistent bidirectional channel for sending and receiving
30 // wire messages. The remote device is the peripheral mode and the service
31 // contains two characteristics: one to send data and another to receive it.
33 // The connection flow is described below.
35 // Discover Reader and Writer Characteristics
36 // |
37 // |
38 // |
39 // Start Notify Session
40 // |
41 // |
42 // |
43 // Write kInviteToConnectSignal to Writer Characteristic
44 // |
45 // |
46 // |
47 // Read kInvitationResponseSignal from Reader Characteristic
48 // |
49 // |
50 // |
51 // Proximity Auth Connection Established
52 class BluetoothLowEnergyConnection : public Connection,
53 public device::BluetoothAdapter::Observer {
54 public:
55 // Signals sent to the remote device to indicate connection related events.
56 enum class ControlSignal : uint32 {
57 kInviteToConnectSignal = 0,
58 kInvitationResponseSignal = 1,
59 kSendSignal = 2,
60 kDisconnectSignal = 3,
63 // The sub-state of a proximity_auth::BluetoothLowEnergyConnection class
64 // extends the IN_PROGRESS state of proximity_auth::Connection::Status.
65 enum class SubStatus {
66 DISCONNECTED,
67 WAITING_GATT_CONNECTION,
68 GATT_CONNECTION_ESTABLISHED,
69 WAITING_CHARACTERISTICS,
70 CHARACTERISTICS_FOUND,
71 WAITING_NOTIFY_SESSION,
72 NOTIFY_SESSION_READY,
73 WAITING_RESPONSE_SIGNAL,
74 CONNECTED,
77 // Constructs a Bluetooth low energy connection to the service with
78 // |remote_service_| on the |remote_device|. The |adapter| must be already
79 // initaalized and ready. The GATT connection may alreaady be established and
80 // pass through |gatt_connection|. A subsequent call to Connect() must be
81 // made.
82 BluetoothLowEnergyConnection(
83 const RemoteDevice& remote_device,
84 scoped_refptr<device::BluetoothAdapter> adapter,
85 const device::BluetoothUUID remote_service_uuid,
86 const device::BluetoothUUID to_peripheral_char_uuid,
87 const device::BluetoothUUID from_peripheral_char_uuid,
88 scoped_ptr<device::BluetoothGattConnection> gatt_connection,
89 int max_number_of_write_attempts);
91 ~BluetoothLowEnergyConnection() override;
93 // proximity_auth::Connection
94 void Connect() override;
95 void Disconnect() override;
97 protected:
98 // Exposed for testing.
99 void SetSubStatus(SubStatus status);
100 SubStatus sub_status() { return sub_status_; }
102 // Virtual for testing.
103 virtual BluetoothLowEnergyCharacteristicsFinder* CreateCharacteristicsFinder(
104 const BluetoothLowEnergyCharacteristicsFinder::SuccessCallback&
105 success_callback,
106 const BluetoothLowEnergyCharacteristicsFinder::ErrorCallback&
107 error_callback);
109 // proximity_auth::Connection
110 void SendMessageImpl(scoped_ptr<WireMessage> message) override;
111 scoped_ptr<WireMessage> DeserializeWireMessage(
112 bool* is_incomplete_message) override;
114 // device::BluetoothAdapter::Observer
115 void DeviceRemoved(device::BluetoothAdapter* adapter,
116 device::BluetoothDevice* device) override;
117 void GattCharacteristicValueChanged(
118 device::BluetoothAdapter* adapter,
119 device::BluetoothGattCharacteristic* characteristic,
120 const std::vector<uint8>& value) override;
122 private:
123 // Represents a request to write |value| to a some characteristic.
124 // |is_last_write_for_wire_messsage| indicates whether this request
125 // corresponds to the last write request for some wire message.
126 // A WireMessage corresponds to exactly two WriteRequest: the first containing
127 // a kSendSignal + the size of the WireMessage, and the second containing a
128 // SendStatusSignal + the serialized WireMessage.
129 struct WriteRequest {
130 WriteRequest(const std::vector<uint8>& val, bool flag);
131 ~WriteRequest();
133 std::vector<uint8> value;
134 bool is_last_write_for_wire_message;
135 int number_of_failed_attempts;
138 // Called when the remote device is successfully disconnected.
139 void OnDisconnected();
141 // Called when there is an error disconnecting the remote device.
142 void OnDisconnectError();
144 // Called when a GATT connection is created or received by the constructor.
145 void OnGattConnectionCreated(
146 scoped_ptr<device::BluetoothGattConnection> gatt_connection);
148 // Callback called when there is an error creating the connection.
149 void OnCreateGattConnectionError(
150 device::BluetoothDevice::ConnectErrorCode error_code);
152 // Callback called when |to_peripheral_char_| and |from_peripheral_char_| were
153 // found.
154 void OnCharacteristicsFound(const RemoteAttribute& service,
155 const RemoteAttribute& to_peripheral_char,
156 const RemoteAttribute& from_peripheral_char);
158 // Callback called there was an error finding the characteristics.
159 void OnCharacteristicsFinderError(
160 const RemoteAttribute& to_peripheral_char,
161 const RemoteAttribute& from_peripheral_char);
163 // Starts a notify session for |from_peripheral_char_| when ready
164 // (SubStatus::CHARACTERISTICS_FOUND).
165 void StartNotifySession();
167 // Called when a notification session is successfully started for
168 // |from_peripheral_char_| characteristic.
169 void OnNotifySessionStarted(
170 scoped_ptr<device::BluetoothGattNotifySession> notify_session);
172 // Called when there is an error starting a notification session for
173 // |from_peripheral_char_| characteristic.
174 void OnNotifySessionError(device::BluetoothGattService::GattErrorCode);
176 // Stops |notify_session_|.
177 void StopNotifySession();
179 // Sends an invite to connect signal to the peripheral if when ready
180 // (SubStatus::NOTIFY_SESSION_READY).
181 void SendInviteToConnectSignal();
183 // Completes and updates the status accordingly.
184 void CompleteConnection();
186 // This is the only entry point for WriteRequests, which are processed
187 // accordingly the following flow:
188 // 1) |request| is enqueued;
189 // 2) |request| will be processed by ProcessNextWriteRequest() when there is
190 // no pending
191 // write request;
192 // 3) |request| will be dequeued when it's successfully processed
193 // (OnRemoteCharacteristicWritten());
194 // 4) |request| is not dequeued if it fails
195 // (OnWriteRemoteCharacteristicError()),
196 // it remains on the queue and will be retried.
197 // |request| will remain on the queue until it succeeds or it triggers a
198 // Disconnect() call (after |max_number_of_tries_|).
199 void WriteRemoteCharacteristic(WriteRequest request);
201 // Processes the next request in |write_requests_queue_|.
202 void ProcessNextWriteRequest();
204 // Called when the BluetoothGattCharacteristic::RemoteCharacteristicWrite() is
205 // sucessfully complete.
206 void OnRemoteCharacteristicWritten(bool run_did_send_message_callback);
208 // Called when there is an error writing to the remote characteristic
209 // |to_peripheral_char_|.
210 void OnWriteRemoteCharacteristicError(
211 bool run_did_send_message_callback,
212 device::BluetoothGattService::GattErrorCode error);
214 // Builds the value to be written on |to_peripheral_char_|. The value
215 // corresponds to |signal| concatenated with |payload|.
216 WriteRequest BuildWriteRequest(const std::vector<uint8>& signal,
217 const std::vector<uint8>& bytes,
218 bool is_last_message_for_wire_message);
220 // Clears |write_requests_queue_|.
221 void ClearWriteRequestsQueue();
223 // Returns the Bluetooth address of the remote device.
224 const std::string& GetRemoteDeviceAddress();
226 // Returns the device corresponding to |remote_device_address_|.
227 device::BluetoothDevice* GetRemoteDevice();
229 // Returns the service corresponding to |remote_service_| in the current
230 // device.
231 device::BluetoothGattService* GetRemoteService();
233 // Returns the characteristic corresponding to |identifier| in the current
234 // service.
235 device::BluetoothGattCharacteristic* GetGattCharacteristic(
236 const std::string& identifier);
238 // Convert the first 4 bytes from a byte vector to a uint32.
239 uint32 ToUint32(const std::vector<uint8>& bytes);
241 // Convert an uint32 to a byte vector.
242 const std::vector<uint8> ToByteVector(uint32 value);
244 // The Bluetooth adapter over which the Bluetooth connection will be made.
245 scoped_refptr<device::BluetoothAdapter> adapter_;
247 // Remote service the |connection_| was established with.
248 RemoteAttribute remote_service_;
250 // Characteristic used to send data to the remote device.
251 RemoteAttribute to_peripheral_char_;
253 // Characteristic used to receive data from the remote device.
254 RemoteAttribute from_peripheral_char_;
256 // The GATT connection with the remote device.
257 scoped_ptr<device::BluetoothGattConnection> connection_;
259 // The characteristics finder for remote device.
260 scoped_ptr<BluetoothLowEnergyCharacteristicsFinder> characteristic_finder_;
262 // The notify session for |from_peripheral_char|.
263 scoped_ptr<device::BluetoothGattNotifySession> notify_session_;
265 // Internal connection status
266 SubStatus sub_status_;
268 // Indicates a receiving operation is in progress. This is set after a
269 // ControlSignal::kSendSignal was received from the remote device.
270 bool receiving_bytes_;
272 // Total number of bytes expected for the current receive operation.
273 std::size_t expected_number_of_incoming_bytes_;
275 // Bytes already received for the current receive operation.
276 std::string incoming_bytes_buffer_;
278 // Indicates there is a BluetoothGattCharacteristic::WriteRemoteCharacteristic
279 // operation pending.
280 bool write_remote_characteristic_pending_;
282 std::queue<WriteRequest> write_requests_queue_;
284 // Maximum number of tries to send any write request.
285 int max_number_of_write_attempts_;
287 // Maximum number of bytes that fit in a single chunk to be written in
288 // |to_peripheral_char_|. Ideally, this should be the maximum value the
289 // peripheral supports and it should be agreed when the GATT connection is
290 // created. Currently, there is no API to find this value. The implementation
291 // uses a hard-coded constant.
292 int max_chunk_size_;
294 // Stores when the instace was created.
295 base::TimeTicks start_time_;
297 base::WeakPtrFactory<BluetoothLowEnergyConnection> weak_ptr_factory_;
299 DISALLOW_COPY_AND_ASSIGN(BluetoothLowEnergyConnection);
302 } // namespace proximity_auth
304 #endif // COMPONENTS_PROXIMITY_AUTH_BLUETOOTH_LOW_ENERGY_CONNECTION_H