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_service_chromeos.h"
7 #include "base/logging.h"
8 #include "base/strings/stringprintf.h"
9 #include "chromeos/dbus/bluetooth_gatt_service_client.h"
10 #include "chromeos/dbus/dbus_thread_manager.h"
11 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
17 // Stream operator for logging vector<uint8>.
18 std::ostream
& operator<<(std::ostream
& out
, const std::vector
<uint8
> bytes
) {
20 for (std::vector
<uint8
>::const_iterator iter
= bytes
.begin();
21 iter
!= bytes
.end(); ++iter
) {
22 out
<< base::StringPrintf("%02X", *iter
);
29 BluetoothRemoteGattServiceChromeOS::BluetoothRemoteGattServiceChromeOS(
30 BluetoothDeviceChromeOS
* device
,
31 const dbus::ObjectPath
& object_path
)
32 : object_path_(object_path
),
34 weak_ptr_factory_(this) {
35 VLOG(1) << "Creating remote GATT service with identifier: "
36 << object_path
.value() << ", UUID: " << GetUUID().canonical_value();
37 DBusThreadManager::Get()->GetBluetoothGattServiceClient()->AddObserver(this);
38 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
41 // Add all known GATT characteristics.
42 const std::vector
<dbus::ObjectPath
>& gatt_chars
=
43 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
45 for (std::vector
<dbus::ObjectPath
>::const_iterator iter
= gatt_chars
.begin();
46 iter
!= gatt_chars
.end(); ++iter
)
47 GattCharacteristicAdded(*iter
);
50 BluetoothRemoteGattServiceChromeOS::~BluetoothRemoteGattServiceChromeOS() {
51 DBusThreadManager::Get()->GetBluetoothGattServiceClient()->
53 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
56 // Clean up all the characteristics. Copy the characteristics list here and
57 // clear the original so that when we send GattCharacteristicRemoved(),
58 // GetCharacteristics() returns no characteristics.
59 CharacteristicMap characteristics
= characteristics_
;
60 characteristics_
.clear();
61 for (CharacteristicMap::iterator iter
= characteristics
.begin();
62 iter
!= characteristics
.end(); ++iter
) {
63 FOR_EACH_OBSERVER(device::BluetoothGattService::Observer
, observers_
,
64 GattCharacteristicRemoved(this, iter
->second
));
69 void BluetoothRemoteGattServiceChromeOS::AddObserver(
70 device::BluetoothGattService::Observer
* observer
) {
72 observers_
.AddObserver(observer
);
75 void BluetoothRemoteGattServiceChromeOS::RemoveObserver(
76 device::BluetoothGattService::Observer
* observer
) {
78 observers_
.RemoveObserver(observer
);
81 std::string
BluetoothRemoteGattServiceChromeOS::GetIdentifier() const {
82 return object_path_
.value();
85 device::BluetoothUUID
BluetoothRemoteGattServiceChromeOS::GetUUID() const {
86 BluetoothGattServiceClient::Properties
* properties
=
87 DBusThreadManager::Get()->GetBluetoothGattServiceClient()->
88 GetProperties(object_path_
);
90 return device::BluetoothUUID(properties
->uuid
.value());
93 bool BluetoothRemoteGattServiceChromeOS::IsLocal() const {
97 bool BluetoothRemoteGattServiceChromeOS::IsPrimary() const {
98 BluetoothGattServiceClient::Properties
* properties
=
99 DBusThreadManager::Get()->GetBluetoothGattServiceClient()->
100 GetProperties(object_path_
);
102 return properties
->primary
.value();
105 std::vector
<device::BluetoothGattCharacteristic
*>
106 BluetoothRemoteGattServiceChromeOS::GetCharacteristics() const {
107 std::vector
<device::BluetoothGattCharacteristic
*> characteristics
;
108 for (CharacteristicMap::const_iterator iter
= characteristics_
.begin();
109 iter
!= characteristics_
.end(); ++iter
) {
110 characteristics
.push_back(iter
->second
);
112 return characteristics
;
115 std::vector
<device::BluetoothGattService
*>
116 BluetoothRemoteGattServiceChromeOS::GetIncludedServices() const {
117 // TODO(armansito): Return the actual included services here.
118 return std::vector
<device::BluetoothGattService
*>();
121 device::BluetoothGattCharacteristic
*
122 BluetoothRemoteGattServiceChromeOS::GetCharacteristic(
123 const std::string
& identifier
) {
124 CharacteristicMap::const_iterator iter
=
125 characteristics_
.find(dbus::ObjectPath(identifier
));
126 if (iter
== characteristics_
.end())
131 bool BluetoothRemoteGattServiceChromeOS::AddCharacteristic(
132 device::BluetoothGattCharacteristic
* characteristic
) {
133 VLOG(1) << "Characteristics cannot be added to a remote GATT service.";
137 bool BluetoothRemoteGattServiceChromeOS::AddIncludedService(
138 device::BluetoothGattService
* service
) {
139 VLOG(1) << "Included services cannot be added to a remote GATT service.";
143 void BluetoothRemoteGattServiceChromeOS::Register(
144 const base::Closure
& callback
,
145 const ErrorCallback
& error_callback
) {
146 VLOG(1) << "A remote GATT service cannot be registered.";
147 error_callback
.Run();
150 void BluetoothRemoteGattServiceChromeOS::Unregister(
151 const base::Closure
& callback
,
152 const ErrorCallback
& error_callback
) {
153 VLOG(1) << "A remote GATT service cannot be unregistered.";
154 error_callback
.Run();
157 void BluetoothRemoteGattServiceChromeOS::NotifyServiceChanged() {
158 FOR_EACH_OBSERVER(device::BluetoothGattService::Observer
, observers_
,
159 GattServiceChanged(this));
162 void BluetoothRemoteGattServiceChromeOS::GattServicePropertyChanged(
163 const dbus::ObjectPath
& object_path
,
164 const std::string
& property_name
){
165 NotifyServiceChanged();
168 void BluetoothRemoteGattServiceChromeOS::GattCharacteristicAdded(
169 const dbus::ObjectPath
& object_path
) {
170 if (characteristics_
.find(object_path
) != characteristics_
.end()) {
171 VLOG(1) << "Remote GATT characteristic already exists: "
172 << object_path
.value();
176 BluetoothGattCharacteristicClient::Properties
* properties
=
177 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
178 GetProperties(object_path
);
180 if (properties
->service
.value() != object_path_
) {
181 VLOG(2) << "Remote GATT characteristic does not belong to this service.";
185 VLOG(1) << "Adding new remote GATT characteristic for GATT service: "
186 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
188 BluetoothRemoteGattCharacteristicChromeOS
* characteristic
=
189 new BluetoothRemoteGattCharacteristicChromeOS(this, object_path
);
190 characteristics_
[object_path
] = characteristic
;
191 DCHECK(characteristic
->GetIdentifier() == object_path
.value());
192 DCHECK(characteristic
->GetUUID().IsValid());
194 FOR_EACH_OBSERVER(device::BluetoothGattService::Observer
, observers_
,
195 GattCharacteristicAdded(this, characteristic
));
196 NotifyServiceChanged();
199 void BluetoothRemoteGattServiceChromeOS::GattCharacteristicRemoved(
200 const dbus::ObjectPath
& object_path
) {
201 CharacteristicMap::iterator iter
= characteristics_
.find(object_path
);
202 if (iter
== characteristics_
.end()) {
203 VLOG(2) << "Unknown GATT characteristic removed: " << object_path
.value();
207 VLOG(1) << "Removing remote GATT characteristic from service: "
208 << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
210 BluetoothRemoteGattCharacteristicChromeOS
* characteristic
= iter
->second
;
211 DCHECK(characteristic
->object_path() == object_path
);
212 characteristics_
.erase(iter
);
214 FOR_EACH_OBSERVER(device::BluetoothGattService::Observer
, observers_
,
215 GattCharacteristicRemoved(this, characteristic
));
216 NotifyServiceChanged();
218 delete characteristic
;
221 void BluetoothRemoteGattServiceChromeOS::GattCharacteristicPropertyChanged(
222 const dbus::ObjectPath
& object_path
,
223 const std::string
& property_name
) {
224 CharacteristicMap::iterator iter
= characteristics_
.find(object_path
);
225 if (iter
== characteristics_
.end()) {
226 VLOG(2) << "Unknown GATT characteristic property changed: "
227 << object_path
.value();
231 // Ignore all property changes except for "Value".
232 BluetoothGattCharacteristicClient::Properties
* properties
=
233 DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->
234 GetProperties(object_path
);
236 if (property_name
!= properties
->value
.name())
239 VLOG(1) << "GATT characteristic value has changed: " << object_path
.value()
240 << ": " << properties
->value
.value();
241 FOR_EACH_OBSERVER(device::BluetoothGattService::Observer
, observers_
,
242 GattCharacteristicValueChanged(this, iter
->second
,
243 properties
->value
.value()));
246 } // namespace chromeos