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

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 <memory> 8 #include <memory>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/strings/stringprintf.h" 12 #include "base/strings/stringprintf.h"
13 #include "device/bluetooth/bluetooth_adapter_bluez.h" 13 #include "device/bluetooth/bluetooth_adapter_bluez.h"
14 #include "device/bluetooth/bluetooth_device.h" 14 #include "device/bluetooth/bluetooth_device.h"
15 #include "device/bluetooth/bluetooth_gatt_descriptor_bluez.h"
15 #include "device/bluetooth/bluetooth_gatt_notify_session_bluez.h" 16 #include "device/bluetooth/bluetooth_gatt_notify_session_bluez.h"
16 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_bluez.h"
17 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_bluez.h"
18 #include "device/bluetooth/bluetooth_remote_gatt_service_bluez.h" 17 #include "device/bluetooth/bluetooth_remote_gatt_service_bluez.h"
19 #include "device/bluetooth/dbus/bluez_dbus_manager.h" 18 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
20 #include "third_party/cros_system_api/dbus/service_constants.h" 19 #include "third_party/cros_system_api/dbus/service_constants.h"
21 20
22 namespace bluez { 21 namespace bluez {
23 22
24 namespace { 23 namespace {
25 24
26 // Stream operator for logging vector<uint8_t>. 25 // Stream operator for logging vector<uint8_t>.
27 std::ostream& operator<<(std::ostream& out, const std::vector<uint8_t> bytes) { 26 std::ostream& operator<<(std::ostream& out, const std::vector<uint8_t> bytes) {
28 out << "["; 27 out << "[";
29 for (std::vector<uint8_t>::const_iterator iter = bytes.begin(); 28 for (std::vector<uint8_t>::const_iterator iter = bytes.begin();
30 iter != bytes.end(); ++iter) { 29 iter != bytes.end(); ++iter) {
31 out << base::StringPrintf("%02X", *iter); 30 out << base::StringPrintf("%02X", *iter);
32 } 31 }
33 return out << "]"; 32 return out << "]";
34 } 33 }
35 34
36 } // namespace 35 } // namespace
37 36
38 BluetoothRemoteGattCharacteristicBlueZ::BluetoothRemoteGattCharacteristicBlueZ( 37 BluetoothRemoteGattCharacteristicBlueZ::BluetoothRemoteGattCharacteristicBlueZ(
39 BluetoothRemoteGattServiceBlueZ* service, 38 BluetoothRemoteGattServiceBlueZ* service,
40 const dbus::ObjectPath& object_path) 39 const dbus::ObjectPath& object_path)
41 : object_path_(object_path), 40 : BluetoothGattCharacteristicBlueZ(service, object_path),
42 service_(service),
43 num_notify_sessions_(0), 41 num_notify_sessions_(0),
44 notify_call_pending_(false), 42 notify_call_pending_(false),
45 weak_ptr_factory_(this) { 43 weak_ptr_factory_(this) {
46 VLOG(1) << "Creating remote GATT characteristic with identifier: " 44 VLOG(1) << "Creating remote GATT characteristic with identifier: "
47 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value(); 45 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
48 bluez::BluezDBusManager::Get() 46 bluez::BluezDBusManager::Get()
49 ->GetBluetoothGattDescriptorClient() 47 ->GetBluetoothGattDescriptorClient()
50 ->AddObserver(this); 48 ->AddObserver(this);
51 49
52 // Add all known GATT characteristic descriptors. 50 // Add all known GATT characteristic descriptors.
(...skipping 19 matching lines...) Expand all
72 delete iter->second; 70 delete iter->second;
73 71
74 // Report an error for all pending calls to StartNotifySession. 72 // Report an error for all pending calls to StartNotifySession.
75 while (!pending_start_notify_calls_.empty()) { 73 while (!pending_start_notify_calls_.empty()) {
76 PendingStartNotifyCall callbacks = pending_start_notify_calls_.front(); 74 PendingStartNotifyCall callbacks = pending_start_notify_calls_.front();
77 pending_start_notify_calls_.pop(); 75 pending_start_notify_calls_.pop();
78 callbacks.second.Run(device::BluetoothGattService::GATT_ERROR_FAILED); 76 callbacks.second.Run(device::BluetoothGattService::GATT_ERROR_FAILED);
79 } 77 }
80 } 78 }
81 79
82 std::string BluetoothRemoteGattCharacteristicBlueZ::GetIdentifier() const {
83 return object_path_.value();
84 }
85
86 device::BluetoothUUID BluetoothRemoteGattCharacteristicBlueZ::GetUUID() const { 80 device::BluetoothUUID BluetoothRemoteGattCharacteristicBlueZ::GetUUID() const {
87 bluez::BluetoothGattCharacteristicClient::Properties* properties = 81 bluez::BluetoothGattCharacteristicClient::Properties* properties =
88 bluez::BluezDBusManager::Get() 82 bluez::BluezDBusManager::Get()
89 ->GetBluetoothGattCharacteristicClient() 83 ->GetBluetoothGattCharacteristicClient()
90 ->GetProperties(object_path_); 84 ->GetProperties(object_path_);
91 DCHECK(properties); 85 DCHECK(properties);
92 return device::BluetoothUUID(properties->uuid.value()); 86 return device::BluetoothUUID(properties->uuid.value());
93 } 87 }
94 88
95 bool BluetoothRemoteGattCharacteristicBlueZ::IsLocal() const { 89 bool BluetoothRemoteGattCharacteristicBlueZ::IsLocal() const {
96 return false; 90 return false;
97 } 91 }
98 92
99 const std::vector<uint8_t>& BluetoothRemoteGattCharacteristicBlueZ::GetValue() 93 const std::vector<uint8_t>& BluetoothRemoteGattCharacteristicBlueZ::GetValue()
100 const { 94 const {
101 bluez::BluetoothGattCharacteristicClient::Properties* properties = 95 bluez::BluetoothGattCharacteristicClient::Properties* properties =
102 bluez::BluezDBusManager::Get() 96 bluez::BluezDBusManager::Get()
103 ->GetBluetoothGattCharacteristicClient() 97 ->GetBluetoothGattCharacteristicClient()
104 ->GetProperties(object_path_); 98 ->GetProperties(object_path_);
105 99
106 DCHECK(properties); 100 DCHECK(properties);
107 101
108 return properties->value.value(); 102 return properties->value.value();
109 } 103 }
110 104
111 device::BluetoothGattService*
112 BluetoothRemoteGattCharacteristicBlueZ::GetService() const {
113 return service_;
114 }
115
116 device::BluetoothGattCharacteristic::Properties 105 device::BluetoothGattCharacteristic::Properties
117 BluetoothRemoteGattCharacteristicBlueZ::GetProperties() const { 106 BluetoothRemoteGattCharacteristicBlueZ::GetProperties() const {
118 bluez::BluetoothGattCharacteristicClient::Properties* properties = 107 bluez::BluetoothGattCharacteristicClient::Properties* properties =
119 bluez::BluezDBusManager::Get() 108 bluez::BluezDBusManager::Get()
120 ->GetBluetoothGattCharacteristicClient() 109 ->GetBluetoothGattCharacteristicClient()
121 ->GetProperties(object_path_); 110 ->GetProperties(object_path_);
122 DCHECK(properties); 111 DCHECK(properties);
123 112
124 Properties props = PROPERTY_NONE; 113 Properties props = PROPERTY_NONE;
125 const std::vector<std::string>& flags = properties->flags.value(); 114 const std::vector<std::string>& flags = properties->flags.value();
(...skipping 17 matching lines...) Expand all
143 props |= PROPERTY_EXTENDED_PROPERTIES; 132 props |= PROPERTY_EXTENDED_PROPERTIES;
144 if (*iter == bluetooth_gatt_characteristic::kFlagReliableWrite) 133 if (*iter == bluetooth_gatt_characteristic::kFlagReliableWrite)
145 props |= PROPERTY_RELIABLE_WRITE; 134 props |= PROPERTY_RELIABLE_WRITE;
146 if (*iter == bluetooth_gatt_characteristic::kFlagWritableAuxiliaries) 135 if (*iter == bluetooth_gatt_characteristic::kFlagWritableAuxiliaries)
147 props |= PROPERTY_WRITABLE_AUXILIARIES; 136 props |= PROPERTY_WRITABLE_AUXILIARIES;
148 } 137 }
149 138
150 return props; 139 return props;
151 } 140 }
152 141
153 device::BluetoothGattCharacteristic::Permissions
154 BluetoothRemoteGattCharacteristicBlueZ::GetPermissions() const {
155 // TODO(armansito): Once BlueZ defines the permissions, return the correct
156 // values here.
157 return PERMISSION_NONE;
158 }
159
160 bool BluetoothRemoteGattCharacteristicBlueZ::IsNotifying() const { 142 bool BluetoothRemoteGattCharacteristicBlueZ::IsNotifying() const {
161 bluez::BluetoothGattCharacteristicClient::Properties* properties = 143 bluez::BluetoothGattCharacteristicClient::Properties* properties =
162 bluez::BluezDBusManager::Get() 144 bluez::BluezDBusManager::Get()
163 ->GetBluetoothGattCharacteristicClient() 145 ->GetBluetoothGattCharacteristicClient()
164 ->GetProperties(object_path_); 146 ->GetProperties(object_path_);
165 DCHECK(properties); 147 DCHECK(properties);
166 148
167 return properties->notifying.value(); 149 return properties->notifying.value();
168 } 150 }
169 151
170 std::vector<device::BluetoothGattDescriptor*>
171 BluetoothRemoteGattCharacteristicBlueZ::GetDescriptors() const {
172 std::vector<device::BluetoothGattDescriptor*> descriptors;
173 for (DescriptorMap::const_iterator iter = descriptors_.begin();
174 iter != descriptors_.end(); ++iter)
175 descriptors.push_back(iter->second);
176 return descriptors;
177 }
178
179 device::BluetoothGattDescriptor*
180 BluetoothRemoteGattCharacteristicBlueZ::GetDescriptor(
181 const std::string& identifier) const {
182 DescriptorMap::const_iterator iter =
183 descriptors_.find(dbus::ObjectPath(identifier));
184 if (iter == descriptors_.end())
185 return NULL;
186 return iter->second;
187 }
188
189 bool BluetoothRemoteGattCharacteristicBlueZ::AddDescriptor( 152 bool BluetoothRemoteGattCharacteristicBlueZ::AddDescriptor(
190 device::BluetoothGattDescriptor* descriptor) { 153 device::BluetoothGattDescriptor* descriptor) {
191 VLOG(1) << "Descriptors cannot be added to a remote GATT characteristic."; 154 VLOG(1) << "Descriptors cannot be added to a remote GATT characteristic.";
192 return false; 155 return false;
193 } 156 }
194 157
195 bool BluetoothRemoteGattCharacteristicBlueZ::UpdateValue( 158 bool BluetoothRemoteGattCharacteristicBlueZ::UpdateValue(
196 const std::vector<uint8_t>& value) { 159 const std::vector<uint8_t>& value) {
197 VLOG(1) << "Cannot update the value of a remote GATT characteristic."; 160 VLOG(1) << "Cannot update the value of a remote GATT characteristic.";
198 return false; 161 return false;
199 } 162 }
200 163
201 void BluetoothRemoteGattCharacteristicBlueZ::ReadRemoteCharacteristic(
202 const ValueCallback& callback,
203 const ErrorCallback& error_callback) {
204 VLOG(1) << "Sending GATT characteristic read request to characteristic: "
205 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value()
206 << ".";
207
208 bluez::BluezDBusManager::Get()
209 ->GetBluetoothGattCharacteristicClient()
210 ->ReadValue(object_path_, callback,
211 base::Bind(&BluetoothRemoteGattCharacteristicBlueZ::OnError,
212 weak_ptr_factory_.GetWeakPtr(), error_callback));
213 }
214
215 void BluetoothRemoteGattCharacteristicBlueZ::WriteRemoteCharacteristic(
216 const std::vector<uint8_t>& new_value,
217 const base::Closure& callback,
218 const ErrorCallback& error_callback) {
219 VLOG(1) << "Sending GATT characteristic write request to characteristic: "
220 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value()
221 << ", with value: " << new_value << ".";
222
223 bluez::BluezDBusManager::Get()
224 ->GetBluetoothGattCharacteristicClient()
225 ->WriteValue(object_path_, new_value, callback,
226 base::Bind(&BluetoothRemoteGattCharacteristicBlueZ::OnError,
227 weak_ptr_factory_.GetWeakPtr(), error_callback));
228 }
229
230 void BluetoothRemoteGattCharacteristicBlueZ::StartNotifySession( 164 void BluetoothRemoteGattCharacteristicBlueZ::StartNotifySession(
231 const NotifySessionCallback& callback, 165 const NotifySessionCallback& callback,
232 const ErrorCallback& error_callback) { 166 const ErrorCallback& error_callback) {
233 VLOG(1) << __func__; 167 VLOG(1) << __func__;
234 168
235 if (num_notify_sessions_ > 0) { 169 if (num_notify_sessions_ > 0) {
236 // The characteristic might have stopped notifying even though the session 170 // The characteristic might have stopped notifying even though the session
237 // count is nonzero. This means that notifications stopped outside of our 171 // count is nonzero. This means that notifications stopped outside of our
238 // control and we should reset the count. If the characteristic is still 172 // control and we should reset the count. If the characteristic is still
239 // notifying, then return success. Otherwise, reset the count and treat 173 // notifying, then return success. Otherwise, reset the count and treat
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 ->StartNotify( 206 ->StartNotify(
273 object_path_, 207 object_path_,
274 base::Bind( 208 base::Bind(
275 &BluetoothRemoteGattCharacteristicBlueZ::OnStartNotifySuccess, 209 &BluetoothRemoteGattCharacteristicBlueZ::OnStartNotifySuccess,
276 weak_ptr_factory_.GetWeakPtr(), callback), 210 weak_ptr_factory_.GetWeakPtr(), callback),
277 base::Bind( 211 base::Bind(
278 &BluetoothRemoteGattCharacteristicBlueZ::OnStartNotifyError, 212 &BluetoothRemoteGattCharacteristicBlueZ::OnStartNotifyError,
279 weak_ptr_factory_.GetWeakPtr(), error_callback)); 213 weak_ptr_factory_.GetWeakPtr(), error_callback));
280 } 214 }
281 215
216 void BluetoothRemoteGattCharacteristicBlueZ::ReadRemoteCharacteristic(
217 const ValueCallback& callback,
218 const ErrorCallback& error_callback) {
219 VLOG(1) << "Sending GATT characteristic read request to characteristic: "
220 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value()
221 << ".";
222
223 bluez::BluezDBusManager::Get()
224 ->GetBluetoothGattCharacteristicClient()
225 ->ReadValue(object_path_, callback,
226 base::Bind(&BluetoothRemoteGattCharacteristicBlueZ::OnError,
227 weak_ptr_factory_.GetWeakPtr(), error_callback));
228 }
229
230 void BluetoothRemoteGattCharacteristicBlueZ::WriteRemoteCharacteristic(
231 const std::vector<uint8_t>& new_value,
232 const base::Closure& callback,
233 const ErrorCallback& error_callback) {
234 VLOG(1) << "Sending GATT characteristic write request to characteristic: "
235 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value()
236 << ", with value: " << new_value << ".";
237
238 bluez::BluezDBusManager::Get()
239 ->GetBluetoothGattCharacteristicClient()
240 ->WriteValue(object_path_, new_value, callback,
241 base::Bind(&BluetoothRemoteGattCharacteristicBlueZ::OnError,
242 weak_ptr_factory_.GetWeakPtr(), error_callback));
243 }
244
282 void BluetoothRemoteGattCharacteristicBlueZ::RemoveNotifySession( 245 void BluetoothRemoteGattCharacteristicBlueZ::RemoveNotifySession(
283 const base::Closure& callback) { 246 const base::Closure& callback) {
284 VLOG(1) << __func__; 247 VLOG(1) << __func__;
285 248
286 if (num_notify_sessions_ > 1) { 249 if (num_notify_sessions_ > 1) {
287 DCHECK(!notify_call_pending_); 250 DCHECK(!notify_call_pending_);
288 --num_notify_sessions_; 251 --num_notify_sessions_;
289 callback.Run(); 252 callback.Run();
290 return; 253 return;
291 } 254 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 ->GetProperties(object_path); 293 ->GetProperties(object_path);
331 DCHECK(properties); 294 DCHECK(properties);
332 if (properties->characteristic.value() != object_path_) { 295 if (properties->characteristic.value() != object_path_) {
333 VLOG(3) << "Remote GATT descriptor does not belong to this characteristic."; 296 VLOG(3) << "Remote GATT descriptor does not belong to this characteristic.";
334 return; 297 return;
335 } 298 }
336 299
337 VLOG(1) << "Adding new remote GATT descriptor for GATT characteristic: " 300 VLOG(1) << "Adding new remote GATT descriptor for GATT characteristic: "
338 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value(); 301 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
339 302
340 BluetoothRemoteGattDescriptorBlueZ* descriptor = 303 BluetoothGattDescriptorBlueZ* descriptor =
341 new BluetoothRemoteGattDescriptorBlueZ(this, object_path); 304 new BluetoothGattDescriptorBlueZ(this, object_path, false /* is_local */);
342 descriptors_[object_path] = descriptor; 305 descriptors_[object_path] = descriptor;
343 DCHECK(descriptor->GetIdentifier() == object_path.value()); 306 DCHECK(descriptor->GetIdentifier() == object_path.value());
344 DCHECK(descriptor->GetUUID().IsValid()); 307 DCHECK(descriptor->GetUUID().IsValid());
345 DCHECK(service_); 308 DCHECK(service_);
346 309
347 service_->NotifyDescriptorAddedOrRemoved(this, descriptor, true /* added */); 310 service_->NotifyDescriptorAddedOrRemoved(this, descriptor, true /* added */);
348 } 311 }
349 312
350 void BluetoothRemoteGattCharacteristicBlueZ::GattDescriptorRemoved( 313 void BluetoothRemoteGattCharacteristicBlueZ::GattDescriptorRemoved(
351 const dbus::ObjectPath& object_path) { 314 const dbus::ObjectPath& object_path) {
352 DescriptorMap::iterator iter = descriptors_.find(object_path); 315 DescriptorMap::iterator iter = descriptors_.find(object_path);
353 if (iter == descriptors_.end()) { 316 if (iter == descriptors_.end()) {
354 VLOG(2) << "Unknown descriptor removed: " << object_path.value(); 317 VLOG(2) << "Unknown descriptor removed: " << object_path.value();
355 return; 318 return;
356 } 319 }
357 320
358 VLOG(1) << "Removing remote GATT descriptor from characteristic: " 321 VLOG(1) << "Removing remote GATT descriptor from characteristic: "
359 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value(); 322 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
360 323
361 BluetoothRemoteGattDescriptorBlueZ* descriptor = iter->second; 324 BluetoothGattDescriptorBlueZ* descriptor = iter->second;
362 DCHECK(descriptor->object_path() == object_path); 325 DCHECK(descriptor->object_path() == object_path);
363 descriptors_.erase(iter); 326 descriptors_.erase(iter);
364 327
365 DCHECK(service_); 328 DCHECK(service_);
366 service_->NotifyDescriptorAddedOrRemoved(this, descriptor, false /* added */); 329 service_->NotifyDescriptorAddedOrRemoved(this, descriptor, false /* added */);
367 330
368 delete descriptor; 331 delete descriptor;
369 } 332 }
370 333
371 void BluetoothRemoteGattCharacteristicBlueZ::GattDescriptorPropertyChanged( 334 void BluetoothRemoteGattCharacteristicBlueZ::GattDescriptorPropertyChanged(
(...skipping 13 matching lines...) Expand all
385 DCHECK(properties); 348 DCHECK(properties);
386 349
387 if (property_name != properties->value.name()) 350 if (property_name != properties->value.name())
388 return; 351 return;
389 352
390 DCHECK(service_); 353 DCHECK(service_);
391 service_->NotifyDescriptorValueChanged(this, iter->second, 354 service_->NotifyDescriptorValueChanged(this, iter->second,
392 properties->value.value()); 355 properties->value.value());
393 } 356 }
394 357
395 void BluetoothRemoteGattCharacteristicBlueZ::OnError(
396 const ErrorCallback& error_callback,
397 const std::string& error_name,
398 const std::string& error_message) {
399 VLOG(1) << "Operation failed: " << error_name
400 << ", message: " << error_message;
401 error_callback.Run(
402 BluetoothRemoteGattServiceBlueZ::DBusErrorToServiceError(error_name));
403 }
404
405 void BluetoothRemoteGattCharacteristicBlueZ::OnStartNotifySuccess( 358 void BluetoothRemoteGattCharacteristicBlueZ::OnStartNotifySuccess(
406 const NotifySessionCallback& callback) { 359 const NotifySessionCallback& callback) {
407 VLOG(1) << "Started notifications from characteristic: " 360 VLOG(1) << "Started notifications from characteristic: "
408 << object_path_.value(); 361 << object_path_.value();
409 DCHECK(num_notify_sessions_ == 0); 362 DCHECK(num_notify_sessions_ == 0);
410 DCHECK(notify_call_pending_); 363 DCHECK(notify_call_pending_);
411 364
412 ++num_notify_sessions_; 365 ++num_notify_sessions_;
413 notify_call_pending_ = false; 366 notify_call_pending_ = false;
414 367
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 } 420 }
468 421
469 void BluetoothRemoteGattCharacteristicBlueZ::ProcessStartNotifyQueue() { 422 void BluetoothRemoteGattCharacteristicBlueZ::ProcessStartNotifyQueue() {
470 while (!pending_start_notify_calls_.empty()) { 423 while (!pending_start_notify_calls_.empty()) {
471 PendingStartNotifyCall callbacks = pending_start_notify_calls_.front(); 424 PendingStartNotifyCall callbacks = pending_start_notify_calls_.front();
472 pending_start_notify_calls_.pop(); 425 pending_start_notify_calls_.pop();
473 StartNotifySession(callbacks.first, callbacks.second); 426 StartNotifySession(callbacks.first, callbacks.second);
474 } 427 }
475 } 428 }
476 429
430 void BluetoothRemoteGattCharacteristicBlueZ::OnError(
431 const ErrorCallback& error_callback,
432 const std::string& error_name,
433 const std::string& error_message) {
434 VLOG(1) << "Operation failed: " << error_name
435 << ", message: " << error_message;
436 error_callback.Run(
437 BluetoothGattServiceBlueZ::DBusErrorToServiceError(error_name));
438 }
439
477 } // namespace bluez 440 } // namespace bluez
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698