OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/proximity_auth/ble/bluetooth_low_energy_connection.h" | 5 #include "components/proximity_auth/ble/bluetooth_low_energy_weave_client_connec tion.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
11 #include "base/memory/ref_counted.h" | |
12 #include "base/memory/weak_ptr.h" | |
13 #include "base/task_runner.h" | 11 #include "base/task_runner.h" |
14 #include "base/threading/thread_task_runner_handle.h" | 12 #include "base/threading/thread_task_runner_handle.h" |
15 #include "base/time/time.h" | |
16 #include "components/proximity_auth/ble/bluetooth_low_energy_characteristics_fin der.h" | |
17 #include "components/proximity_auth/ble/fake_wire_message.h" | |
18 #include "components/proximity_auth/bluetooth_throttler.h" | 13 #include "components/proximity_auth/bluetooth_throttler.h" |
19 #include "components/proximity_auth/connection_finder.h" | 14 #include "components/proximity_auth/connection_finder.h" |
20 #include "components/proximity_auth/logging/logging.h" | 15 #include "components/proximity_auth/logging/logging.h" |
21 #include "components/proximity_auth/wire_message.h" | 16 #include "components/proximity_auth/wire_message.h" |
22 #include "device/bluetooth/bluetooth_adapter.h" | |
23 #include "device/bluetooth/bluetooth_device.h" | |
24 #include "device/bluetooth/bluetooth_gatt_connection.h" | 17 #include "device/bluetooth/bluetooth_gatt_connection.h" |
25 #include "device/bluetooth/bluetooth_gatt_notify_session.h" | |
26 #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h" | |
27 #include "device/bluetooth/bluetooth_uuid.h" | |
28 | 18 |
29 using device::BluetoothAdapter; | 19 using device::BluetoothAdapter; |
30 using device::BluetoothDevice; | 20 using device::BluetoothDevice; |
31 using device::BluetoothGattConnection; | 21 using device::BluetoothGattConnection; |
32 using device::BluetoothRemoteGattService; | 22 using device::BluetoothRemoteGattService; |
33 using device::BluetoothRemoteGattCharacteristic; | 23 using device::BluetoothRemoteGattCharacteristic; |
34 using device::BluetoothGattNotifySession; | 24 using device::BluetoothGattNotifySession; |
35 using device::BluetoothUUID; | 25 using device::BluetoothUUID; |
36 | 26 |
37 namespace proximity_auth { | 27 namespace proximity_auth { |
28 namespace weave { | |
38 namespace { | 29 namespace { |
39 | 30 |
40 // The UUID of the characteristic used to send data to the peripheral. | 31 typedef BluetoothLowEnergyWeavePacketReceiver::State ReceiverState; |
41 const char kToPeripheralCharUUID[] = "977c6674-1239-4e72-993b-502369b8bb5a"; | |
42 | 32 |
43 // The UUID of the characteristic used to receive data from the peripheral. | 33 // The UUID of the TX characteristic used to transmit data to the server. |
44 const char kFromPeripheralCharUUID[] = "f4b904a2-a030-43b3-98a8-221c536c03cb"; | 34 const char kTXCharacteristicUUID[] = "00000100-0004-1000-8000-001A11000101"; |
45 | 35 |
46 // Deprecated signal send as the first byte in send byte operations. | 36 // The UUID of the RX characteristic used to receive data from the server. |
47 const int kFirstByteZero = 0; | 37 const char kRXCharacteristicUUID[] = "00000100-0004-1000-8000-001A11000102"; |
48 | 38 |
49 // The maximum number of bytes written in a remote characteristic with a single | |
50 // write request. This is not the connection MTU, we are assuming that the | |
51 // remote device allows for writes larger than MTU. | |
52 const int kMaxChunkSize = 500; | |
53 } // namespace | 39 } // namespace |
54 | 40 |
55 BluetoothLowEnergyConnection::BluetoothLowEnergyConnection( | 41 BluetoothLowEnergyWeaveClientConnection:: |
56 const RemoteDevice& device, | 42 BluetoothLowEnergyWeaveClientConnection( |
57 scoped_refptr<device::BluetoothAdapter> adapter, | 43 const RemoteDevice& device, |
58 const BluetoothUUID remote_service_uuid, | 44 scoped_refptr<device::BluetoothAdapter> adapter, |
59 BluetoothThrottler* bluetooth_throttler, | 45 const BluetoothUUID remote_service_uuid, |
60 int max_number_of_write_attempts) | 46 BluetoothThrottler* bluetooth_throttler, |
47 int max_number_of_write_attempts) | |
61 : Connection(device), | 48 : Connection(device), |
62 adapter_(adapter), | 49 adapter_(adapter), |
63 remote_service_({remote_service_uuid, ""}), | 50 remote_service_({remote_service_uuid, ""}), |
64 to_peripheral_char_({BluetoothUUID(kToPeripheralCharUUID), ""}), | 51 packet_generator_( |
65 from_peripheral_char_({BluetoothUUID(kFromPeripheralCharUUID), ""}), | 52 BluetoothLowEnergyWeavePacketGenerator::Factory::NewInstance()), |
53 packet_receiver_( | |
54 BluetoothLowEnergyWeavePacketReceiver::Factory::NewInstance( | |
55 BluetoothLowEnergyWeavePacketReceiver::ReceiverType::CLIENT)), | |
56 tx_characteristic_({BluetoothUUID(kTXCharacteristicUUID), ""}), | |
57 rx_characteristic_({BluetoothUUID(kRXCharacteristicUUID), ""}), | |
66 bluetooth_throttler_(bluetooth_throttler), | 58 bluetooth_throttler_(bluetooth_throttler), |
67 task_runner_(base::ThreadTaskRunnerHandle::Get()), | 59 task_runner_(base::ThreadTaskRunnerHandle::Get()), |
68 sub_status_(SubStatus::DISCONNECTED), | 60 sub_status_(SubStatus::DISCONNECTED), |
69 receiving_bytes_(false), | |
70 write_remote_characteristic_pending_(false), | 61 write_remote_characteristic_pending_(false), |
71 max_number_of_write_attempts_(max_number_of_write_attempts), | 62 max_number_of_write_attempts_(max_number_of_write_attempts), |
72 max_chunk_size_(kMaxChunkSize), | |
73 weak_ptr_factory_(this) { | 63 weak_ptr_factory_(this) { |
74 DCHECK(adapter_); | 64 DCHECK(adapter_); |
75 DCHECK(adapter_->IsInitialized()); | 65 DCHECK(adapter_->IsInitialized()); |
76 | 66 |
77 adapter_->AddObserver(this); | 67 adapter_->AddObserver(this); |
78 } | 68 } |
79 | 69 |
80 BluetoothLowEnergyConnection::~BluetoothLowEnergyConnection() { | 70 BluetoothLowEnergyWeaveClientConnection:: |
71 ~BluetoothLowEnergyWeaveClientConnection() { | |
81 Disconnect(); | 72 Disconnect(); |
82 if (adapter_) { | 73 if (adapter_) { |
83 adapter_->RemoveObserver(this); | 74 adapter_->RemoveObserver(this); |
84 adapter_ = NULL; | 75 adapter_ = NULL; |
85 } | 76 } |
86 } | 77 } |
87 | 78 |
88 void BluetoothLowEnergyConnection::Connect() { | 79 void BluetoothLowEnergyWeaveClientConnection::Connect() { |
89 DCHECK(sub_status() == SubStatus::DISCONNECTED); | 80 DCHECK(sub_status() == SubStatus::DISCONNECTED); |
90 | 81 |
91 SetSubStatus(SubStatus::WAITING_GATT_CONNECTION); | 82 SetSubStatus(SubStatus::WAITING_GATT_CONNECTION); |
92 base::TimeDelta throttler_delay = bluetooth_throttler_->GetDelay(); | 83 base::TimeDelta throttler_delay = bluetooth_throttler_->GetDelay(); |
93 PA_LOG(INFO) << "Connecting in " << throttler_delay; | 84 PA_LOG(INFO) << "Connecting in " << throttler_delay; |
94 | 85 |
95 start_time_ = base::TimeTicks::Now(); | 86 start_time_ = base::TimeTicks::Now(); |
96 | 87 |
97 // If necessary, wait to create a new GATT connection. | 88 // If necessary, wait to create a new GATT connection. |
98 // | 89 // |
99 // Avoid creating a new GATT connection immediately after a given device was | 90 // Avoid creating a new GATT connection immediately after a given device was |
100 // disconnected. This is a workaround for crbug.com/508919. | 91 // disconnected. This is a workaround for crbug.com/508919. |
101 if (!throttler_delay.is_zero()) { | 92 if (!throttler_delay.is_zero()) { |
102 task_runner_->PostDelayedTask( | 93 task_runner_->PostDelayedTask( |
103 FROM_HERE, | 94 FROM_HERE, |
104 base::Bind(&BluetoothLowEnergyConnection::CreateGattConnection, | 95 base::Bind( |
105 weak_ptr_factory_.GetWeakPtr()), | 96 &BluetoothLowEnergyWeaveClientConnection::CreateGattConnection, |
97 weak_ptr_factory_.GetWeakPtr()), | |
106 throttler_delay); | 98 throttler_delay); |
107 return; | 99 return; |
108 } | 100 } |
109 | 101 |
110 CreateGattConnection(); | 102 CreateGattConnection(); |
111 } | 103 } |
112 | 104 |
113 void BluetoothLowEnergyConnection::CreateGattConnection() { | 105 void BluetoothLowEnergyWeaveClientConnection::CreateGattConnection() { |
114 DCHECK(sub_status() == SubStatus::WAITING_GATT_CONNECTION); | 106 DCHECK(sub_status() == SubStatus::WAITING_GATT_CONNECTION); |
115 | 107 |
116 BluetoothDevice* remote_device = GetRemoteDevice(); | 108 BluetoothDevice* remote_device = GetRemoteDevice(); |
117 if (remote_device) { | 109 if (remote_device) { |
118 PA_LOG(INFO) << "Creating GATT connection with " | 110 PA_LOG(INFO) << "Creating GATT connection with " |
119 << remote_device->GetAddress(); | 111 << remote_device->GetAddress(); |
120 | 112 |
121 remote_device->CreateGattConnection( | 113 remote_device->CreateGattConnection( |
122 base::Bind(&BluetoothLowEnergyConnection::OnGattConnectionCreated, | 114 base::Bind( |
123 weak_ptr_factory_.GetWeakPtr()), | 115 &BluetoothLowEnergyWeaveClientConnection::OnGattConnectionCreated, |
124 base::Bind(&BluetoothLowEnergyConnection::OnCreateGattConnectionError, | 116 weak_ptr_factory_.GetWeakPtr()), |
117 base::Bind(&BluetoothLowEnergyWeaveClientConnection:: | |
118 OnCreateGattConnectionError, | |
125 weak_ptr_factory_.GetWeakPtr())); | 119 weak_ptr_factory_.GetWeakPtr())); |
126 } | 120 } |
127 } | 121 } |
128 | 122 |
129 void BluetoothLowEnergyConnection::Disconnect() { | 123 void BluetoothLowEnergyWeaveClientConnection::Disconnect() { |
130 if (sub_status() != SubStatus::DISCONNECTED) { | 124 if (sub_status() != SubStatus::DISCONNECTED) { |
131 weak_ptr_factory_.InvalidateWeakPtrs(); | 125 weak_ptr_factory_.InvalidateWeakPtrs(); |
132 StopNotifySession(); | 126 StopNotifySession(); |
133 characteristic_finder_.reset(); | 127 characteristic_finder_.reset(); |
134 if (gatt_connection_) { | 128 if (gatt_connection_) { |
135 PA_LOG(INFO) << "Disconnect from device " | 129 PA_LOG(INFO) << "Disconnect from device " |
136 << gatt_connection_->GetDeviceAddress(); | 130 << gatt_connection_->GetDeviceAddress(); |
137 | 131 |
138 // Destroying BluetoothGattConnection also disconnects it. | 132 // Destroying BluetoothGattConnection also disconnects it. |
139 gatt_connection_.reset(); | 133 gatt_connection_.reset(); |
140 } | 134 } |
141 | 135 |
142 // Only transition to the DISCONNECTED state after perfoming all necessary | 136 // Only transition to the DISCONNECTED state after perfoming all necessary |
143 // operations. Otherwise, it'll trigger observers that can pontentially | 137 // operations. Otherwise, it'll trigger observers that can pontentially |
144 // destroy the current instance (causing a crash). | 138 // destroy the current instance (causing a crash). |
145 SetSubStatus(SubStatus::DISCONNECTED); | 139 SetSubStatus(SubStatus::DISCONNECTED); |
146 } | 140 } |
147 } | 141 } |
148 | 142 |
149 void BluetoothLowEnergyConnection::SetSubStatus(SubStatus new_sub_status) { | 143 void BluetoothLowEnergyWeaveClientConnection::SetSubStatus( |
144 SubStatus new_sub_status) { | |
150 sub_status_ = new_sub_status; | 145 sub_status_ = new_sub_status; |
151 | 146 |
152 // Sets the status of parent class proximity_auth::Connection accordingly. | 147 // Sets the status of parent class proximity_auth::Connection accordingly. |
153 if (new_sub_status == SubStatus::CONNECTED) { | 148 if (new_sub_status == SubStatus::CONNECTED) { |
154 SetStatus(CONNECTED); | 149 SetStatus(Status::CONNECTED); |
155 } else if (new_sub_status == SubStatus::DISCONNECTED) { | 150 } else if (new_sub_status == SubStatus::DISCONNECTED) { |
156 SetStatus(DISCONNECTED); | 151 SetStatus(Status::DISCONNECTED); |
157 } else { | 152 } else { |
158 SetStatus(IN_PROGRESS); | 153 SetStatus(Status::IN_PROGRESS); |
159 } | 154 } |
160 } | 155 } |
161 | 156 |
162 void BluetoothLowEnergyConnection::SetTaskRunnerForTesting( | 157 void BluetoothLowEnergyWeaveClientConnection::SetTaskRunnerForTesting( |
163 scoped_refptr<base::TaskRunner> task_runner) { | 158 scoped_refptr<base::TaskRunner> task_runner) { |
164 task_runner_ = task_runner; | 159 task_runner_ = task_runner; |
165 } | 160 } |
166 | 161 |
167 void BluetoothLowEnergyConnection::SendMessageImpl( | 162 void BluetoothLowEnergyWeaveClientConnection::SendMessageImpl( |
168 std::unique_ptr<WireMessage> message) { | 163 std::unique_ptr<WireMessage> message) { |
169 PA_LOG(INFO) << "Sending message " << message->Serialize(); | 164 PA_LOG(INFO) << "Sending message " << message->Serialize(); |
170 std::string serialized_msg = message->Serialize(); | 165 std::string serialized_msg = message->Serialize(); |
171 | 166 |
172 // [First write]: Build a header with the [send signal] + [size of the | 167 std::vector<Packet> packets = |
173 // message]. | 168 packet_generator_->EncodeDataMessage(serialized_msg); |
174 WriteRequest write_request = BuildWriteRequest( | |
175 ToByteVector(static_cast<uint32_t>(ControlSignal::kSendSignal)), | |
176 ToByteVector(static_cast<uint32_t>(serialized_msg.size())), false); | |
177 | 169 |
178 // [First write]: Fill the it with a prefix of |serialized_msg| up to | 170 for (uint32_t i = 0; i < packets.size(); ++i) { |
179 // |max_chunk_size_|. | 171 WriteRequest request = WriteRequest(packets[i], i == packets.size() - 1); |
180 size_t first_chunk_size = std::min( | 172 WriteRemoteCharacteristic(request); |
181 max_chunk_size_ - write_request.value.size(), serialized_msg.size()); | |
182 std::vector<uint8_t> bytes(serialized_msg.begin(), | |
183 serialized_msg.begin() + first_chunk_size); | |
184 write_request.value.insert(write_request.value.end(), bytes.begin(), | |
185 bytes.end()); | |
186 | |
187 bool is_last_write_request = first_chunk_size == serialized_msg.size(); | |
188 write_request.is_last_write_for_wire_message = is_last_write_request; | |
189 WriteRemoteCharacteristic(write_request); | |
190 if (is_last_write_request) | |
191 return; | |
192 | |
193 // [Other write requests]: Each chunk has to include a deprecated signal: | |
194 // |kFirstByteZero| as the first byte. | |
195 int chunk_size = max_chunk_size_ - 1; | |
196 std::vector<uint8_t> kFirstByteZeroVector; | |
197 kFirstByteZeroVector.push_back(static_cast<uint8_t>(kFirstByteZero)); | |
198 | |
199 int message_size = static_cast<int>(serialized_msg.size()); | |
200 int start_index = first_chunk_size; | |
201 while (start_index < message_size) { | |
202 int end_index = (start_index + chunk_size) <= message_size | |
203 ? (start_index + chunk_size) | |
204 : message_size; | |
205 bool is_last_write_request = (end_index == message_size); | |
206 write_request = BuildWriteRequest( | |
207 kFirstByteZeroVector, | |
208 std::vector<uint8_t>(serialized_msg.begin() + start_index, | |
209 serialized_msg.begin() + end_index), | |
210 is_last_write_request); | |
211 WriteRemoteCharacteristic(write_request); | |
212 start_index = end_index; | |
213 } | 173 } |
214 } | 174 } |
215 | 175 |
216 // Changes in the GATT connection with the remote device should be observed | 176 // Changes in the GATT connection with the remote device should be observed |
217 // here. If the GATT connection is dropped, we should call Disconnect() anyway, | 177 // here. If the GATT connection is dropped, we should call Disconnect() anyway, |
218 // so the object can notify its observers. | 178 // so the object can notify its observers. |
219 void BluetoothLowEnergyConnection::DeviceChanged(BluetoothAdapter* adapter, | 179 void BluetoothLowEnergyWeaveClientConnection::DeviceChanged( |
220 BluetoothDevice* device) { | 180 BluetoothAdapter* adapter, |
181 BluetoothDevice* device) { | |
221 DCHECK(device); | 182 DCHECK(device); |
222 if (sub_status() == SubStatus::DISCONNECTED || | 183 if (sub_status() == SubStatus::DISCONNECTED || |
223 device->GetAddress() != GetDeviceAddress()) | 184 device->GetAddress() != GetDeviceAddress()) |
224 return; | 185 return; |
225 | 186 |
226 if (sub_status() != SubStatus::WAITING_GATT_CONNECTION && | 187 if (sub_status() != SubStatus::WAITING_GATT_CONNECTION && |
227 !device->IsConnected()) { | 188 !device->IsConnected()) { |
228 PA_LOG(INFO) << "GATT connection dropped " << GetDeviceAddress() | 189 PA_LOG(INFO) << "GATT connection dropped " << GetDeviceAddress() |
229 << "\ndevice connected: " << device->IsConnected() | 190 << "\ndevice connected: " << device->IsConnected() |
230 << "\ngatt connection: " | 191 << "\ngatt connection: " |
231 << (gatt_connection_ ? gatt_connection_->IsConnected() | 192 << (gatt_connection_ ? gatt_connection_->IsConnected() |
232 : false); | 193 : false); |
233 Disconnect(); | 194 Disconnect(); |
234 } | 195 } |
235 } | 196 } |
236 | 197 |
237 void BluetoothLowEnergyConnection::DeviceRemoved(BluetoothAdapter* adapter, | 198 void BluetoothLowEnergyWeaveClientConnection::DeviceRemoved( |
238 BluetoothDevice* device) { | 199 BluetoothAdapter* adapter, |
200 BluetoothDevice* device) { | |
239 DCHECK(device); | 201 DCHECK(device); |
240 if (sub_status_ == SubStatus::DISCONNECTED || | 202 if (sub_status_ == SubStatus::DISCONNECTED || |
241 device->GetAddress() != GetDeviceAddress()) | 203 device->GetAddress() != GetDeviceAddress()) |
242 return; | 204 return; |
243 | 205 |
244 PA_LOG(INFO) << "Device removed " << GetDeviceAddress(); | 206 PA_LOG(INFO) << "Device removed " << GetDeviceAddress(); |
245 Disconnect(); | 207 Disconnect(); |
246 } | 208 } |
247 | 209 |
248 void BluetoothLowEnergyConnection::GattCharacteristicValueChanged( | 210 void BluetoothLowEnergyWeaveClientConnection::GattCharacteristicValueChanged( |
249 BluetoothAdapter* adapter, | 211 BluetoothAdapter* adapter, |
250 BluetoothRemoteGattCharacteristic* characteristic, | 212 BluetoothRemoteGattCharacteristic* characteristic, |
251 const std::vector<uint8_t>& value) { | 213 const Packet& value) { |
252 DCHECK_EQ(adapter, adapter_.get()); | 214 DCHECK_EQ(adapter, adapter_.get()); |
253 if (sub_status() != SubStatus::WAITING_RESPONSE_SIGNAL && | 215 if (sub_status() != SubStatus::WAITING_CONNECTION_RESPONSE && |
254 sub_status() != SubStatus::CONNECTED) | 216 sub_status() != SubStatus::CONNECTED) |
255 return; | 217 return; |
256 | 218 |
257 PA_LOG(INFO) << "Characteristic value changed: " | 219 PA_LOG(INFO) << "Characteristic value changed: " |
258 << characteristic->GetUUID().canonical_value(); | 220 << characteristic->GetUUID().canonical_value(); |
259 | 221 |
260 if (characteristic->GetIdentifier() == from_peripheral_char_.id) { | 222 if (characteristic->GetIdentifier() == rx_characteristic_.id) { |
261 if (receiving_bytes_) { | 223 ReceiverState state = packet_receiver_->ReceivePacket(value); |
262 // Ignoring the first byte, as it contains a deprecated signal. | 224 PA_LOG(INFO) << "\nReceiver State: " << state; |
263 const std::string bytes(value.begin() + 1, value.end()); | 225 switch (state) { |
264 incoming_bytes_buffer_.append(bytes); | 226 case ReceiverState::DATA_READY: |
265 if (incoming_bytes_buffer_.size() >= expected_number_of_incoming_bytes_) { | 227 OnBytesReceived(packet_receiver_->GetDataMessage()); |
266 OnBytesReceived(incoming_bytes_buffer_); | 228 break; |
267 receiving_bytes_ = false; | 229 case ReceiverState::CONNECTION_CLOSED: |
268 } | 230 PA_LOG(ERROR) << "Connection closed due to: " |
269 return; | 231 << packet_receiver_->GetReasonForClose(); |
270 } | 232 Disconnect(); |
271 | 233 break; |
272 if (value.size() < 4) { | 234 case ReceiverState::ERROR_DETECTED: |
273 PA_LOG(WARNING) << "Incoming data corrupted, no signal found."; | 235 // TODO(jingxuy): test this once the design has been confirmed |
274 return; | 236 WriteConnectionClose(packet_generator_->CreateConnectionClose( |
275 } | 237 packet_receiver_->GetReasonToClose())); |
276 | 238 Disconnect(); |
277 const ControlSignal signal = static_cast<ControlSignal>(ToUint32(value)); | 239 break; |
278 switch (signal) { | 240 case ReceiverState::WAITING: |
279 case ControlSignal::kInvitationResponseSignal: | 241 // Receiver state should have changed from CONNECTING to WAITING if |
280 if (sub_status() == SubStatus::WAITING_RESPONSE_SIGNAL) | 242 // a proper connection response had been received. |
243 // The max packet size selected from the connection response will be | |
244 // used to generate future data packets. | |
245 packet_generator_->SetMaxPacketSize( | |
246 packet_receiver_->GetMaxPacketSize()); | |
247 if (sub_status() == SubStatus::WAITING_CONNECTION_RESPONSE) | |
Kyle Horimoto
2016/06/30 01:29:48
Should this be an assertion? Is there ever a valid
jingxuy
2016/06/30 21:59:25
Done.
| |
281 CompleteConnection(); | 248 CompleteConnection(); |
282 break; | 249 break; |
283 case ControlSignal::kInviteToConnectSignal: | 250 case ReceiverState::RECEIVING_DATA: |
251 // Normal in between states, so do nothing. | |
284 break; | 252 break; |
285 case ControlSignal::kSendSignal: { | 253 default: |
286 if (value.size() < 8) { | 254 NOTREACHED(); |
287 PA_LOG(WARNING) | |
288 << "Incoming data corrupted, expected message size not found."; | |
289 return; | |
290 } | |
291 std::vector<uint8_t> size(value.begin() + 4, value.begin() + 8); | |
292 expected_number_of_incoming_bytes_ = | |
293 static_cast<size_t>(ToUint32(size)); | |
294 receiving_bytes_ = true; | |
295 incoming_bytes_buffer_.clear(); | |
296 | |
297 const std::string bytes(value.begin() + 8, value.end()); | |
298 incoming_bytes_buffer_.append(bytes); | |
299 if (incoming_bytes_buffer_.size() >= | |
300 expected_number_of_incoming_bytes_) { | |
301 OnBytesReceived(incoming_bytes_buffer_); | |
302 receiving_bytes_ = false; | |
303 } | |
304 break; | |
305 } | |
306 case ControlSignal::kDisconnectSignal: | |
307 PA_LOG(INFO) << "Disconnect signal received."; | |
308 Disconnect(); | |
309 break; | |
310 } | 255 } |
311 } | 256 } |
312 } | 257 } |
313 | 258 |
314 BluetoothLowEnergyConnection::WriteRequest::WriteRequest( | 259 BluetoothLowEnergyWeaveClientConnection::WriteRequest::WriteRequest( |
315 const std::vector<uint8_t>& val, | 260 const Packet& val, |
316 bool flag) | 261 bool flag) |
317 : value(val), | 262 : value(val), |
318 is_last_write_for_wire_message(flag), | 263 is_last_write_for_wire_message(flag), |
319 number_of_failed_attempts(0) {} | 264 number_of_failed_attempts(0) {} |
320 | 265 |
321 BluetoothLowEnergyConnection::WriteRequest::WriteRequest( | 266 BluetoothLowEnergyWeaveClientConnection::WriteRequest::WriteRequest( |
322 const WriteRequest& other) = default; | 267 const WriteRequest& other) = default; |
323 | 268 |
324 BluetoothLowEnergyConnection::WriteRequest::~WriteRequest() {} | 269 BluetoothLowEnergyWeaveClientConnection::WriteRequest::~WriteRequest() {} |
325 | 270 |
326 void BluetoothLowEnergyConnection::CompleteConnection() { | 271 void BluetoothLowEnergyWeaveClientConnection::CompleteConnection() { |
327 PA_LOG(INFO) << "Connection completed. Time elapsed: " | 272 PA_LOG(INFO) << "Connection completed. Time elapsed: " |
328 << base::TimeTicks::Now() - start_time_; | 273 << base::TimeTicks::Now() - start_time_; |
329 SetSubStatus(SubStatus::CONNECTED); | 274 SetSubStatus(SubStatus::CONNECTED); |
330 } | 275 } |
331 | 276 |
332 void BluetoothLowEnergyConnection::OnCreateGattConnectionError( | 277 void BluetoothLowEnergyWeaveClientConnection::OnCreateGattConnectionError( |
333 device::BluetoothDevice::ConnectErrorCode error_code) { | 278 device::BluetoothDevice::ConnectErrorCode error_code) { |
334 DCHECK(sub_status_ == SubStatus::WAITING_GATT_CONNECTION); | 279 DCHECK(sub_status_ == SubStatus::WAITING_GATT_CONNECTION); |
335 PA_LOG(WARNING) << "Error creating GATT connection to " | 280 PA_LOG(WARNING) << "Error creating GATT connection to " |
336 << remote_device().bluetooth_address | 281 << remote_device().bluetooth_address |
337 << "error code: " << error_code; | 282 << "error code: " << error_code; |
338 Disconnect(); | 283 Disconnect(); |
339 } | 284 } |
340 | 285 |
341 void BluetoothLowEnergyConnection::OnGattConnectionCreated( | 286 void BluetoothLowEnergyWeaveClientConnection::OnGattConnectionCreated( |
342 std::unique_ptr<device::BluetoothGattConnection> gatt_connection) { | 287 std::unique_ptr<device::BluetoothGattConnection> gatt_connection) { |
343 DCHECK(sub_status() == SubStatus::WAITING_GATT_CONNECTION); | 288 DCHECK(sub_status() == SubStatus::WAITING_GATT_CONNECTION); |
344 PA_LOG(INFO) << "GATT connection with " << gatt_connection->GetDeviceAddress() | 289 PA_LOG(INFO) << "GATT connection with " << gatt_connection->GetDeviceAddress() |
345 << " created."; | 290 << " created."; |
346 PrintTimeElapsed(); | 291 PrintTimeElapsed(); |
347 | 292 |
348 // Informing |bluetooth_trottler_| a new connection was established. | 293 // Informing |bluetooth_trottler_| a new connection was established. |
349 bluetooth_throttler_->OnConnection(this); | 294 bluetooth_throttler_->OnConnection(this); |
350 | 295 |
351 gatt_connection_ = std::move(gatt_connection); | 296 gatt_connection_ = std::move(gatt_connection); |
352 SetSubStatus(SubStatus::WAITING_CHARACTERISTICS); | 297 SetSubStatus(SubStatus::WAITING_CHARACTERISTICS); |
353 characteristic_finder_.reset(CreateCharacteristicsFinder( | 298 characteristic_finder_.reset(CreateCharacteristicsFinder( |
354 base::Bind(&BluetoothLowEnergyConnection::OnCharacteristicsFound, | 299 base::Bind( |
355 weak_ptr_factory_.GetWeakPtr()), | 300 &BluetoothLowEnergyWeaveClientConnection::OnCharacteristicsFound, |
356 base::Bind(&BluetoothLowEnergyConnection::OnCharacteristicsFinderError, | 301 weak_ptr_factory_.GetWeakPtr()), |
302 base::Bind(&BluetoothLowEnergyWeaveClientConnection:: | |
303 OnCharacteristicsFinderError, | |
357 weak_ptr_factory_.GetWeakPtr()))); | 304 weak_ptr_factory_.GetWeakPtr()))); |
358 } | 305 } |
359 | 306 |
360 BluetoothLowEnergyCharacteristicsFinder* | 307 BluetoothLowEnergyCharacteristicsFinder* |
361 BluetoothLowEnergyConnection::CreateCharacteristicsFinder( | 308 BluetoothLowEnergyWeaveClientConnection::CreateCharacteristicsFinder( |
362 const BluetoothLowEnergyCharacteristicsFinder::SuccessCallback& | 309 const BluetoothLowEnergyCharacteristicsFinder::SuccessCallback& |
363 success_callback, | 310 success_callback, |
364 const BluetoothLowEnergyCharacteristicsFinder::ErrorCallback& | 311 const BluetoothLowEnergyCharacteristicsFinder::ErrorCallback& |
365 error_callback) { | 312 error_callback) { |
366 return new BluetoothLowEnergyCharacteristicsFinder( | 313 return new BluetoothLowEnergyCharacteristicsFinder( |
367 adapter_, GetRemoteDevice(), remote_service_, to_peripheral_char_, | 314 adapter_, GetRemoteDevice(), remote_service_, tx_characteristic_, |
368 from_peripheral_char_, success_callback, error_callback); | 315 rx_characteristic_, success_callback, error_callback); |
369 } | 316 } |
370 | 317 |
371 void BluetoothLowEnergyConnection::OnCharacteristicsFound( | 318 void BluetoothLowEnergyWeaveClientConnection::OnCharacteristicsFound( |
372 const RemoteAttribute& service, | 319 const RemoteAttribute& service, |
373 const RemoteAttribute& to_peripheral_char, | 320 const RemoteAttribute& tx_characteristic, |
374 const RemoteAttribute& from_peripheral_char) { | 321 const RemoteAttribute& rx_characteristic) { |
375 PA_LOG(INFO) << "Remote chacteristics found."; | 322 PA_LOG(INFO) << "Remote chacteristics found."; |
376 PrintTimeElapsed(); | 323 PrintTimeElapsed(); |
377 | 324 |
378 DCHECK(sub_status() == SubStatus::WAITING_CHARACTERISTICS); | 325 DCHECK(sub_status() == SubStatus::WAITING_CHARACTERISTICS); |
379 remote_service_ = service; | 326 remote_service_ = service; |
380 to_peripheral_char_ = to_peripheral_char; | 327 tx_characteristic_ = tx_characteristic; |
381 from_peripheral_char_ = from_peripheral_char; | 328 rx_characteristic_ = rx_characteristic; |
382 | 329 |
383 SetSubStatus(SubStatus::CHARACTERISTICS_FOUND); | 330 SetSubStatus(SubStatus::CHARACTERISTICS_FOUND); |
384 StartNotifySession(); | 331 StartNotifySession(); |
385 } | 332 } |
386 | 333 |
387 void BluetoothLowEnergyConnection::OnCharacteristicsFinderError( | 334 void BluetoothLowEnergyWeaveClientConnection::OnCharacteristicsFinderError( |
388 const RemoteAttribute& to_peripheral_char, | 335 const RemoteAttribute& tx_characteristic, |
389 const RemoteAttribute& from_peripheral_char) { | 336 const RemoteAttribute& rx_characteristic) { |
390 DCHECK(sub_status() == SubStatus::WAITING_CHARACTERISTICS); | 337 DCHECK(sub_status() == SubStatus::WAITING_CHARACTERISTICS); |
391 PA_LOG(WARNING) << "Connection error, missing characteristics for SmartLock " | 338 PA_LOG(WARNING) << "Connection error, missing characteristics for SmartLock " |
392 "service.\n" | 339 "service.\n" |
393 << (to_peripheral_char.id.empty() | 340 << (tx_characteristic.id.empty() |
394 ? to_peripheral_char.uuid.canonical_value() | 341 ? tx_characteristic.uuid.canonical_value() |
395 : "") | 342 : "") |
396 << (from_peripheral_char.id.empty() | 343 << (rx_characteristic.id.empty() |
397 ? ", " + from_peripheral_char.uuid.canonical_value() | 344 ? ", " + rx_characteristic.uuid.canonical_value() |
398 : "") << " not found."; | 345 : "") |
346 << " not found."; | |
399 | 347 |
400 Disconnect(); | 348 Disconnect(); |
401 } | 349 } |
402 | 350 |
403 void BluetoothLowEnergyConnection::StartNotifySession() { | 351 void BluetoothLowEnergyWeaveClientConnection::StartNotifySession() { |
404 if (sub_status() == SubStatus::CHARACTERISTICS_FOUND) { | 352 if (sub_status() == SubStatus::CHARACTERISTICS_FOUND) { |
405 BluetoothRemoteGattCharacteristic* characteristic = | 353 BluetoothRemoteGattCharacteristic* characteristic = |
406 GetGattCharacteristic(from_peripheral_char_.id); | 354 GetGattCharacteristic(rx_characteristic_.id); |
407 DCHECK(characteristic); | 355 DCHECK(characteristic); |
408 | 356 |
409 // This is a workaround for crbug.com/507325. If |characteristic| is already | 357 // This is a workaround for crbug.com/507325. If |characteristic| is already |
410 // notifying |characteristic->StartNotifySession()| will fail with | 358 // notifying |characteristic->StartNotifySession()| will fail with |
411 // GATT_ERROR_FAILED. | 359 // GATT_ERROR_FAILED. |
412 if (characteristic->IsNotifying()) { | 360 if (characteristic->IsNotifying()) { |
413 PA_LOG(INFO) << characteristic->GetUUID().canonical_value() | 361 PA_LOG(INFO) << characteristic->GetUUID().canonical_value() |
414 << " already notifying."; | 362 << " already notifying."; |
415 SetSubStatus(SubStatus::NOTIFY_SESSION_READY); | 363 SetSubStatus(SubStatus::NOTIFY_SESSION_READY); |
416 SendInviteToConnectSignal(); | 364 SendConnectionRequest(); |
417 return; | 365 return; |
418 } | 366 } |
419 | 367 |
420 SetSubStatus(SubStatus::WAITING_NOTIFY_SESSION); | 368 SetSubStatus(SubStatus::WAITING_NOTIFY_SESSION); |
421 characteristic->StartNotifySession( | 369 characteristic->StartNotifySession( |
422 base::Bind(&BluetoothLowEnergyConnection::OnNotifySessionStarted, | 370 base::Bind( |
423 weak_ptr_factory_.GetWeakPtr()), | 371 &BluetoothLowEnergyWeaveClientConnection::OnNotifySessionStarted, |
424 base::Bind(&BluetoothLowEnergyConnection::OnNotifySessionError, | 372 weak_ptr_factory_.GetWeakPtr()), |
425 weak_ptr_factory_.GetWeakPtr())); | 373 base::Bind( |
374 &BluetoothLowEnergyWeaveClientConnection::OnNotifySessionError, | |
375 weak_ptr_factory_.GetWeakPtr())); | |
426 } | 376 } |
427 } | 377 } |
428 | 378 |
429 void BluetoothLowEnergyConnection::OnNotifySessionError( | 379 void BluetoothLowEnergyWeaveClientConnection::OnNotifySessionStarted( |
430 BluetoothRemoteGattService::GattErrorCode error) { | |
431 DCHECK(sub_status() == SubStatus::WAITING_NOTIFY_SESSION); | |
432 PA_LOG(WARNING) << "Error starting notification session: " << error; | |
433 Disconnect(); | |
434 } | |
435 | |
436 void BluetoothLowEnergyConnection::OnNotifySessionStarted( | |
437 std::unique_ptr<BluetoothGattNotifySession> notify_session) { | 380 std::unique_ptr<BluetoothGattNotifySession> notify_session) { |
438 DCHECK(sub_status() == SubStatus::WAITING_NOTIFY_SESSION); | 381 DCHECK(sub_status() == SubStatus::WAITING_NOTIFY_SESSION); |
439 PA_LOG(INFO) << "Notification session started " | 382 PA_LOG(INFO) << "Notification session started " |
440 << notify_session->GetCharacteristicIdentifier(); | 383 << notify_session->GetCharacteristicIdentifier(); |
441 PrintTimeElapsed(); | 384 PrintTimeElapsed(); |
442 | 385 |
443 SetSubStatus(SubStatus::NOTIFY_SESSION_READY); | 386 SetSubStatus(SubStatus::NOTIFY_SESSION_READY); |
444 notify_session_ = std::move(notify_session); | 387 notify_session_ = std::move(notify_session); |
445 | 388 |
446 SendInviteToConnectSignal(); | 389 SendConnectionRequest(); |
447 } | 390 } |
448 | 391 |
449 void BluetoothLowEnergyConnection::StopNotifySession() { | 392 void BluetoothLowEnergyWeaveClientConnection::OnNotifySessionError( |
393 BluetoothRemoteGattService::GattErrorCode error) { | |
394 DCHECK(sub_status() == SubStatus::WAITING_NOTIFY_SESSION); | |
395 PA_LOG(WARNING) << "Error starting notification session: " << error; | |
396 Disconnect(); | |
397 } | |
398 | |
399 void BluetoothLowEnergyWeaveClientConnection::StopNotifySession() { | |
450 if (notify_session_) { | 400 if (notify_session_) { |
451 notify_session_->Stop(base::Bind(&base::DoNothing)); | 401 notify_session_->Stop(base::Bind(&base::DoNothing)); |
452 notify_session_.reset(); | 402 notify_session_.reset(); |
453 } | 403 } |
454 } | 404 } |
455 | 405 |
456 void BluetoothLowEnergyConnection::SendInviteToConnectSignal() { | 406 void BluetoothLowEnergyWeaveClientConnection::SendConnectionRequest() { |
457 if (sub_status() == SubStatus::NOTIFY_SESSION_READY) { | 407 if (sub_status() == SubStatus::NOTIFY_SESSION_READY) { |
458 PA_LOG(INFO) << "Sending invite to connect signal"; | 408 PA_LOG(INFO) << "Sending connection request to the server"; |
459 SetSubStatus(SubStatus::WAITING_RESPONSE_SIGNAL); | 409 SetSubStatus(SubStatus::WAITING_CONNECTION_RESPONSE); |
460 | 410 |
461 WriteRequest write_request = BuildWriteRequest( | 411 WriteRequest write_request = |
462 ToByteVector( | 412 WriteRequest(packet_generator_->CreateConnectionRequest(), false); |
463 static_cast<uint32_t>(ControlSignal::kInviteToConnectSignal)), | |
464 std::vector<uint8_t>(), false); | |
465 | 413 |
466 WriteRemoteCharacteristic(write_request); | 414 WriteRemoteCharacteristic(write_request); |
467 } | 415 } |
468 } | 416 } |
469 | 417 |
470 void BluetoothLowEnergyConnection::WriteRemoteCharacteristic( | 418 void BluetoothLowEnergyWeaveClientConnection::WriteConnectionClose( |
471 WriteRequest request) { | 419 const Packet& connection_close) { |
420 // TODO(jingxuy): I know this is single threaded, but can it actually still | |
Kyle Horimoto
2016/06/30 00:42:33
Please don't make two separate paths for this. Thi
jingxuy
2016/06/30 01:14:55
This is done because I am presuming that you want
Kyle Horimoto
2016/06/30 02:01:25
All writes that have been queued should still be w
jingxuy
2016/06/30 21:59:25
I think the misunderstanding is that this connecti
Kyle Horimoto
2016/06/30 22:36:11
The connection close packet can also used to close
jingxuy
2016/07/01 00:00:44
Yes, I think queuing is the proper way to send a n
sacomoto
2016/07/06 13:07:07
This strategy is correct. The close connection pac
jingxuy
2016/07/07 04:20:57
Done.
| |
421 // have arbitrary overlay? If so, then this queue clear can race with | |
422 // ProcessNextWriteRequest. | |
423 std::queue<WriteRequest> empty; | |
424 std::swap(write_requests_queue_, empty); | |
425 | |
426 // Spin wait on the current pending one unless overwritting is okay. | |
427 while (write_remote_characteristic_pending_) { | |
428 }; | |
429 | |
430 BluetoothRemoteGattCharacteristic* characteristic = | |
431 GetGattCharacteristic(tx_characteristic_.id); | |
432 | |
433 characteristic->WriteRemoteCharacteristic( | |
434 connection_close, | |
435 base::Bind( | |
436 &BluetoothLowEnergyWeaveClientConnection::OnConnectionCloseWritten, | |
437 weak_ptr_factory_.GetWeakPtr()), | |
438 base::Bind( | |
439 &BluetoothLowEnergyWeaveClientConnection::OnConnectionCloseError, | |
440 weak_ptr_factory_.GetWeakPtr())); | |
441 } | |
442 | |
443 void BluetoothLowEnergyWeaveClientConnection::OnConnectionCloseWritten() { | |
444 PA_LOG(INFO) << "Connection close written."; | |
445 Disconnect(); | |
446 } | |
447 | |
448 void BluetoothLowEnergyWeaveClientConnection::OnConnectionCloseError( | |
449 BluetoothRemoteGattService::GattErrorCode error) { | |
450 PA_LOG(INFO) << "Failed to write connection close due to GATT error: " | |
451 << error; | |
452 Disconnect(); | |
453 } | |
454 | |
455 void BluetoothLowEnergyWeaveClientConnection::WriteRemoteCharacteristic( | |
456 const WriteRequest& request) { | |
472 write_requests_queue_.push(request); | 457 write_requests_queue_.push(request); |
473 ProcessNextWriteRequest(); | 458 ProcessNextWriteRequest(); |
474 } | 459 } |
475 | 460 |
476 void BluetoothLowEnergyConnection::ProcessNextWriteRequest() { | 461 void BluetoothLowEnergyWeaveClientConnection::ProcessNextWriteRequest() { |
477 BluetoothRemoteGattCharacteristic* characteristic = | 462 BluetoothRemoteGattCharacteristic* characteristic = |
478 GetGattCharacteristic(to_peripheral_char_.id); | 463 GetGattCharacteristic(tx_characteristic_.id); |
479 if (!write_requests_queue_.empty() && !write_remote_characteristic_pending_ && | 464 if (!write_requests_queue_.empty() && !write_remote_characteristic_pending_ && |
480 characteristic) { | 465 characteristic) { |
481 write_remote_characteristic_pending_ = true; | 466 write_remote_characteristic_pending_ = true; |
482 WriteRequest next_request = write_requests_queue_.front(); | 467 WriteRequest next_request = write_requests_queue_.front(); |
468 | |
483 PA_LOG(INFO) << "Writing characteristic..."; | 469 PA_LOG(INFO) << "Writing characteristic..."; |
484 characteristic->WriteRemoteCharacteristic( | 470 characteristic->WriteRemoteCharacteristic( |
485 next_request.value, | 471 next_request.value, |
486 base::Bind(&BluetoothLowEnergyConnection::OnRemoteCharacteristicWritten, | 472 base::Bind(&BluetoothLowEnergyWeaveClientConnection:: |
473 OnRemoteCharacteristicWritten, | |
487 weak_ptr_factory_.GetWeakPtr(), | 474 weak_ptr_factory_.GetWeakPtr(), |
488 next_request.is_last_write_for_wire_message), | 475 next_request.is_last_write_for_wire_message), |
489 base::Bind( | 476 base::Bind(&BluetoothLowEnergyWeaveClientConnection:: |
490 &BluetoothLowEnergyConnection::OnWriteRemoteCharacteristicError, | 477 OnWriteRemoteCharacteristicError, |
491 weak_ptr_factory_.GetWeakPtr(), | 478 weak_ptr_factory_.GetWeakPtr(), |
492 next_request.is_last_write_for_wire_message)); | 479 next_request.is_last_write_for_wire_message)); |
493 } | 480 } |
494 } | 481 } |
495 | 482 |
496 void BluetoothLowEnergyConnection::OnRemoteCharacteristicWritten( | 483 void BluetoothLowEnergyWeaveClientConnection::OnRemoteCharacteristicWritten( |
497 bool run_did_send_message_callback) { | 484 bool run_did_send_message_callback) { |
498 PA_LOG(INFO) << "Characteristic written."; | 485 PA_LOG(INFO) << "Characteristic written."; |
499 write_remote_characteristic_pending_ = false; | 486 write_remote_characteristic_pending_ = false; |
500 // TODO(sacomoto): Actually pass the current message to the observer. | 487 // TODO(sacomoto): Actually pass the current message to the observer. |
501 if (run_did_send_message_callback) | 488 if (run_did_send_message_callback) |
502 OnDidSendMessage(WireMessage(std::string(), std::string()), true); | 489 OnDidSendMessage(WireMessage(std::string(), std::string()), true); |
503 | 490 |
504 // Removes the top of queue (already processed) and process the next request. | 491 // Removes the top of queue (already processed) and process the next request. |
505 DCHECK(!write_requests_queue_.empty()); | 492 DCHECK(!write_requests_queue_.empty()); |
506 write_requests_queue_.pop(); | 493 write_requests_queue_.pop(); |
507 ProcessNextWriteRequest(); | 494 ProcessNextWriteRequest(); |
508 } | 495 } |
509 | 496 |
510 void BluetoothLowEnergyConnection::OnWriteRemoteCharacteristicError( | 497 void BluetoothLowEnergyWeaveClientConnection::OnWriteRemoteCharacteristicError( |
511 bool run_did_send_message_callback, | 498 bool run_did_send_message_callback, |
512 BluetoothRemoteGattService::GattErrorCode error) { | 499 BluetoothRemoteGattService::GattErrorCode error) { |
513 PA_LOG(WARNING) << "Error " << error << " writing characteristic: " | 500 PA_LOG(WARNING) << "Error " << error << " writing characteristic: " |
514 << to_peripheral_char_.uuid.canonical_value(); | 501 << tx_characteristic_.uuid.canonical_value(); |
515 write_remote_characteristic_pending_ = false; | 502 write_remote_characteristic_pending_ = false; |
516 // TODO(sacomoto): Actually pass the current message to the observer. | 503 // TODO(sacomoto): Actually pass the current message to the observer. |
517 if (run_did_send_message_callback) | 504 if (run_did_send_message_callback) |
518 OnDidSendMessage(WireMessage(std::string(), std::string()), false); | 505 OnDidSendMessage(WireMessage(std::string(), std::string()), false); |
519 | 506 |
520 // Increases the number of failed attempts and retry. | 507 // Increases the number of failed attempts and retry. |
521 DCHECK(!write_requests_queue_.empty()); | 508 DCHECK(!write_requests_queue_.empty()); |
522 if (++write_requests_queue_.front().number_of_failed_attempts >= | 509 if (++write_requests_queue_.front().number_of_failed_attempts >= |
523 max_number_of_write_attempts_) { | 510 max_number_of_write_attempts_) { |
524 Disconnect(); | 511 Disconnect(); |
525 return; | 512 return; |
526 } | 513 } |
527 ProcessNextWriteRequest(); | 514 ProcessNextWriteRequest(); |
528 } | 515 } |
529 | 516 |
530 BluetoothLowEnergyConnection::WriteRequest | 517 void BluetoothLowEnergyWeaveClientConnection::PrintTimeElapsed() { |
531 BluetoothLowEnergyConnection::BuildWriteRequest( | |
532 const std::vector<uint8_t>& signal, | |
533 const std::vector<uint8_t>& bytes, | |
534 bool is_last_write_for_wire_message) { | |
535 std::vector<uint8_t> value(signal.begin(), signal.end()); | |
536 value.insert(value.end(), bytes.begin(), bytes.end()); | |
537 return WriteRequest(value, is_last_write_for_wire_message); | |
538 } | |
539 | |
540 void BluetoothLowEnergyConnection::PrintTimeElapsed() { | |
541 PA_LOG(INFO) << "Time elapsed: " << base::TimeTicks::Now() - start_time_; | 518 PA_LOG(INFO) << "Time elapsed: " << base::TimeTicks::Now() - start_time_; |
542 } | 519 } |
543 | 520 |
544 std::string BluetoothLowEnergyConnection::GetDeviceAddress() { | 521 std::string BluetoothLowEnergyWeaveClientConnection::GetDeviceAddress() { |
545 // When the remote device is connected we should rely on the address given by | 522 // When the remote device is connected we should rely on the address given by |
546 // |gatt_connection_|. As the device address may change if the device is | 523 // |gatt_connection_|. As the device address may change if the device is |
547 // paired. The address in |gatt_connection_| is automatically updated in this | 524 // paired. The address in |gatt_connection_| is automatically updated in this |
548 // case. | 525 // case. |
549 return gatt_connection_ ? gatt_connection_->GetDeviceAddress() | 526 return gatt_connection_ ? gatt_connection_->GetDeviceAddress() |
550 : remote_device().bluetooth_address; | 527 : remote_device().bluetooth_address; |
551 } | 528 } |
552 | 529 |
553 BluetoothDevice* BluetoothLowEnergyConnection::GetRemoteDevice() { | 530 BluetoothDevice* BluetoothLowEnergyWeaveClientConnection::GetRemoteDevice() { |
554 // It's not possible to simply use | 531 // It's not possible to simply use |
555 // |adapter_->GetDevice(GetDeviceAddress())| to find the device with MAC | 532 // |adapter_->GetDevice(GetDeviceAddress())| to find the device with MAC |
556 // address |GetDeviceAddress()|. For paired devices, | 533 // address |GetDeviceAddress()|. For paired devices, |
557 // BluetoothAdapter::GetDevice(XXX) searches for the temporary MAC address | 534 // BluetoothAdapter::GetDevice(XXX) searches for the temporary MAC address |
558 // XXX, whereas |GetDeviceAddress()| is the real MAC address. This is a | 535 // XXX, whereas |GetDeviceAddress()| is the real MAC address. This is a |
559 // bug in the way device::BluetoothAdapter is storing the devices (see | 536 // bug in the way device::BluetoothAdapter is storing the devices (see |
560 // crbug.com/497841). | 537 // crbug.com/497841). |
561 std::vector<BluetoothDevice*> devices = adapter_->GetDevices(); | 538 std::vector<BluetoothDevice*> devices = adapter_->GetDevices(); |
562 for (const auto& device : devices) { | 539 for (const auto& device : devices) { |
563 if (device->GetAddress() == GetDeviceAddress()) | 540 if (device->GetAddress() == GetDeviceAddress()) |
564 return device; | 541 return device; |
565 } | 542 } |
566 | 543 |
567 return nullptr; | 544 return nullptr; |
568 } | 545 } |
569 | 546 |
570 BluetoothRemoteGattService* BluetoothLowEnergyConnection::GetRemoteService() { | 547 BluetoothRemoteGattService* |
548 BluetoothLowEnergyWeaveClientConnection::GetRemoteService() { | |
571 BluetoothDevice* remote_device = GetRemoteDevice(); | 549 BluetoothDevice* remote_device = GetRemoteDevice(); |
572 if (!remote_device) { | 550 if (!remote_device) { |
573 PA_LOG(WARNING) << "Remote device not found."; | 551 PA_LOG(WARNING) << "Remote device not found."; |
574 return NULL; | 552 return NULL; |
575 } | 553 } |
576 if (remote_service_.id.empty()) { | 554 if (remote_service_.id.empty()) { |
577 std::vector<BluetoothRemoteGattService*> services = | 555 std::vector<BluetoothRemoteGattService*> services = |
578 remote_device->GetGattServices(); | 556 remote_device->GetGattServices(); |
579 for (const auto& service : services) | 557 for (const auto& service : services) |
580 if (service->GetUUID() == remote_service_.uuid) { | 558 if (service->GetUUID() == remote_service_.uuid) { |
581 remote_service_.id = service->GetIdentifier(); | 559 remote_service_.id = service->GetIdentifier(); |
582 break; | 560 break; |
583 } | 561 } |
584 } | 562 } |
585 return remote_device->GetGattService(remote_service_.id); | 563 return remote_device->GetGattService(remote_service_.id); |
586 } | 564 } |
587 | 565 |
588 BluetoothRemoteGattCharacteristic* | 566 BluetoothRemoteGattCharacteristic* |
589 BluetoothLowEnergyConnection::GetGattCharacteristic( | 567 BluetoothLowEnergyWeaveClientConnection::GetGattCharacteristic( |
590 const std::string& gatt_characteristic) { | 568 const std::string& gatt_characteristic) { |
591 BluetoothRemoteGattService* remote_service = GetRemoteService(); | 569 BluetoothRemoteGattService* remote_service = GetRemoteService(); |
592 if (!remote_service) { | 570 if (!remote_service) { |
593 PA_LOG(WARNING) << "Remote service not found."; | 571 PA_LOG(WARNING) << "Remote service not found."; |
594 return NULL; | 572 return NULL; |
595 } | 573 } |
596 return remote_service->GetCharacteristic(gatt_characteristic); | 574 return remote_service->GetCharacteristic(gatt_characteristic); |
597 } | 575 } |
598 | 576 |
599 // TODO(sacomoto): make this robust to byte ordering in both sides of the | 577 } // namespace weave |
600 // SmartLock BLE socket. | |
601 uint32_t BluetoothLowEnergyConnection::ToUint32( | |
602 const std::vector<uint8_t>& bytes) { | |
603 return bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24); | |
604 } | |
605 | |
606 // TODO(sacomoto): make this robust to byte ordering in both sides of the | |
607 // SmartLock BLE socket. | |
608 const std::vector<uint8_t> BluetoothLowEnergyConnection::ToByteVector( | |
609 const uint32_t value) { | |
610 std::vector<uint8_t> bytes(4, 0); | |
611 bytes[0] = static_cast<uint8_t>(value); | |
612 bytes[1] = static_cast<uint8_t>(value >> 8); | |
613 bytes[2] = static_cast<uint8_t>(value >> 16); | |
614 bytes[3] = static_cast<uint8_t>(value >> 24); | |
615 return bytes; | |
616 } | |
617 | 578 |
618 } // namespace proximity_auth | 579 } // namespace proximity_auth |
OLD | NEW |