OLD | NEW |
1 // Copyright 2016 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 "device/bluetooth/bluez/bluetooth_remote_gatt_characteristic_bluez.h" | 5 #include "device/bluetooth/bluez/bluetooth_remote_gatt_characteristic_bluez.h" |
6 | 6 |
7 #include <iterator> | 7 #include <iterator> |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/callback.h" | 11 #include "base/callback.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
14 #include "dbus/property.h" | 14 #include "dbus/property.h" |
15 #include "device/bluetooth/bluetooth_device.h" | 15 #include "device/bluetooth/bluetooth_device.h" |
16 #include "device/bluetooth/bluetooth_gatt_characteristic.h" | 16 #include "device/bluetooth/bluetooth_gatt_characteristic.h" |
| 17 #include "device/bluetooth/bluetooth_gatt_notify_session.h" |
17 #include "device/bluetooth/bluetooth_gatt_service.h" | 18 #include "device/bluetooth/bluetooth_gatt_service.h" |
18 #include "device/bluetooth/bluez/bluetooth_adapter_bluez.h" | 19 #include "device/bluetooth/bluez/bluetooth_adapter_bluez.h" |
19 #include "device/bluetooth/bluez/bluetooth_gatt_notify_session_bluez.h" | |
20 #include "device/bluetooth/bluez/bluetooth_remote_gatt_descriptor_bluez.h" | 20 #include "device/bluetooth/bluez/bluetooth_remote_gatt_descriptor_bluez.h" |
21 #include "device/bluetooth/bluez/bluetooth_remote_gatt_service_bluez.h" | 21 #include "device/bluetooth/bluez/bluetooth_remote_gatt_service_bluez.h" |
22 #include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h" | 22 #include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h" |
23 #include "device/bluetooth/dbus/bluez_dbus_manager.h" | 23 #include "device/bluetooth/dbus/bluez_dbus_manager.h" |
24 #include "third_party/cros_system_api/dbus/service_constants.h" | 24 #include "third_party/cros_system_api/dbus/service_constants.h" |
25 | 25 |
26 namespace bluez { | 26 namespace bluez { |
27 | 27 |
28 namespace { | 28 namespace { |
29 | 29 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 delete iter->second; | 76 delete iter->second; |
77 | 77 |
78 // Report an error for all pending calls to StartNotifySession. | 78 // Report an error for all pending calls to StartNotifySession. |
79 while (!pending_start_notify_calls_.empty()) { | 79 while (!pending_start_notify_calls_.empty()) { |
80 PendingStartNotifyCall callbacks = pending_start_notify_calls_.front(); | 80 PendingStartNotifyCall callbacks = pending_start_notify_calls_.front(); |
81 pending_start_notify_calls_.pop(); | 81 pending_start_notify_calls_.pop(); |
82 callbacks.second.Run(device::BluetoothRemoteGattService::GATT_ERROR_FAILED); | 82 callbacks.second.Run(device::BluetoothRemoteGattService::GATT_ERROR_FAILED); |
83 } | 83 } |
84 } | 84 } |
85 | 85 |
| 86 void BluetoothRemoteGattCharacteristicBlueZ::StopNotifySession( |
| 87 device::BluetoothGattNotifySession* session, |
| 88 const base::Closure& callback) { |
| 89 VLOG(1) << __func__; |
| 90 |
| 91 if (num_notify_sessions_ > 1) { |
| 92 DCHECK(!notify_call_pending_); |
| 93 --num_notify_sessions_; |
| 94 callback.Run(); |
| 95 return; |
| 96 } |
| 97 |
| 98 // Notifications may have stopped outside our control. If the characteristic |
| 99 // is no longer notifying, return success. |
| 100 if (!IsNotifying()) { |
| 101 num_notify_sessions_ = 0; |
| 102 callback.Run(); |
| 103 return; |
| 104 } |
| 105 |
| 106 if (notify_call_pending_ || num_notify_sessions_ == 0) { |
| 107 callback.Run(); |
| 108 return; |
| 109 } |
| 110 |
| 111 DCHECK(num_notify_sessions_ == 1); |
| 112 notify_call_pending_ = true; |
| 113 bluez::BluezDBusManager::Get() |
| 114 ->GetBluetoothGattCharacteristicClient() |
| 115 ->StopNotify( |
| 116 object_path(), |
| 117 base::Bind( |
| 118 &BluetoothRemoteGattCharacteristicBlueZ::OnStopNotifySuccess, |
| 119 weak_ptr_factory_.GetWeakPtr(), callback), |
| 120 base::Bind(&BluetoothRemoteGattCharacteristicBlueZ::OnStopNotifyError, |
| 121 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 122 } |
| 123 |
86 device::BluetoothUUID BluetoothRemoteGattCharacteristicBlueZ::GetUUID() const { | 124 device::BluetoothUUID BluetoothRemoteGattCharacteristicBlueZ::GetUUID() const { |
87 bluez::BluetoothGattCharacteristicClient::Properties* properties = | 125 bluez::BluetoothGattCharacteristicClient::Properties* properties = |
88 bluez::BluezDBusManager::Get() | 126 bluez::BluezDBusManager::Get() |
89 ->GetBluetoothGattCharacteristicClient() | 127 ->GetBluetoothGattCharacteristicClient() |
90 ->GetProperties(object_path()); | 128 ->GetProperties(object_path()); |
91 DCHECK(properties); | 129 DCHECK(properties); |
92 return device::BluetoothUUID(properties->uuid.value()); | 130 return device::BluetoothUUID(properties->uuid.value()); |
93 } | 131 } |
94 | 132 |
95 device::BluetoothRemoteGattCharacteristic::Properties | 133 device::BluetoothRemoteGattCharacteristic::Properties |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 error_callback.Run( | 237 error_callback.Run( |
200 device::BluetoothRemoteGattService::GATT_ERROR_FAILED); | 238 device::BluetoothRemoteGattService::GATT_ERROR_FAILED); |
201 return; | 239 return; |
202 } | 240 } |
203 | 241 |
204 ++num_notify_sessions_; | 242 ++num_notify_sessions_; |
205 DCHECK(service_); | 243 DCHECK(service_); |
206 DCHECK(service_->GetAdapter()); | 244 DCHECK(service_->GetAdapter()); |
207 DCHECK(service_->GetDevice()); | 245 DCHECK(service_->GetDevice()); |
208 std::unique_ptr<device::BluetoothGattNotifySession> session( | 246 std::unique_ptr<device::BluetoothGattNotifySession> session( |
209 new BluetoothGattNotifySessionBlueZ( | 247 new device::BluetoothGattNotifySession( |
210 service_->GetAdapter(), service_->GetDevice()->GetAddress(), | 248 weak_ptr_factory_.GetWeakPtr())); |
211 service_->GetIdentifier(), GetIdentifier(), object_path())); | |
212 callback.Run(std::move(session)); | 249 callback.Run(std::move(session)); |
213 return; | 250 return; |
214 } | 251 } |
215 | 252 |
216 num_notify_sessions_ = 0; | 253 num_notify_sessions_ = 0; |
217 } | 254 } |
218 | 255 |
219 // Queue the callbacks if there is a pending call to bluetoothd. | 256 // Queue the callbacks if there is a pending call to bluetoothd. |
220 if (notify_call_pending_) { | 257 if (notify_call_pending_) { |
221 pending_start_notify_calls_.push(std::make_pair(callback, error_callback)); | 258 pending_start_notify_calls_.push(std::make_pair(callback, error_callback)); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value() | 294 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value() |
258 << ", with value: " << new_value << "."; | 295 << ", with value: " << new_value << "."; |
259 | 296 |
260 bluez::BluezDBusManager::Get() | 297 bluez::BluezDBusManager::Get() |
261 ->GetBluetoothGattCharacteristicClient() | 298 ->GetBluetoothGattCharacteristicClient() |
262 ->WriteValue(object_path(), new_value, callback, | 299 ->WriteValue(object_path(), new_value, callback, |
263 base::Bind(&BluetoothRemoteGattCharacteristicBlueZ::OnError, | 300 base::Bind(&BluetoothRemoteGattCharacteristicBlueZ::OnError, |
264 weak_ptr_factory_.GetWeakPtr(), error_callback)); | 301 weak_ptr_factory_.GetWeakPtr(), error_callback)); |
265 } | 302 } |
266 | 303 |
267 void BluetoothRemoteGattCharacteristicBlueZ::RemoveNotifySession( | 304 void BluetoothRemoteGattCharacteristicBlueZ::SubscribeToNotifications( |
268 const base::Closure& callback) { | 305 device::BluetoothRemoteGattDescriptor* ccc_descriptor, |
269 VLOG(1) << __func__; | 306 const base::Closure& callback, |
| 307 const ErrorCallback& error_callback) { |
| 308 // TODO(http://crbug.com/636275): Implement this method |
| 309 NOTIMPLEMENTED(); |
| 310 } |
270 | 311 |
271 if (num_notify_sessions_ > 1) { | 312 void BluetoothRemoteGattCharacteristicBlueZ::UnsubscribeFromNotifications( |
272 DCHECK(!notify_call_pending_); | 313 device::BluetoothRemoteGattDescriptor* ccc_descriptor, |
273 --num_notify_sessions_; | 314 const base::Closure& callback, |
274 callback.Run(); | 315 const ErrorCallback& error_callback) { |
275 return; | 316 // TODO(http://crbug.com/636275): Implement this method |
276 } | 317 NOTIMPLEMENTED(); |
277 | |
278 // Notifications may have stopped outside our control. If the characteristic | |
279 // is no longer notifying, return success. | |
280 if (!IsNotifying()) { | |
281 num_notify_sessions_ = 0; | |
282 callback.Run(); | |
283 return; | |
284 } | |
285 | |
286 if (notify_call_pending_ || num_notify_sessions_ == 0) { | |
287 callback.Run(); | |
288 return; | |
289 } | |
290 | |
291 DCHECK(num_notify_sessions_ == 1); | |
292 notify_call_pending_ = true; | |
293 bluez::BluezDBusManager::Get() | |
294 ->GetBluetoothGattCharacteristicClient() | |
295 ->StopNotify( | |
296 object_path(), | |
297 base::Bind( | |
298 &BluetoothRemoteGattCharacteristicBlueZ::OnStopNotifySuccess, | |
299 weak_ptr_factory_.GetWeakPtr(), callback), | |
300 base::Bind(&BluetoothRemoteGattCharacteristicBlueZ::OnStopNotifyError, | |
301 weak_ptr_factory_.GetWeakPtr(), callback)); | |
302 } | 318 } |
303 | 319 |
304 void BluetoothRemoteGattCharacteristicBlueZ::GattDescriptorAdded( | 320 void BluetoothRemoteGattCharacteristicBlueZ::GattDescriptorAdded( |
305 const dbus::ObjectPath& object_path) { | 321 const dbus::ObjectPath& object_path) { |
306 if (descriptors_.find(object_path) != descriptors_.end()) { | 322 if (descriptors_.find(object_path) != descriptors_.end()) { |
307 VLOG(1) << "Remote GATT characteristic descriptor already exists: " | 323 VLOG(1) << "Remote GATT characteristic descriptor already exists: " |
308 << object_path.value(); | 324 << object_path.value(); |
309 return; | 325 return; |
310 } | 326 } |
311 | 327 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 DCHECK(num_notify_sessions_ == 0); | 403 DCHECK(num_notify_sessions_ == 0); |
388 DCHECK(notify_call_pending_); | 404 DCHECK(notify_call_pending_); |
389 | 405 |
390 ++num_notify_sessions_; | 406 ++num_notify_sessions_; |
391 notify_call_pending_ = false; | 407 notify_call_pending_ = false; |
392 | 408 |
393 // Invoke the queued callbacks for this operation. | 409 // Invoke the queued callbacks for this operation. |
394 DCHECK(service_); | 410 DCHECK(service_); |
395 DCHECK(service_->GetDevice()); | 411 DCHECK(service_->GetDevice()); |
396 std::unique_ptr<device::BluetoothGattNotifySession> session( | 412 std::unique_ptr<device::BluetoothGattNotifySession> session( |
397 new BluetoothGattNotifySessionBlueZ( | 413 new device::BluetoothGattNotifySession(weak_ptr_factory_.GetWeakPtr())); |
398 service_->GetAdapter(), service_->GetDevice()->GetAddress(), | |
399 service_->GetIdentifier(), GetIdentifier(), object_path())); | |
400 callback.Run(std::move(session)); | 414 callback.Run(std::move(session)); |
401 | 415 |
402 ProcessStartNotifyQueue(); | 416 ProcessStartNotifyQueue(); |
403 } | 417 } |
404 | 418 |
405 void BluetoothRemoteGattCharacteristicBlueZ::OnStartNotifyError( | 419 void BluetoothRemoteGattCharacteristicBlueZ::OnStartNotifyError( |
406 const ErrorCallback& error_callback, | 420 const ErrorCallback& error_callback, |
407 const std::string& error_name, | 421 const std::string& error_name, |
408 const std::string& error_message) { | 422 const std::string& error_message) { |
409 VLOG(1) << "Failed to start notifications from characteristic: " | 423 VLOG(1) << "Failed to start notifications from characteristic: " |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 const ErrorCallback& error_callback, | 470 const ErrorCallback& error_callback, |
457 const std::string& error_name, | 471 const std::string& error_name, |
458 const std::string& error_message) { | 472 const std::string& error_message) { |
459 VLOG(1) << "Operation failed: " << error_name | 473 VLOG(1) << "Operation failed: " << error_name |
460 << ", message: " << error_message; | 474 << ", message: " << error_message; |
461 error_callback.Run( | 475 error_callback.Run( |
462 BluetoothGattServiceBlueZ::DBusErrorToServiceError(error_name)); | 476 BluetoothGattServiceBlueZ::DBusErrorToServiceError(error_name)); |
463 } | 477 } |
464 | 478 |
465 } // namespace bluez | 479 } // namespace bluez |
OLD | NEW |