| 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" | |
| 18 #include "device/bluetooth/bluetooth_gatt_service.h" | 17 #include "device/bluetooth/bluetooth_gatt_service.h" |
| 19 #include "device/bluetooth/bluez/bluetooth_adapter_bluez.h" | 18 #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 | |
| 124 device::BluetoothUUID BluetoothRemoteGattCharacteristicBlueZ::GetUUID() const { | 86 device::BluetoothUUID BluetoothRemoteGattCharacteristicBlueZ::GetUUID() const { |
| 125 bluez::BluetoothGattCharacteristicClient::Properties* properties = | 87 bluez::BluetoothGattCharacteristicClient::Properties* properties = |
| 126 bluez::BluezDBusManager::Get() | 88 bluez::BluezDBusManager::Get() |
| 127 ->GetBluetoothGattCharacteristicClient() | 89 ->GetBluetoothGattCharacteristicClient() |
| 128 ->GetProperties(object_path()); | 90 ->GetProperties(object_path()); |
| 129 DCHECK(properties); | 91 DCHECK(properties); |
| 130 return device::BluetoothUUID(properties->uuid.value()); | 92 return device::BluetoothUUID(properties->uuid.value()); |
| 131 } | 93 } |
| 132 | 94 |
| 133 device::BluetoothRemoteGattCharacteristic::Properties | 95 device::BluetoothRemoteGattCharacteristic::Properties |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 error_callback.Run( | 199 error_callback.Run( |
| 238 device::BluetoothRemoteGattService::GATT_ERROR_FAILED); | 200 device::BluetoothRemoteGattService::GATT_ERROR_FAILED); |
| 239 return; | 201 return; |
| 240 } | 202 } |
| 241 | 203 |
| 242 ++num_notify_sessions_; | 204 ++num_notify_sessions_; |
| 243 DCHECK(service_); | 205 DCHECK(service_); |
| 244 DCHECK(service_->GetAdapter()); | 206 DCHECK(service_->GetAdapter()); |
| 245 DCHECK(service_->GetDevice()); | 207 DCHECK(service_->GetDevice()); |
| 246 std::unique_ptr<device::BluetoothGattNotifySession> session( | 208 std::unique_ptr<device::BluetoothGattNotifySession> session( |
| 247 new device::BluetoothGattNotifySession( | 209 new BluetoothGattNotifySessionBlueZ( |
| 248 weak_ptr_factory_.GetWeakPtr())); | 210 service_->GetAdapter(), service_->GetDevice()->GetAddress(), |
| 211 service_->GetIdentifier(), GetIdentifier(), object_path())); |
| 249 callback.Run(std::move(session)); | 212 callback.Run(std::move(session)); |
| 250 return; | 213 return; |
| 251 } | 214 } |
| 252 | 215 |
| 253 num_notify_sessions_ = 0; | 216 num_notify_sessions_ = 0; |
| 254 } | 217 } |
| 255 | 218 |
| 256 // Queue the callbacks if there is a pending call to bluetoothd. | 219 // Queue the callbacks if there is a pending call to bluetoothd. |
| 257 if (notify_call_pending_) { | 220 if (notify_call_pending_) { |
| 258 pending_start_notify_calls_.push(std::make_pair(callback, error_callback)); | 221 pending_start_notify_calls_.push(std::make_pair(callback, error_callback)); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value() | 257 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value() |
| 295 << ", with value: " << new_value << "."; | 258 << ", with value: " << new_value << "."; |
| 296 | 259 |
| 297 bluez::BluezDBusManager::Get() | 260 bluez::BluezDBusManager::Get() |
| 298 ->GetBluetoothGattCharacteristicClient() | 261 ->GetBluetoothGattCharacteristicClient() |
| 299 ->WriteValue(object_path(), new_value, callback, | 262 ->WriteValue(object_path(), new_value, callback, |
| 300 base::Bind(&BluetoothRemoteGattCharacteristicBlueZ::OnError, | 263 base::Bind(&BluetoothRemoteGattCharacteristicBlueZ::OnError, |
| 301 weak_ptr_factory_.GetWeakPtr(), error_callback)); | 264 weak_ptr_factory_.GetWeakPtr(), error_callback)); |
| 302 } | 265 } |
| 303 | 266 |
| 304 void BluetoothRemoteGattCharacteristicBlueZ::SubscribeToNotifications( | 267 void BluetoothRemoteGattCharacteristicBlueZ::RemoveNotifySession( |
| 305 device::BluetoothRemoteGattDescriptor* ccc_descriptor, | 268 const base::Closure& callback) { |
| 306 const base::Closure& callback, | 269 VLOG(1) << __func__; |
| 307 const ErrorCallback& error_callback) { | |
| 308 // TODO(http://crbug.com/636275): Implement this method | |
| 309 NOTIMPLEMENTED(); | |
| 310 } | |
| 311 | 270 |
| 312 void BluetoothRemoteGattCharacteristicBlueZ::UnsubscribeFromNotifications( | 271 if (num_notify_sessions_ > 1) { |
| 313 device::BluetoothRemoteGattDescriptor* ccc_descriptor, | 272 DCHECK(!notify_call_pending_); |
| 314 const base::Closure& callback, | 273 --num_notify_sessions_; |
| 315 const ErrorCallback& error_callback) { | 274 callback.Run(); |
| 316 // TODO(http://crbug.com/636275): Implement this method | 275 return; |
| 317 NOTIMPLEMENTED(); | 276 } |
| 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)); |
| 318 } | 302 } |
| 319 | 303 |
| 320 void BluetoothRemoteGattCharacteristicBlueZ::GattDescriptorAdded( | 304 void BluetoothRemoteGattCharacteristicBlueZ::GattDescriptorAdded( |
| 321 const dbus::ObjectPath& object_path) { | 305 const dbus::ObjectPath& object_path) { |
| 322 if (descriptors_.find(object_path) != descriptors_.end()) { | 306 if (descriptors_.find(object_path) != descriptors_.end()) { |
| 323 VLOG(1) << "Remote GATT characteristic descriptor already exists: " | 307 VLOG(1) << "Remote GATT characteristic descriptor already exists: " |
| 324 << object_path.value(); | 308 << object_path.value(); |
| 325 return; | 309 return; |
| 326 } | 310 } |
| 327 | 311 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 DCHECK(num_notify_sessions_ == 0); | 387 DCHECK(num_notify_sessions_ == 0); |
| 404 DCHECK(notify_call_pending_); | 388 DCHECK(notify_call_pending_); |
| 405 | 389 |
| 406 ++num_notify_sessions_; | 390 ++num_notify_sessions_; |
| 407 notify_call_pending_ = false; | 391 notify_call_pending_ = false; |
| 408 | 392 |
| 409 // Invoke the queued callbacks for this operation. | 393 // Invoke the queued callbacks for this operation. |
| 410 DCHECK(service_); | 394 DCHECK(service_); |
| 411 DCHECK(service_->GetDevice()); | 395 DCHECK(service_->GetDevice()); |
| 412 std::unique_ptr<device::BluetoothGattNotifySession> session( | 396 std::unique_ptr<device::BluetoothGattNotifySession> session( |
| 413 new device::BluetoothGattNotifySession(weak_ptr_factory_.GetWeakPtr())); | 397 new BluetoothGattNotifySessionBlueZ( |
| 398 service_->GetAdapter(), service_->GetDevice()->GetAddress(), |
| 399 service_->GetIdentifier(), GetIdentifier(), object_path())); |
| 414 callback.Run(std::move(session)); | 400 callback.Run(std::move(session)); |
| 415 | 401 |
| 416 ProcessStartNotifyQueue(); | 402 ProcessStartNotifyQueue(); |
| 417 } | 403 } |
| 418 | 404 |
| 419 void BluetoothRemoteGattCharacteristicBlueZ::OnStartNotifyError( | 405 void BluetoothRemoteGattCharacteristicBlueZ::OnStartNotifyError( |
| 420 const ErrorCallback& error_callback, | 406 const ErrorCallback& error_callback, |
| 421 const std::string& error_name, | 407 const std::string& error_name, |
| 422 const std::string& error_message) { | 408 const std::string& error_message) { |
| 423 VLOG(1) << "Failed to start notifications from characteristic: " | 409 VLOG(1) << "Failed to start notifications from characteristic: " |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 const ErrorCallback& error_callback, | 456 const ErrorCallback& error_callback, |
| 471 const std::string& error_name, | 457 const std::string& error_name, |
| 472 const std::string& error_message) { | 458 const std::string& error_message) { |
| 473 VLOG(1) << "Operation failed: " << error_name | 459 VLOG(1) << "Operation failed: " << error_name |
| 474 << ", message: " << error_message; | 460 << ", message: " << error_message; |
| 475 error_callback.Run( | 461 error_callback.Run( |
| 476 BluetoothGattServiceBlueZ::DBusErrorToServiceError(error_name)); | 462 BluetoothGattServiceBlueZ::DBusErrorToServiceError(error_name)); |
| 477 } | 463 } |
| 478 | 464 |
| 479 } // namespace bluez | 465 } // namespace bluez |
| OLD | NEW |