| OLD | NEW |
| 1 // Copyright 2014 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/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 #include <ostream> | |
| 10 | 9 |
| 11 #include "base/bind.h" | 10 #include "base/bind.h" |
| 12 #include "base/callback.h" | 11 #include "base/callback.h" |
| 13 #include "base/callback_forward.h" | |
| 14 #include "base/logging.h" | 12 #include "base/logging.h" |
| 15 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
| 16 #include "dbus/property.h" | 14 #include "dbus/property.h" |
| 17 #include "device/bluetooth/bluetooth_adapter_bluez.h" | |
| 18 #include "device/bluetooth/bluetooth_device.h" | 15 #include "device/bluetooth/bluetooth_device.h" |
| 19 #include "device/bluetooth/bluetooth_gatt_characteristic.h" | 16 #include "device/bluetooth/bluetooth_gatt_characteristic.h" |
| 20 #include "device/bluetooth/bluetooth_gatt_descriptor_bluez.h" | |
| 21 #include "device/bluetooth/bluetooth_gatt_notify_session_bluez.h" | |
| 22 #include "device/bluetooth/bluetooth_gatt_service.h" | 17 #include "device/bluetooth/bluetooth_gatt_service.h" |
| 23 #include "device/bluetooth/bluetooth_remote_gatt_service_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" |
| 21 #include "device/bluetooth/bluez/bluetooth_remote_gatt_service_bluez.h" |
| 24 #include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h" | 22 #include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h" |
| 25 #include "device/bluetooth/dbus/bluez_dbus_manager.h" | 23 #include "device/bluetooth/dbus/bluez_dbus_manager.h" |
| 26 #include "third_party/cros_system_api/dbus/service_constants.h" | 24 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 27 | 25 |
| 28 namespace bluez { | 26 namespace bluez { |
| 29 | 27 |
| 30 namespace { | 28 namespace { |
| 31 | 29 |
| 32 // Stream operator for logging vector<uint8_t>. | 30 // Stream operator for logging vector<uint8_t>. |
| 33 std::ostream& operator<<(std::ostream& out, const std::vector<uint8_t> bytes) { | 31 std::ostream& operator<<(std::ostream& out, const std::vector<uint8_t> bytes) { |
| 34 out << "["; | 32 out << "["; |
| 35 for (std::vector<uint8_t>::const_iterator iter = bytes.begin(); | 33 for (std::vector<uint8_t>::const_iterator iter = bytes.begin(); |
| 36 iter != bytes.end(); ++iter) { | 34 iter != bytes.end(); ++iter) { |
| 37 out << base::StringPrintf("%02X", *iter); | 35 out << base::StringPrintf("%02X", *iter); |
| 38 } | 36 } |
| 39 return out << "]"; | 37 return out << "]"; |
| 40 } | 38 } |
| 41 | 39 |
| 42 } // namespace | 40 } // namespace |
| 43 | 41 |
| 44 BluetoothRemoteGattCharacteristicBlueZ::BluetoothRemoteGattCharacteristicBlueZ( | 42 BluetoothRemoteGattCharacteristicBlueZ::BluetoothRemoteGattCharacteristicBlueZ( |
| 45 BluetoothRemoteGattServiceBlueZ* service, | 43 BluetoothRemoteGattServiceBlueZ* service, |
| 46 const dbus::ObjectPath& object_path) | 44 const dbus::ObjectPath& object_path) |
| 47 : BluetoothGattCharacteristicBlueZ(service, object_path), | 45 : BluetoothGattCharacteristicBlueZ(object_path), |
| 48 num_notify_sessions_(0), | 46 num_notify_sessions_(0), |
| 49 notify_call_pending_(false), | 47 notify_call_pending_(false), |
| 48 service_(service), |
| 50 weak_ptr_factory_(this) { | 49 weak_ptr_factory_(this) { |
| 51 VLOG(1) << "Creating remote GATT characteristic with identifier: " | 50 VLOG(1) << "Creating remote GATT characteristic with identifier: " |
| 52 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value(); | 51 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value(); |
| 53 bluez::BluezDBusManager::Get() | 52 bluez::BluezDBusManager::Get() |
| 54 ->GetBluetoothGattDescriptorClient() | 53 ->GetBluetoothGattDescriptorClient() |
| 55 ->AddObserver(this); | 54 ->AddObserver(this); |
| 56 | 55 |
| 57 // Add all known GATT characteristic descriptors. | 56 // Add all known GATT characteristic descriptors. |
| 58 const std::vector<dbus::ObjectPath>& gatt_descs = | 57 const std::vector<dbus::ObjectPath>& gatt_descs = |
| 59 bluez::BluezDBusManager::Get() | 58 bluez::BluezDBusManager::Get() |
| (...skipping 13 matching lines...) Expand all Loading... |
| 73 // Clean up all the descriptors. There isn't much point in notifying service | 72 // Clean up all the descriptors. There isn't much point in notifying service |
| 74 // observers for each descriptor that gets removed, so just delete them. | 73 // observers for each descriptor that gets removed, so just delete them. |
| 75 for (DescriptorMap::iterator iter = descriptors_.begin(); | 74 for (DescriptorMap::iterator iter = descriptors_.begin(); |
| 76 iter != descriptors_.end(); ++iter) | 75 iter != descriptors_.end(); ++iter) |
| 77 delete iter->second; | 76 delete iter->second; |
| 78 | 77 |
| 79 // Report an error for all pending calls to StartNotifySession. | 78 // Report an error for all pending calls to StartNotifySession. |
| 80 while (!pending_start_notify_calls_.empty()) { | 79 while (!pending_start_notify_calls_.empty()) { |
| 81 PendingStartNotifyCall callbacks = pending_start_notify_calls_.front(); | 80 PendingStartNotifyCall callbacks = pending_start_notify_calls_.front(); |
| 82 pending_start_notify_calls_.pop(); | 81 pending_start_notify_calls_.pop(); |
| 83 callbacks.second.Run(device::BluetoothGattService::GATT_ERROR_FAILED); | 82 callbacks.second.Run(device::BluetoothRemoteGattService::GATT_ERROR_FAILED); |
| 84 } | 83 } |
| 85 } | 84 } |
| 86 | 85 |
| 87 device::BluetoothUUID BluetoothRemoteGattCharacteristicBlueZ::GetUUID() const { | 86 device::BluetoothUUID BluetoothRemoteGattCharacteristicBlueZ::GetUUID() const { |
| 88 bluez::BluetoothGattCharacteristicClient::Properties* properties = | 87 bluez::BluetoothGattCharacteristicClient::Properties* properties = |
| 89 bluez::BluezDBusManager::Get() | 88 bluez::BluezDBusManager::Get() |
| 90 ->GetBluetoothGattCharacteristicClient() | 89 ->GetBluetoothGattCharacteristicClient() |
| 91 ->GetProperties(object_path()); | 90 ->GetProperties(object_path()); |
| 92 DCHECK(properties); | 91 DCHECK(properties); |
| 93 return device::BluetoothUUID(properties->uuid.value()); | 92 return device::BluetoothUUID(properties->uuid.value()); |
| 94 } | 93 } |
| 95 | 94 |
| 96 bool BluetoothRemoteGattCharacteristicBlueZ::IsLocal() const { | 95 device::BluetoothRemoteGattCharacteristic::Properties |
| 97 return false; | |
| 98 } | |
| 99 | |
| 100 const std::vector<uint8_t>& BluetoothRemoteGattCharacteristicBlueZ::GetValue() | |
| 101 const { | |
| 102 bluez::BluetoothGattCharacteristicClient::Properties* properties = | |
| 103 bluez::BluezDBusManager::Get() | |
| 104 ->GetBluetoothGattCharacteristicClient() | |
| 105 ->GetProperties(object_path()); | |
| 106 | |
| 107 DCHECK(properties); | |
| 108 | |
| 109 return properties->value.value(); | |
| 110 } | |
| 111 | |
| 112 device::BluetoothGattCharacteristic::Properties | |
| 113 BluetoothRemoteGattCharacteristicBlueZ::GetProperties() const { | 96 BluetoothRemoteGattCharacteristicBlueZ::GetProperties() const { |
| 114 bluez::BluetoothGattCharacteristicClient::Properties* properties = | 97 bluez::BluetoothGattCharacteristicClient::Properties* properties = |
| 115 bluez::BluezDBusManager::Get() | 98 bluez::BluezDBusManager::Get() |
| 116 ->GetBluetoothGattCharacteristicClient() | 99 ->GetBluetoothGattCharacteristicClient() |
| 117 ->GetProperties(object_path()); | 100 ->GetProperties(object_path()); |
| 118 DCHECK(properties); | 101 DCHECK(properties); |
| 119 | 102 |
| 120 Properties props = PROPERTY_NONE; | 103 Properties props = PROPERTY_NONE; |
| 121 const std::vector<std::string>& flags = properties->flags.value(); | 104 const std::vector<std::string>& flags = properties->flags.value(); |
| 122 for (std::vector<std::string>::const_iterator iter = flags.begin(); | 105 for (std::vector<std::string>::const_iterator iter = flags.begin(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 139 props |= PROPERTY_EXTENDED_PROPERTIES; | 122 props |= PROPERTY_EXTENDED_PROPERTIES; |
| 140 if (*iter == bluetooth_gatt_characteristic::kFlagReliableWrite) | 123 if (*iter == bluetooth_gatt_characteristic::kFlagReliableWrite) |
| 141 props |= PROPERTY_RELIABLE_WRITE; | 124 props |= PROPERTY_RELIABLE_WRITE; |
| 142 if (*iter == bluetooth_gatt_characteristic::kFlagWritableAuxiliaries) | 125 if (*iter == bluetooth_gatt_characteristic::kFlagWritableAuxiliaries) |
| 143 props |= PROPERTY_WRITABLE_AUXILIARIES; | 126 props |= PROPERTY_WRITABLE_AUXILIARIES; |
| 144 } | 127 } |
| 145 | 128 |
| 146 return props; | 129 return props; |
| 147 } | 130 } |
| 148 | 131 |
| 132 device::BluetoothRemoteGattCharacteristic::Permissions |
| 133 BluetoothRemoteGattCharacteristicBlueZ::GetPermissions() const { |
| 134 // TODO(armansito): Once BlueZ defines the permissions, return the correct |
| 135 // values here. |
| 136 return PERMISSION_NONE; |
| 137 } |
| 138 |
| 139 const std::vector<uint8_t>& BluetoothRemoteGattCharacteristicBlueZ::GetValue() |
| 140 const { |
| 141 bluez::BluetoothGattCharacteristicClient::Properties* properties = |
| 142 bluez::BluezDBusManager::Get() |
| 143 ->GetBluetoothGattCharacteristicClient() |
| 144 ->GetProperties(object_path()); |
| 145 |
| 146 DCHECK(properties); |
| 147 |
| 148 return properties->value.value(); |
| 149 } |
| 150 |
| 151 device::BluetoothRemoteGattService* |
| 152 BluetoothRemoteGattCharacteristicBlueZ::GetService() const { |
| 153 return service_; |
| 154 } |
| 155 |
| 149 bool BluetoothRemoteGattCharacteristicBlueZ::IsNotifying() const { | 156 bool BluetoothRemoteGattCharacteristicBlueZ::IsNotifying() const { |
| 150 bluez::BluetoothGattCharacteristicClient::Properties* properties = | 157 bluez::BluetoothGattCharacteristicClient::Properties* properties = |
| 151 bluez::BluezDBusManager::Get() | 158 bluez::BluezDBusManager::Get() |
| 152 ->GetBluetoothGattCharacteristicClient() | 159 ->GetBluetoothGattCharacteristicClient() |
| 153 ->GetProperties(object_path()); | 160 ->GetProperties(object_path()); |
| 154 DCHECK(properties); | 161 DCHECK(properties); |
| 155 | 162 |
| 156 return properties->notifying.value(); | 163 return properties->notifying.value(); |
| 157 } | 164 } |
| 158 | 165 |
| 159 bool BluetoothRemoteGattCharacteristicBlueZ::AddDescriptor( | 166 std::vector<device::BluetoothRemoteGattDescriptor*> |
| 160 device::BluetoothGattDescriptor* descriptor) { | 167 BluetoothRemoteGattCharacteristicBlueZ::GetDescriptors() const { |
| 161 VLOG(1) << "Descriptors cannot be added to a remote GATT characteristic."; | 168 std::vector<device::BluetoothRemoteGattDescriptor*> descriptors; |
| 162 return false; | 169 for (DescriptorMap::const_iterator iter = descriptors_.begin(); |
| 170 iter != descriptors_.end(); ++iter) |
| 171 descriptors.push_back(iter->second); |
| 172 return descriptors; |
| 163 } | 173 } |
| 164 | 174 |
| 165 bool BluetoothRemoteGattCharacteristicBlueZ::UpdateValue( | 175 device::BluetoothRemoteGattDescriptor* |
| 166 const std::vector<uint8_t>& value) { | 176 BluetoothRemoteGattCharacteristicBlueZ::GetDescriptor( |
| 167 VLOG(1) << "Cannot update the value of a remote GATT characteristic."; | 177 const std::string& identifier) const { |
| 168 return false; | 178 DescriptorMap::const_iterator iter = |
| 179 descriptors_.find(dbus::ObjectPath(identifier)); |
| 180 if (iter == descriptors_.end()) |
| 181 return nullptr; |
| 182 return iter->second; |
| 169 } | 183 } |
| 170 | 184 |
| 171 void BluetoothRemoteGattCharacteristicBlueZ::StartNotifySession( | 185 void BluetoothRemoteGattCharacteristicBlueZ::StartNotifySession( |
| 172 const NotifySessionCallback& callback, | 186 const NotifySessionCallback& callback, |
| 173 const ErrorCallback& error_callback) { | 187 const ErrorCallback& error_callback) { |
| 174 VLOG(1) << __func__; | 188 VLOG(1) << __func__; |
| 175 | 189 |
| 176 if (num_notify_sessions_ > 0) { | 190 if (num_notify_sessions_ > 0) { |
| 177 // The characteristic might have stopped notifying even though the session | 191 // The characteristic might have stopped notifying even though the session |
| 178 // count is nonzero. This means that notifications stopped outside of our | 192 // count is nonzero. This means that notifications stopped outside of our |
| 179 // control and we should reset the count. If the characteristic is still | 193 // control and we should reset the count. If the characteristic is still |
| 180 // notifying, then return success. Otherwise, reset the count and treat | 194 // notifying, then return success. Otherwise, reset the count and treat |
| 181 // this call as if the count were 0. | 195 // this call as if the count were 0. |
| 182 if (IsNotifying()) { | 196 if (IsNotifying()) { |
| 183 // Check for overflows, though unlikely. | 197 // Check for overflows, though unlikely. |
| 184 if (num_notify_sessions_ == std::numeric_limits<size_t>::max()) { | 198 if (num_notify_sessions_ == std::numeric_limits<size_t>::max()) { |
| 185 error_callback.Run(device::BluetoothGattService::GATT_ERROR_FAILED); | 199 error_callback.Run( |
| 200 device::BluetoothRemoteGattService::GATT_ERROR_FAILED); |
| 186 return; | 201 return; |
| 187 } | 202 } |
| 188 | 203 |
| 189 ++num_notify_sessions_; | 204 ++num_notify_sessions_; |
| 190 DCHECK(service_); | 205 DCHECK(service_); |
| 191 DCHECK(service_->GetAdapter()); | 206 DCHECK(service_->GetAdapter()); |
| 192 DCHECK(service_->GetDevice()); | 207 DCHECK(service_->GetDevice()); |
| 193 std::unique_ptr<device::BluetoothGattNotifySession> session( | 208 std::unique_ptr<device::BluetoothGattNotifySession> session( |
| 194 new BluetoothGattNotifySessionBlueZ( | 209 new BluetoothGattNotifySessionBlueZ( |
| 195 service_->GetAdapter(), service_->GetDevice()->GetAddress(), | 210 service_->GetAdapter(), service_->GetDevice()->GetAddress(), |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 ->GetProperties(object_path); | 315 ->GetProperties(object_path); |
| 301 DCHECK(properties); | 316 DCHECK(properties); |
| 302 if (properties->characteristic.value() != this->object_path()) { | 317 if (properties->characteristic.value() != this->object_path()) { |
| 303 VLOG(3) << "Remote GATT descriptor does not belong to this characteristic."; | 318 VLOG(3) << "Remote GATT descriptor does not belong to this characteristic."; |
| 304 return; | 319 return; |
| 305 } | 320 } |
| 306 | 321 |
| 307 VLOG(1) << "Adding new remote GATT descriptor for GATT characteristic: " | 322 VLOG(1) << "Adding new remote GATT descriptor for GATT characteristic: " |
| 308 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value(); | 323 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value(); |
| 309 | 324 |
| 310 BluetoothGattDescriptorBlueZ* descriptor = | 325 BluetoothRemoteGattDescriptorBlueZ* descriptor = |
| 311 new BluetoothGattDescriptorBlueZ(this, object_path, false /* is_local */); | 326 new BluetoothRemoteGattDescriptorBlueZ(this, object_path); |
| 312 descriptors_[object_path] = descriptor; | 327 descriptors_[object_path] = descriptor; |
| 313 DCHECK(descriptor->GetIdentifier() == object_path.value()); | 328 DCHECK(descriptor->GetIdentifier() == object_path.value()); |
| 314 DCHECK(descriptor->GetUUID().IsValid()); | 329 DCHECK(descriptor->GetUUID().IsValid()); |
| 315 DCHECK(service_); | 330 DCHECK(service_); |
| 316 | 331 |
| 317 static_cast<BluetoothRemoteGattServiceBlueZ*>(service_) | 332 static_cast<BluetoothRemoteGattServiceBlueZ*>(service_) |
| 318 ->NotifyDescriptorAddedOrRemoved(this, descriptor, true /* added */); | 333 ->NotifyDescriptorAddedOrRemoved(this, descriptor, true /* added */); |
| 319 } | 334 } |
| 320 | 335 |
| 321 void BluetoothRemoteGattCharacteristicBlueZ::GattDescriptorRemoved( | 336 void BluetoothRemoteGattCharacteristicBlueZ::GattDescriptorRemoved( |
| 322 const dbus::ObjectPath& object_path) { | 337 const dbus::ObjectPath& object_path) { |
| 323 DescriptorMap::iterator iter = descriptors_.find(object_path); | 338 DescriptorMap::iterator iter = descriptors_.find(object_path); |
| 324 if (iter == descriptors_.end()) { | 339 if (iter == descriptors_.end()) { |
| 325 VLOG(2) << "Unknown descriptor removed: " << object_path.value(); | 340 VLOG(2) << "Unknown descriptor removed: " << object_path.value(); |
| 326 return; | 341 return; |
| 327 } | 342 } |
| 328 | 343 |
| 329 VLOG(1) << "Removing remote GATT descriptor from characteristic: " | 344 VLOG(1) << "Removing remote GATT descriptor from characteristic: " |
| 330 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value(); | 345 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value(); |
| 331 | 346 |
| 332 BluetoothGattDescriptorBlueZ* descriptor = iter->second; | 347 BluetoothRemoteGattDescriptorBlueZ* descriptor = iter->second; |
| 333 DCHECK(descriptor->object_path() == object_path); | 348 DCHECK(descriptor->object_path() == object_path); |
| 334 descriptors_.erase(iter); | 349 descriptors_.erase(iter); |
| 335 | 350 |
| 336 DCHECK(service_); | 351 DCHECK(service_); |
| 337 static_cast<BluetoothRemoteGattServiceBlueZ*>(service_) | 352 static_cast<BluetoothRemoteGattServiceBlueZ*>(service_) |
| 338 ->NotifyDescriptorAddedOrRemoved(this, descriptor, false /* added */); | 353 ->NotifyDescriptorAddedOrRemoved(this, descriptor, false /* added */); |
| 339 | 354 |
| 340 delete descriptor; | 355 delete descriptor; |
| 341 } | 356 } |
| 342 | 357 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 const ErrorCallback& error_callback, | 456 const ErrorCallback& error_callback, |
| 442 const std::string& error_name, | 457 const std::string& error_name, |
| 443 const std::string& error_message) { | 458 const std::string& error_message) { |
| 444 VLOG(1) << "Operation failed: " << error_name | 459 VLOG(1) << "Operation failed: " << error_name |
| 445 << ", message: " << error_message; | 460 << ", message: " << error_message; |
| 446 error_callback.Run( | 461 error_callback.Run( |
| 447 BluetoothGattServiceBlueZ::DBusErrorToServiceError(error_name)); | 462 BluetoothGattServiceBlueZ::DBusErrorToServiceError(error_name)); |
| 448 } | 463 } |
| 449 | 464 |
| 450 } // namespace bluez | 465 } // namespace bluez |
| OLD | NEW |