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 "chromeos/dbus/bluetooth_gatt_characteristic_client.h"
8 #include "base/memory/weak_ptr.h"
9 #include "base/observer_list.h"
11 #include "dbus/object_manager.h"
12 #include "third_party/cros_system_api/dbus/service_constants.h"
18 // TODO(armansito): Move this constant to cros_system_api.
19 const char kValueProperty
[] = "Value";
24 const char BluetoothGattCharacteristicClient::kNoResponseError
[] =
25 "org.chromium.Error.NoResponse";
27 const char BluetoothGattCharacteristicClient::kUnknownCharacteristicError
[] =
28 "org.chromium.Error.UnknownCharacteristic";
30 BluetoothGattCharacteristicClient::Properties::Properties(
31 dbus::ObjectProxy
* object_proxy
,
32 const std::string
& interface_name
,
33 const PropertyChangedCallback
& callback
)
34 : dbus::PropertySet(object_proxy
, interface_name
, callback
) {
35 RegisterProperty(bluetooth_gatt_characteristic::kUUIDProperty
, &uuid
);
36 RegisterProperty(bluetooth_gatt_characteristic::kServiceProperty
, &service
);
37 RegisterProperty(kValueProperty
, &value
);
38 RegisterProperty(bluetooth_gatt_characteristic::kNotifyingProperty
,
40 RegisterProperty(bluetooth_gatt_characteristic::kFlagsProperty
, &flags
);
41 RegisterProperty(bluetooth_gatt_characteristic::kDescriptorsProperty
,
45 BluetoothGattCharacteristicClient::Properties::~Properties() {
48 // The BluetoothGattCharacteristicClient implementation used in production.
49 class BluetoothGattCharacteristicClientImpl
50 : public BluetoothGattCharacteristicClient
,
51 public dbus::ObjectManager::Interface
{
53 BluetoothGattCharacteristicClientImpl()
54 : object_manager_(NULL
),
55 weak_ptr_factory_(this) {
58 ~BluetoothGattCharacteristicClientImpl() override
{
59 object_manager_
->UnregisterInterface(
60 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface
);
63 // BluetoothGattCharacteristicClient override.
65 BluetoothGattCharacteristicClient::Observer
* observer
) override
{
67 observers_
.AddObserver(observer
);
70 // BluetoothGattCharacteristicClient override.
72 BluetoothGattCharacteristicClient::Observer
* observer
) override
{
74 observers_
.RemoveObserver(observer
);
77 // BluetoothGattCharacteristicClient override.
78 std::vector
<dbus::ObjectPath
> GetCharacteristics() override
{
79 DCHECK(object_manager_
);
80 return object_manager_
->GetObjectsWithInterface(
81 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface
);
84 // BluetoothGattCharacteristicClient override.
85 Properties
* GetProperties(const dbus::ObjectPath
& object_path
) override
{
86 DCHECK(object_manager_
);
87 return static_cast<Properties
*>(
88 object_manager_
->GetProperties(
90 bluetooth_gatt_characteristic::
91 kBluetoothGattCharacteristicInterface
));
94 // BluetoothGattCharacteristicClient override.
95 void ReadValue(const dbus::ObjectPath
& object_path
,
96 const ValueCallback
& callback
,
97 const ErrorCallback
& error_callback
) override
{
98 dbus::ObjectProxy
* object_proxy
=
99 object_manager_
->GetObjectProxy(object_path
);
101 error_callback
.Run(kUnknownCharacteristicError
, "");
105 dbus::MethodCall
method_call(
106 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface
,
107 bluetooth_gatt_characteristic::kReadValue
);
109 object_proxy
->CallMethodWithErrorCallback(
111 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
112 base::Bind(&BluetoothGattCharacteristicClientImpl::OnValueSuccess
,
113 weak_ptr_factory_
.GetWeakPtr(),
115 base::Bind(&BluetoothGattCharacteristicClientImpl::OnError
,
116 weak_ptr_factory_
.GetWeakPtr(),
120 // BluetoothGattCharacteristicClient override.
121 void WriteValue(const dbus::ObjectPath
& object_path
,
122 const std::vector
<uint8
>& value
,
123 const base::Closure
& callback
,
124 const ErrorCallback
& error_callback
) override
{
125 dbus::ObjectProxy
* object_proxy
=
126 object_manager_
->GetObjectProxy(object_path
);
128 error_callback
.Run(kUnknownCharacteristicError
, "");
132 dbus::MethodCall
method_call(
133 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface
,
134 bluetooth_gatt_characteristic::kWriteValue
);
135 dbus::MessageWriter
writer(&method_call
);
136 writer
.AppendArrayOfBytes(value
.data(), value
.size());
138 object_proxy
->CallMethodWithErrorCallback(
140 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
141 base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess
,
142 weak_ptr_factory_
.GetWeakPtr(),
144 base::Bind(&BluetoothGattCharacteristicClientImpl::OnError
,
145 weak_ptr_factory_
.GetWeakPtr(),
149 // BluetoothGattCharacteristicClient override.
150 void StartNotify(const dbus::ObjectPath
& object_path
,
151 const base::Closure
& callback
,
152 const ErrorCallback
& error_callback
) override
{
153 dbus::ObjectProxy
* object_proxy
=
154 object_manager_
->GetObjectProxy(object_path
);
156 error_callback
.Run(kUnknownCharacteristicError
, "");
160 dbus::MethodCall
method_call(
161 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface
,
162 bluetooth_gatt_characteristic::kStartNotify
);
164 object_proxy
->CallMethodWithErrorCallback(
166 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
167 base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess
,
168 weak_ptr_factory_
.GetWeakPtr(),
170 base::Bind(&BluetoothGattCharacteristicClientImpl::OnError
,
171 weak_ptr_factory_
.GetWeakPtr(),
175 // BluetoothGattCharacteristicClient override.
176 void StopNotify(const dbus::ObjectPath
& object_path
,
177 const base::Closure
& callback
,
178 const ErrorCallback
& error_callback
) override
{
179 dbus::ObjectProxy
* object_proxy
=
180 object_manager_
->GetObjectProxy(object_path
);
182 error_callback
.Run(kUnknownCharacteristicError
, "");
186 dbus::MethodCall
method_call(
187 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface
,
188 bluetooth_gatt_characteristic::kStopNotify
);
190 object_proxy
->CallMethodWithErrorCallback(
192 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
193 base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess
,
194 weak_ptr_factory_
.GetWeakPtr(),
196 base::Bind(&BluetoothGattCharacteristicClientImpl::OnError
,
197 weak_ptr_factory_
.GetWeakPtr(),
201 // dbus::ObjectManager::Interface override.
202 dbus::PropertySet
* CreateProperties(
203 dbus::ObjectProxy
* object_proxy
,
204 const dbus::ObjectPath
& object_path
,
205 const std::string
& interface_name
) override
{
206 Properties
* properties
= new Properties(
209 base::Bind(&BluetoothGattCharacteristicClientImpl::OnPropertyChanged
,
210 weak_ptr_factory_
.GetWeakPtr(),
212 return static_cast<dbus::PropertySet
*>(properties
);
215 // dbus::ObjectManager::Interface override.
216 void ObjectAdded(const dbus::ObjectPath
& object_path
,
217 const std::string
& interface_name
) override
{
218 VLOG(2) << "Remote GATT characteristic added: " << object_path
.value();
219 FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer
, observers_
,
220 GattCharacteristicAdded(object_path
));
223 // dbus::ObjectManager::Interface override.
224 void ObjectRemoved(const dbus::ObjectPath
& object_path
,
225 const std::string
& interface_name
) override
{
226 VLOG(2) << "Remote GATT characteristic removed: " << object_path
.value();
227 FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer
, observers_
,
228 GattCharacteristicRemoved(object_path
));
232 // chromeos::DBusClient override.
233 void Init(dbus::Bus
* bus
) override
{
234 object_manager_
= bus
->GetObjectManager(
235 bluetooth_object_manager::kBluetoothObjectManagerServiceName
,
237 bluetooth_object_manager::kBluetoothObjectManagerServicePath
));
238 object_manager_
->RegisterInterface(
239 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface
,
244 // Called by dbus::PropertySet when a property value is changed, either by
245 // result of a signal or response to a GetAll() or Get() call. Informs
247 virtual void OnPropertyChanged(const dbus::ObjectPath
& object_path
,
248 const std::string
& property_name
) {
249 VLOG(2) << "Remote GATT characteristic property changed: "
250 << object_path
.value() << ": " << property_name
;
251 FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer
, observers_
,
252 GattCharacteristicPropertyChanged(object_path
,
256 // Called when a response for successful method call is received.
257 void OnSuccess(const base::Closure
& callback
, dbus::Response
* response
) {
262 // Called when a characteristic value response for a successful method call
264 void OnValueSuccess(const ValueCallback
& callback
, dbus::Response
* response
) {
266 dbus::MessageReader
reader(response
);
268 const uint8
* bytes
= NULL
;
271 if (!reader
.PopArrayOfBytes(&bytes
, &length
))
272 VLOG(2) << "Error reading array of bytes in ValueCallback";
274 std::vector
<uint8
> value
;
277 value
.assign(bytes
, bytes
+ length
);
282 // Called when a response for a failed method call is received.
283 void OnError(const ErrorCallback
& error_callback
,
284 dbus::ErrorResponse
* response
) {
285 // Error response has optional error message argument.
286 std::string error_name
;
287 std::string error_message
;
289 dbus::MessageReader
reader(response
);
290 error_name
= response
->GetErrorName();
291 reader
.PopString(&error_message
);
293 error_name
= kNoResponseError
;
296 error_callback
.Run(error_name
, error_message
);
299 dbus::ObjectManager
* object_manager_
;
301 // List of observers interested in event notifications from us.
302 base::ObserverList
<BluetoothGattCharacteristicClient::Observer
> observers_
;
304 // Weak pointer factory for generating 'this' pointers that might live longer
306 // Note: This should remain the last member so it'll be destroyed and
307 // invalidate its weak pointers before any other members are destroyed.
308 base::WeakPtrFactory
<BluetoothGattCharacteristicClientImpl
>
311 DISALLOW_COPY_AND_ASSIGN(BluetoothGattCharacteristicClientImpl
);
314 BluetoothGattCharacteristicClient::BluetoothGattCharacteristicClient() {
317 BluetoothGattCharacteristicClient::~BluetoothGattCharacteristicClient() {
321 BluetoothGattCharacteristicClient
* BluetoothGattCharacteristicClient::Create() {
322 return new BluetoothGattCharacteristicClientImpl();
325 } // namespace chromeos