Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: device/bluetooth/bluetooth_remote_gatt_characteristic_bluez.cc

Issue 1872943002: Add support for local services/characteristics/descriptors. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/bluetooth_remote_gatt_characteristic_bluez.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
12 #include "device/bluetooth/bluetooth_adapter_bluez.h" 12 #include "device/bluetooth/bluetooth_adapter_bluez.h"
13 #include "device/bluetooth/bluetooth_device.h" 13 #include "device/bluetooth/bluetooth_device.h"
14 #include "device/bluetooth/bluetooth_gatt_descriptor_bluez.h"
14 #include "device/bluetooth/bluetooth_gatt_notify_session_bluez.h" 15 #include "device/bluetooth/bluetooth_gatt_notify_session_bluez.h"
15 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_bluez.h"
16 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_bluez.h"
17 #include "device/bluetooth/bluetooth_remote_gatt_service_bluez.h" 16 #include "device/bluetooth/bluetooth_remote_gatt_service_bluez.h"
18 #include "device/bluetooth/dbus/bluez_dbus_manager.h" 17 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
19 #include "third_party/cros_system_api/dbus/service_constants.h" 18 #include "third_party/cros_system_api/dbus/service_constants.h"
20 19
21 namespace bluez { 20 namespace bluez {
22 21
23 namespace {
24
25 // Stream operator for logging vector<uint8_t>.
26 std::ostream& operator<<(std::ostream& out, const std::vector<uint8_t> bytes) {
27 out << "[";
28 for (std::vector<uint8_t>::const_iterator iter = bytes.begin();
29 iter != bytes.end(); ++iter) {
30 out << base::StringPrintf("%02X", *iter);
31 }
32 return out << "]";
33 }
34
35 } // namespace
36
37 BluetoothRemoteGattCharacteristicBlueZ::BluetoothRemoteGattCharacteristicBlueZ( 22 BluetoothRemoteGattCharacteristicBlueZ::BluetoothRemoteGattCharacteristicBlueZ(
38 BluetoothRemoteGattServiceBlueZ* service, 23 BluetoothRemoteGattServiceBlueZ* service,
39 const dbus::ObjectPath& object_path) 24 const dbus::ObjectPath& object_path)
40 : object_path_(object_path), 25 : BluetoothGattCharacteristicBlueZ(service, object_path),
41 service_(service),
42 num_notify_sessions_(0), 26 num_notify_sessions_(0),
43 notify_call_pending_(false), 27 notify_call_pending_(false),
44 weak_ptr_factory_(this) { 28 weak_ptr_factory_(this) {
45 VLOG(1) << "Creating remote GATT characteristic with identifier: " 29 VLOG(1) << "Creating remote GATT characteristic with identifier: "
46 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value(); 30 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
47 bluez::BluezDBusManager::Get() 31 bluez::BluezDBusManager::Get()
48 ->GetBluetoothGattDescriptorClient() 32 ->GetBluetoothGattDescriptorClient()
49 ->AddObserver(this); 33 ->AddObserver(this);
50 34
51 // Add all known GATT characteristic descriptors. 35 // Add all known GATT characteristic descriptors.
(...skipping 19 matching lines...) Expand all
71 delete iter->second; 55 delete iter->second;
72 56
73 // Report an error for all pending calls to StartNotifySession. 57 // Report an error for all pending calls to StartNotifySession.
74 while (!pending_start_notify_calls_.empty()) { 58 while (!pending_start_notify_calls_.empty()) {
75 PendingStartNotifyCall callbacks = pending_start_notify_calls_.front(); 59 PendingStartNotifyCall callbacks = pending_start_notify_calls_.front();
76 pending_start_notify_calls_.pop(); 60 pending_start_notify_calls_.pop();
77 callbacks.second.Run(device::BluetoothGattService::GATT_ERROR_FAILED); 61 callbacks.second.Run(device::BluetoothGattService::GATT_ERROR_FAILED);
78 } 62 }
79 } 63 }
80 64
81 std::string BluetoothRemoteGattCharacteristicBlueZ::GetIdentifier() const {
82 return object_path_.value();
83 }
84
85 device::BluetoothUUID BluetoothRemoteGattCharacteristicBlueZ::GetUUID() const {
86 bluez::BluetoothGattCharacteristicClient::Properties* properties =
87 bluez::BluezDBusManager::Get()
88 ->GetBluetoothGattCharacteristicClient()
89 ->GetProperties(object_path_);
90 DCHECK(properties);
91 return device::BluetoothUUID(properties->uuid.value());
92 }
93
94 bool BluetoothRemoteGattCharacteristicBlueZ::IsLocal() const { 65 bool BluetoothRemoteGattCharacteristicBlueZ::IsLocal() const {
95 return false; 66 return false;
96 } 67 }
97 68
98 const std::vector<uint8_t>& BluetoothRemoteGattCharacteristicBlueZ::GetValue()
99 const {
100 bluez::BluetoothGattCharacteristicClient::Properties* properties =
101 bluez::BluezDBusManager::Get()
102 ->GetBluetoothGattCharacteristicClient()
103 ->GetProperties(object_path_);
104
105 DCHECK(properties);
106
107 return properties->value.value();
108 }
109
110 device::BluetoothGattService*
111 BluetoothRemoteGattCharacteristicBlueZ::GetService() const {
112 return service_;
113 }
114
115 device::BluetoothGattCharacteristic::Properties
116 BluetoothRemoteGattCharacteristicBlueZ::GetProperties() const {
117 bluez::BluetoothGattCharacteristicClient::Properties* properties =
118 bluez::BluezDBusManager::Get()
119 ->GetBluetoothGattCharacteristicClient()
120 ->GetProperties(object_path_);
121 DCHECK(properties);
122
123 Properties props = PROPERTY_NONE;
124 const std::vector<std::string>& flags = properties->flags.value();
125 for (std::vector<std::string>::const_iterator iter = flags.begin();
126 iter != flags.end(); ++iter) {
127 if (*iter == bluetooth_gatt_characteristic::kFlagBroadcast)
128 props |= PROPERTY_BROADCAST;
129 if (*iter == bluetooth_gatt_characteristic::kFlagRead)
130 props |= PROPERTY_READ;
131 if (*iter == bluetooth_gatt_characteristic::kFlagWriteWithoutResponse)
132 props |= PROPERTY_WRITE_WITHOUT_RESPONSE;
133 if (*iter == bluetooth_gatt_characteristic::kFlagWrite)
134 props |= PROPERTY_WRITE;
135 if (*iter == bluetooth_gatt_characteristic::kFlagNotify)
136 props |= PROPERTY_NOTIFY;
137 if (*iter == bluetooth_gatt_characteristic::kFlagIndicate)
138 props |= PROPERTY_INDICATE;
139 if (*iter == bluetooth_gatt_characteristic::kFlagAuthenticatedSignedWrites)
140 props |= PROPERTY_AUTHENTICATED_SIGNED_WRITES;
141 if (*iter == bluetooth_gatt_characteristic::kFlagExtendedProperties)
142 props |= PROPERTY_EXTENDED_PROPERTIES;
143 if (*iter == bluetooth_gatt_characteristic::kFlagReliableWrite)
144 props |= PROPERTY_RELIABLE_WRITE;
145 if (*iter == bluetooth_gatt_characteristic::kFlagWritableAuxiliaries)
146 props |= PROPERTY_WRITABLE_AUXILIARIES;
147 }
148
149 return props;
150 }
151
152 device::BluetoothGattCharacteristic::Permissions
153 BluetoothRemoteGattCharacteristicBlueZ::GetPermissions() const {
154 // TODO(armansito): Once BlueZ defines the permissions, return the correct
155 // values here.
156 return PERMISSION_NONE;
157 }
158
159 bool BluetoothRemoteGattCharacteristicBlueZ::IsNotifying() const {
160 bluez::BluetoothGattCharacteristicClient::Properties* properties =
161 bluez::BluezDBusManager::Get()
162 ->GetBluetoothGattCharacteristicClient()
163 ->GetProperties(object_path_);
164 DCHECK(properties);
165
166 return properties->notifying.value();
167 }
168
169 std::vector<device::BluetoothGattDescriptor*>
170 BluetoothRemoteGattCharacteristicBlueZ::GetDescriptors() const {
171 std::vector<device::BluetoothGattDescriptor*> descriptors;
172 for (DescriptorMap::const_iterator iter = descriptors_.begin();
173 iter != descriptors_.end(); ++iter)
174 descriptors.push_back(iter->second);
175 return descriptors;
176 }
177
178 device::BluetoothGattDescriptor*
179 BluetoothRemoteGattCharacteristicBlueZ::GetDescriptor(
180 const std::string& identifier) const {
181 DescriptorMap::const_iterator iter =
182 descriptors_.find(dbus::ObjectPath(identifier));
183 if (iter == descriptors_.end())
184 return NULL;
185 return iter->second;
186 }
187
188 bool BluetoothRemoteGattCharacteristicBlueZ::AddDescriptor( 69 bool BluetoothRemoteGattCharacteristicBlueZ::AddDescriptor(
189 device::BluetoothGattDescriptor* descriptor) { 70 device::BluetoothGattDescriptor* descriptor) {
190 VLOG(1) << "Descriptors cannot be added to a remote GATT characteristic."; 71 VLOG(1) << "Descriptors cannot be added to a remote GATT characteristic.";
191 return false; 72 return false;
192 } 73 }
193 74
194 bool BluetoothRemoteGattCharacteristicBlueZ::UpdateValue( 75 bool BluetoothRemoteGattCharacteristicBlueZ::UpdateValue(
195 const std::vector<uint8_t>& value) { 76 const std::vector<uint8_t>& value) {
196 VLOG(1) << "Cannot update the value of a remote GATT characteristic."; 77 VLOG(1) << "Cannot update the value of a remote GATT characteristic.";
197 return false; 78 return false;
198 } 79 }
199 80
200 void BluetoothRemoteGattCharacteristicBlueZ::ReadRemoteCharacteristic(
201 const ValueCallback& callback,
202 const ErrorCallback& error_callback) {
203 VLOG(1) << "Sending GATT characteristic read request to characteristic: "
204 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value()
205 << ".";
206
207 bluez::BluezDBusManager::Get()
208 ->GetBluetoothGattCharacteristicClient()
209 ->ReadValue(object_path_, callback,
210 base::Bind(&BluetoothRemoteGattCharacteristicBlueZ::OnError,
211 weak_ptr_factory_.GetWeakPtr(), error_callback));
212 }
213
214 void BluetoothRemoteGattCharacteristicBlueZ::WriteRemoteCharacteristic(
215 const std::vector<uint8_t>& new_value,
216 const base::Closure& callback,
217 const ErrorCallback& error_callback) {
218 VLOG(1) << "Sending GATT characteristic write request to characteristic: "
219 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value()
220 << ", with value: " << new_value << ".";
221
222 bluez::BluezDBusManager::Get()
223 ->GetBluetoothGattCharacteristicClient()
224 ->WriteValue(object_path_, new_value, callback,
225 base::Bind(&BluetoothRemoteGattCharacteristicBlueZ::OnError,
226 weak_ptr_factory_.GetWeakPtr(), error_callback));
227 }
228
229 void BluetoothRemoteGattCharacteristicBlueZ::StartNotifySession( 81 void BluetoothRemoteGattCharacteristicBlueZ::StartNotifySession(
230 const NotifySessionCallback& callback, 82 const NotifySessionCallback& callback,
231 const ErrorCallback& error_callback) { 83 const ErrorCallback& error_callback) {
232 VLOG(1) << __func__; 84 VLOG(1) << __func__;
233 85
234 if (num_notify_sessions_ > 0) { 86 if (num_notify_sessions_ > 0) {
235 // The characteristic might have stopped notifying even though the session 87 // The characteristic might have stopped notifying even though the session
236 // count is nonzero. This means that notifications stopped outside of our 88 // count is nonzero. This means that notifications stopped outside of our
237 // control and we should reset the count. If the characteristic is still 89 // control and we should reset the count. If the characteristic is still
238 // notifying, then return success. Otherwise, reset the count and treat 90 // notifying, then return success. Otherwise, reset the count and treat
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 ->GetProperties(object_path); 181 ->GetProperties(object_path);
330 DCHECK(properties); 182 DCHECK(properties);
331 if (properties->characteristic.value() != object_path_) { 183 if (properties->characteristic.value() != object_path_) {
332 VLOG(3) << "Remote GATT descriptor does not belong to this characteristic."; 184 VLOG(3) << "Remote GATT descriptor does not belong to this characteristic.";
333 return; 185 return;
334 } 186 }
335 187
336 VLOG(1) << "Adding new remote GATT descriptor for GATT characteristic: " 188 VLOG(1) << "Adding new remote GATT descriptor for GATT characteristic: "
337 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value(); 189 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
338 190
339 BluetoothRemoteGattDescriptorBlueZ* descriptor = 191 BluetoothGattDescriptorBlueZ* descriptor =
340 new BluetoothRemoteGattDescriptorBlueZ(this, object_path); 192 new BluetoothGattDescriptorBlueZ(this, object_path, false /* is_local */);
341 descriptors_[object_path] = descriptor; 193 descriptors_[object_path] = descriptor;
342 DCHECK(descriptor->GetIdentifier() == object_path.value()); 194 DCHECK(descriptor->GetIdentifier() == object_path.value());
343 DCHECK(descriptor->GetUUID().IsValid()); 195 DCHECK(descriptor->GetUUID().IsValid());
344 DCHECK(service_); 196 DCHECK(service_);
345 197
346 service_->NotifyDescriptorAddedOrRemoved(this, descriptor, true /* added */); 198 service_->NotifyDescriptorAddedOrRemoved(this, descriptor, true /* added */);
347 } 199 }
348 200
349 void BluetoothRemoteGattCharacteristicBlueZ::GattDescriptorRemoved( 201 void BluetoothRemoteGattCharacteristicBlueZ::GattDescriptorRemoved(
350 const dbus::ObjectPath& object_path) { 202 const dbus::ObjectPath& object_path) {
351 DescriptorMap::iterator iter = descriptors_.find(object_path); 203 DescriptorMap::iterator iter = descriptors_.find(object_path);
352 if (iter == descriptors_.end()) { 204 if (iter == descriptors_.end()) {
353 VLOG(2) << "Unknown descriptor removed: " << object_path.value(); 205 VLOG(2) << "Unknown descriptor removed: " << object_path.value();
354 return; 206 return;
355 } 207 }
356 208
357 VLOG(1) << "Removing remote GATT descriptor from characteristic: " 209 VLOG(1) << "Removing remote GATT descriptor from characteristic: "
358 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value(); 210 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
359 211
360 BluetoothRemoteGattDescriptorBlueZ* descriptor = iter->second; 212 BluetoothGattDescriptorBlueZ* descriptor = iter->second;
361 DCHECK(descriptor->object_path() == object_path); 213 DCHECK(descriptor->object_path() == object_path);
362 descriptors_.erase(iter); 214 descriptors_.erase(iter);
363 215
364 DCHECK(service_); 216 DCHECK(service_);
365 service_->NotifyDescriptorAddedOrRemoved(this, descriptor, false /* added */); 217 service_->NotifyDescriptorAddedOrRemoved(this, descriptor, false /* added */);
366 218
367 delete descriptor; 219 delete descriptor;
368 } 220 }
369 221
370 void BluetoothRemoteGattCharacteristicBlueZ::GattDescriptorPropertyChanged( 222 void BluetoothRemoteGattCharacteristicBlueZ::GattDescriptorPropertyChanged(
(...skipping 13 matching lines...) Expand all
384 DCHECK(properties); 236 DCHECK(properties);
385 237
386 if (property_name != properties->value.name()) 238 if (property_name != properties->value.name())
387 return; 239 return;
388 240
389 DCHECK(service_); 241 DCHECK(service_);
390 service_->NotifyDescriptorValueChanged(this, iter->second, 242 service_->NotifyDescriptorValueChanged(this, iter->second,
391 properties->value.value()); 243 properties->value.value());
392 } 244 }
393 245
394 void BluetoothRemoteGattCharacteristicBlueZ::OnError(
395 const ErrorCallback& error_callback,
396 const std::string& error_name,
397 const std::string& error_message) {
398 VLOG(1) << "Operation failed: " << error_name
399 << ", message: " << error_message;
400 error_callback.Run(
401 BluetoothRemoteGattServiceBlueZ::DBusErrorToServiceError(error_name));
402 }
403
404 void BluetoothRemoteGattCharacteristicBlueZ::OnStartNotifySuccess( 246 void BluetoothRemoteGattCharacteristicBlueZ::OnStartNotifySuccess(
405 const NotifySessionCallback& callback) { 247 const NotifySessionCallback& callback) {
406 VLOG(1) << "Started notifications from characteristic: " 248 VLOG(1) << "Started notifications from characteristic: "
407 << object_path_.value(); 249 << object_path_.value();
408 DCHECK(num_notify_sessions_ == 0); 250 DCHECK(num_notify_sessions_ == 0);
409 DCHECK(notify_call_pending_); 251 DCHECK(notify_call_pending_);
410 252
411 ++num_notify_sessions_; 253 ++num_notify_sessions_;
412 notify_call_pending_ = false; 254 notify_call_pending_ = false;
413 255
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 309
468 void BluetoothRemoteGattCharacteristicBlueZ::ProcessStartNotifyQueue() { 310 void BluetoothRemoteGattCharacteristicBlueZ::ProcessStartNotifyQueue() {
469 while (!pending_start_notify_calls_.empty()) { 311 while (!pending_start_notify_calls_.empty()) {
470 PendingStartNotifyCall callbacks = pending_start_notify_calls_.front(); 312 PendingStartNotifyCall callbacks = pending_start_notify_calls_.front();
471 pending_start_notify_calls_.pop(); 313 pending_start_notify_calls_.pop();
472 StartNotifySession(callbacks.first, callbacks.second); 314 StartNotifySession(callbacks.first, callbacks.second);
473 } 315 }
474 } 316 }
475 317
476 } // namespace bluez 318 } // namespace bluez
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698