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 |