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
3 // found in the LICENSE file.
5 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
7 #include "base/logging.h"
8 #include "base/strings/stringprintf.h"
9 #include "chromeos/dbus/dbus_thread_manager.h"
10 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h"
11 #include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h"
12 #include "third_party/cros_system_api/dbus/service_constants.h"
18 // Stream operator for logging vector<uint8>.
19 std::ostream
& operator<<(std::ostream
& out
, const std::vector
<uint8
> bytes
) {
21 for (std::vector
<uint8
>::const_iterator iter
= bytes
.begin();
22 iter
!= bytes
.end(); ++iter
) {
23 out
<< base::StringPrintf("%02X", *iter
);
30 BluetoothRemoteGattCharacteristicChromeOS::
31 BluetoothRemoteGattCharacteristicChromeOS(
32 BluetoothRemoteGattServiceChromeOS
* service
,
33 const dbus::ObjectPath
& object_path
)
34 : object_path_(object_path
),
36 weak_ptr_factory_(this) {
37 VLOG(1) << "Creating remote GATT characteristic with identifier: "
38 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
39 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
41 DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->
44 // Add all known GATT characteristic descriptors.
45 const std::vector
<dbus::ObjectPath
>& gatt_descs
=
46 DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->
48 for (std::vector
<dbus::ObjectPath
>::const_iterator iter
= gatt_descs
.begin();
49 iter
!= gatt_descs
.end(); ++iter
)
50 GattDescriptorAdded(*iter
);
53 BluetoothRemoteGattCharacteristicChromeOS::
54 ~BluetoothRemoteGattCharacteristicChromeOS() {
55 DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->
57 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
60 // Clean up all the descriptors. There isn't much point in notifying service
61 // observers for each descriptor that gets removed, so just delete them.
62 for (DescriptorMap::iterator iter
= descriptors_
.begin();
63 iter
!= descriptors_
.end(); ++iter
)
67 std::string
BluetoothRemoteGattCharacteristicChromeOS::GetIdentifier() const {
68 return object_path_
.value();
72 BluetoothRemoteGattCharacteristicChromeOS::GetUUID() const {
73 BluetoothGattCharacteristicClient::Properties
* properties
=
74 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
75 GetProperties(object_path_
);
77 return device::BluetoothUUID(properties
->uuid
.value());
80 bool BluetoothRemoteGattCharacteristicChromeOS::IsLocal() const {
84 const std::vector
<uint8
>&
85 BluetoothRemoteGattCharacteristicChromeOS::GetValue() const {
89 device::BluetoothGattService
*
90 BluetoothRemoteGattCharacteristicChromeOS::GetService() const {
94 device::BluetoothGattCharacteristic::Properties
95 BluetoothRemoteGattCharacteristicChromeOS::GetProperties() const {
96 BluetoothGattCharacteristicClient::Properties
* properties
=
97 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
98 GetProperties(object_path_
);
101 Properties props
= kPropertyNone
;
102 const std::vector
<std::string
>& flags
= properties
->flags
.value();
103 for (std::vector
<std::string
>::const_iterator iter
= flags
.begin();
106 if (*iter
== bluetooth_gatt_characteristic::kFlagBroadcast
)
107 props
|= kPropertyBroadcast
;
108 if (*iter
== bluetooth_gatt_characteristic::kFlagRead
)
109 props
|= kPropertyRead
;
110 if (*iter
== bluetooth_gatt_characteristic::kFlagWriteWithoutResponse
)
111 props
|= kPropertyWriteWithoutResponse
;
112 if (*iter
== bluetooth_gatt_characteristic::kFlagWrite
)
113 props
|= kPropertyWrite
;
114 if (*iter
== bluetooth_gatt_characteristic::kFlagNotify
)
115 props
|= kPropertyNotify
;
116 if (*iter
== bluetooth_gatt_characteristic::kFlagIndicate
)
117 props
|= kPropertyIndicate
;
118 if (*iter
== bluetooth_gatt_characteristic::kFlagAuthenticatedSignedWrites
)
119 props
|= kPropertyAuthenticatedSignedWrites
;
120 if (*iter
== bluetooth_gatt_characteristic::kFlagExtendedProperties
)
121 props
|= kPropertyExtendedProperties
;
122 if (*iter
== bluetooth_gatt_characteristic::kFlagReliableWrite
)
123 props
|= kPropertyReliableWrite
;
124 if (*iter
== bluetooth_gatt_characteristic::kFlagWritableAuxiliaries
)
125 props
|= kPropertyWritableAuxiliaries
;
131 device::BluetoothGattCharacteristic::Permissions
132 BluetoothRemoteGattCharacteristicChromeOS::GetPermissions() const {
133 // TODO(armansito): Once BlueZ defines the permissions, return the correct
135 return kPermissionNone
;
138 std::vector
<device::BluetoothGattDescriptor
*>
139 BluetoothRemoteGattCharacteristicChromeOS::GetDescriptors() const {
140 std::vector
<device::BluetoothGattDescriptor
*> descriptors
;
141 for (DescriptorMap::const_iterator iter
= descriptors_
.begin();
142 iter
!= descriptors_
.end(); ++iter
)
143 descriptors
.push_back(iter
->second
);
147 device::BluetoothGattDescriptor
*
148 BluetoothRemoteGattCharacteristicChromeOS::GetDescriptor(
149 const std::string
& identifier
) const {
150 DescriptorMap::const_iterator iter
=
151 descriptors_
.find(dbus::ObjectPath(identifier
));
152 if (iter
== descriptors_
.end())
157 bool BluetoothRemoteGattCharacteristicChromeOS::AddDescriptor(
158 device::BluetoothGattDescriptor
* descriptor
) {
159 VLOG(1) << "Descriptors cannot be added to a remote GATT characteristic.";
163 bool BluetoothRemoteGattCharacteristicChromeOS::UpdateValue(
164 const std::vector
<uint8
>& value
) {
165 VLOG(1) << "Cannot update the value of a remote GATT characteristic.";
169 void BluetoothRemoteGattCharacteristicChromeOS::ReadRemoteCharacteristic(
170 const ValueCallback
& callback
,
171 const ErrorCallback
& error_callback
) {
172 VLOG(1) << "Sending GATT characteristic read request to characteristic: "
173 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value()
176 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->ReadValue(
178 base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnValueSuccess
,
179 weak_ptr_factory_
.GetWeakPtr(),
181 base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnError
,
182 weak_ptr_factory_
.GetWeakPtr(),
186 void BluetoothRemoteGattCharacteristicChromeOS::WriteRemoteCharacteristic(
187 const std::vector
<uint8
>& new_value
,
188 const base::Closure
& callback
,
189 const ErrorCallback
& error_callback
) {
190 VLOG(1) << "Sending GATT characteristic write request to characteristic: "
191 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value()
192 << ", with value: " << new_value
<< ".";
194 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->WriteValue(
198 base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnError
,
199 weak_ptr_factory_
.GetWeakPtr(),
203 void BluetoothRemoteGattCharacteristicChromeOS::GattCharacteristicValueUpdated(
204 const dbus::ObjectPath
& object_path
,
205 const std::vector
<uint8
>& value
) {
206 if (object_path
!= object_path_
)
209 cached_value_
= value
;
211 VLOG(1) << "GATT characteristic value has changed: " << object_path
.value()
214 service_
->NotifyCharacteristicValueChanged(this, value
);
217 void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorAdded(
218 const dbus::ObjectPath
& object_path
) {
219 if (descriptors_
.find(object_path
) != descriptors_
.end()) {
220 VLOG(1) << "Remote GATT characteristic descriptor already exists: "
221 << object_path
.value();
225 BluetoothGattDescriptorClient::Properties
* properties
=
226 DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->
227 GetProperties(object_path
);
229 if (properties
->characteristic
.value() != object_path_
) {
230 VLOG(2) << "Remote GATT descriptor does not belong to this characteristic.";
234 VLOG(1) << "Adding new remote GATT descriptor for GATT characteristic: "
235 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
237 BluetoothRemoteGattDescriptorChromeOS
* descriptor
=
238 new BluetoothRemoteGattDescriptorChromeOS(this, object_path
);
239 descriptors_
[object_path
] = descriptor
;
240 DCHECK(descriptor
->GetIdentifier() == object_path
.value());
241 DCHECK(descriptor
->GetUUID().IsValid());
244 service_
->NotifyDescriptorAddedOrRemoved(this, descriptor
, true /* added */);
245 service_
->NotifyServiceChanged();
248 void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorRemoved(
249 const dbus::ObjectPath
& object_path
) {
250 DescriptorMap::iterator iter
= descriptors_
.find(object_path
);
251 if (iter
== descriptors_
.end()) {
252 VLOG(2) << "Unknown descriptor removed: " << object_path
.value();
256 VLOG(1) << "Removing remote GATT descriptor from characteristic: "
257 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
259 BluetoothRemoteGattDescriptorChromeOS
* descriptor
= iter
->second
;
260 DCHECK(descriptor
->object_path() == object_path
);
261 descriptors_
.erase(iter
);
263 service_
->NotifyDescriptorAddedOrRemoved(this, descriptor
, false /* added */);
268 service_
->NotifyServiceChanged();
271 void BluetoothRemoteGattCharacteristicChromeOS::OnValueSuccess(
272 const ValueCallback
& callback
,
273 const std::vector
<uint8
>& value
) {
274 VLOG(1) << "Characteristic value read: " << value
;
275 cached_value_
= value
;
278 service_
->NotifyCharacteristicValueChanged(this, cached_value_
);
283 void BluetoothRemoteGattCharacteristicChromeOS::OnError(
284 const ErrorCallback
& error_callback
,
285 const std::string
& error_name
,
286 const std::string
& error_message
) {
287 VLOG(1) << "Operation failed: " << error_name
<< ", message: "
289 error_callback
.Run();
292 } // namespace chromeos