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/bluetooth_gatt_characteristic_client.h"
10 #include "chromeos/dbus/dbus_thread_manager.h"
11 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h"
12 #include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.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()->GetBluetoothGattDescriptorClient()->
42 // Add all known GATT characteristic descriptors.
43 const std::vector
<dbus::ObjectPath
>& gatt_descs
=
44 DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->
46 for (std::vector
<dbus::ObjectPath
>::const_iterator iter
= gatt_descs
.begin();
47 iter
!= gatt_descs
.end(); ++iter
)
48 GattDescriptorAdded(*iter
);
51 BluetoothRemoteGattCharacteristicChromeOS::
52 ~BluetoothRemoteGattCharacteristicChromeOS() {
53 DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->
56 // Clean up all the descriptors. There isn't much point in notifying service
57 // observers for each descriptor that gets removed, so just delete them.
58 for (DescriptorMap::iterator iter
= descriptors_
.begin();
59 iter
!= descriptors_
.end(); ++iter
)
63 std::string
BluetoothRemoteGattCharacteristicChromeOS::GetIdentifier() const {
64 return object_path_
.value();
68 BluetoothRemoteGattCharacteristicChromeOS::GetUUID() const {
69 BluetoothGattCharacteristicClient::Properties
* properties
=
70 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
71 GetProperties(object_path_
);
73 return device::BluetoothUUID(properties
->uuid
.value());
76 bool BluetoothRemoteGattCharacteristicChromeOS::IsLocal() const {
80 const std::vector
<uint8
>&
81 BluetoothRemoteGattCharacteristicChromeOS::GetValue() const {
82 BluetoothGattCharacteristicClient::Properties
* properties
=
83 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
84 GetProperties(object_path_
);
86 return properties
->value
.value();
89 device::BluetoothGattService
*
90 BluetoothRemoteGattCharacteristicChromeOS::GetService() const {
94 device::BluetoothGattCharacteristic::Properties
95 BluetoothRemoteGattCharacteristicChromeOS::GetProperties() const {
96 // TODO(armansito): Once BlueZ implements properties properly, return those
101 device::BluetoothGattCharacteristic::Permissions
102 BluetoothRemoteGattCharacteristicChromeOS::GetPermissions() const {
103 // TODO(armansito): Once BlueZ defines the permissions, return the correct
105 return kPermissionNone
;
108 std::vector
<device::BluetoothGattDescriptor
*>
109 BluetoothRemoteGattCharacteristicChromeOS::GetDescriptors() const {
110 std::vector
<device::BluetoothGattDescriptor
*> descriptors
;
111 for (DescriptorMap::const_iterator iter
= descriptors_
.begin();
112 iter
!= descriptors_
.end(); ++iter
)
113 descriptors
.push_back(iter
->second
);
117 bool BluetoothRemoteGattCharacteristicChromeOS::AddDescriptor(
118 device::BluetoothGattDescriptor
* descriptor
) {
119 VLOG(1) << "Descriptors cannot be added to a remote GATT characteristic.";
123 bool BluetoothRemoteGattCharacteristicChromeOS::UpdateValue(
124 const std::vector
<uint8
>& value
) {
125 VLOG(1) << "Cannot update the value of a remote GATT characteristic.";
129 void BluetoothRemoteGattCharacteristicChromeOS::ReadRemoteCharacteristic(
130 const ValueCallback
& callback
,
131 const ErrorCallback
& error_callback
) {
132 VLOG(1) << "Sending GATT characteristic read request to characteristic: "
133 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value()
135 BluetoothGattCharacteristicClient::Properties
* properties
=
136 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
137 GetProperties(object_path_
);
139 properties
->value
.Get(
140 base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnGetValue
,
141 weak_ptr_factory_
.GetWeakPtr(),
142 callback
, error_callback
));
145 void BluetoothRemoteGattCharacteristicChromeOS::WriteRemoteCharacteristic(
146 const std::vector
<uint8
>& new_value
,
147 const base::Closure
& callback
,
148 const ErrorCallback
& error_callback
) {
149 VLOG(1) << "Sending GATT characteristic write request to characteristic: "
150 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value()
151 << ", with value: " << new_value
<< ".";
153 // Permission and bonding are handled by BlueZ so no need check it here.
154 if (new_value
.empty()) {
155 VLOG(1) << "Nothing to write.";
156 error_callback
.Run();
160 BluetoothGattCharacteristicClient::Properties
* properties
=
161 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
162 GetProperties(object_path_
);
164 properties
->value
.Set(
166 base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnSetValue
,
167 weak_ptr_factory_
.GetWeakPtr(),
168 callback
, error_callback
));
171 void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorAdded(
172 const dbus::ObjectPath
& object_path
) {
173 if (descriptors_
.find(object_path
) != descriptors_
.end()) {
174 VLOG(1) << "Remote GATT characteristic descriptor already exists: "
175 << object_path
.value();
179 BluetoothGattDescriptorClient::Properties
* properties
=
180 DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->
181 GetProperties(object_path
);
183 if (properties
->characteristic
.value() != object_path_
) {
184 VLOG(2) << "Remote GATT descriptor does not belong to this characteristic.";
188 VLOG(1) << "Adding new remote GATT descriptor for GATT characteristic: "
189 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
191 BluetoothRemoteGattDescriptorChromeOS
* descriptor
=
192 new BluetoothRemoteGattDescriptorChromeOS(this, object_path
);
193 descriptors_
[object_path
] = descriptor
;
194 DCHECK(descriptor
->GetIdentifier() == object_path
.value());
195 DCHECK(descriptor
->GetUUID().IsValid());
197 service_
->NotifyServiceChanged();
200 void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorRemoved(
201 const dbus::ObjectPath
& object_path
) {
202 DescriptorMap::iterator iter
= descriptors_
.find(object_path
);
203 if (iter
== descriptors_
.end()) {
204 VLOG(2) << "Unknown descriptor removed: " << object_path
.value();
208 VLOG(1) << "Removing remote GATT descriptor from characteristic: "
209 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
211 BluetoothRemoteGattDescriptorChromeOS
* descriptor
= iter
->second
;
212 DCHECK(descriptor
->object_path() == object_path
);
213 descriptors_
.erase(iter
);
217 service_
->NotifyServiceChanged();
220 void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorPropertyChanged(
221 const dbus::ObjectPath
& object_path
,
222 const std::string
& property_name
) {
223 DescriptorMap::const_iterator iter
= descriptors_
.find(object_path
);
224 if (iter
== descriptors_
.end())
227 VLOG(1) << "GATT descriptor property changed: " << object_path
.value()
228 << ", property: " << property_name
;
231 void BluetoothRemoteGattCharacteristicChromeOS::OnGetValue(
232 const ValueCallback
& callback
,
233 const ErrorCallback
& error_callback
,
236 VLOG(1) << "Failed to read the value from the remote characteristic.";
237 error_callback
.Run();
241 VLOG(1) << "Read value of remote characteristic.";
242 BluetoothGattCharacteristicClient::Properties
* properties
=
243 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
244 GetProperties(object_path_
);
246 callback
.Run(properties
->value
.value());
249 void BluetoothRemoteGattCharacteristicChromeOS::OnSetValue(
250 const base::Closure
& callback
,
251 const ErrorCallback
& error_callback
,
254 VLOG(1) << "Failed to write the value of remote characteristic.";
255 error_callback
.Run();
259 VLOG(1) << "Wrote value of remote characteristic.";
263 } // namespace chromeos