| 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 |