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"
17 const char BluetoothGattCharacteristicClient::kNoResponseError
[] =
18 "org.chromium.Error.NoResponse";
20 const char BluetoothGattCharacteristicClient::kUnknownCharacteristicError
[] =
21 "org.chromium.Error.UnknownCharacteristic";
23 BluetoothGattCharacteristicClient::Properties::Properties(
24 dbus::ObjectProxy
* object_proxy
,
25 const std::string
& interface_name
,
26 const PropertyChangedCallback
& callback
)
27 : dbus::PropertySet(object_proxy
, interface_name
, callback
) {
28 RegisterProperty(bluetooth_gatt_characteristic::kUUIDProperty
, &uuid
);
29 RegisterProperty(bluetooth_gatt_characteristic::kServiceProperty
, &service
);
30 RegisterProperty(bluetooth_gatt_characteristic::kNotifyingProperty
,
32 RegisterProperty(bluetooth_gatt_characteristic::kFlagsProperty
, &flags
);
33 RegisterProperty(bluetooth_gatt_characteristic::kDescriptorsProperty
,
37 BluetoothGattCharacteristicClient::Properties::~Properties() {
40 // The BluetoothGattCharacteristicClient implementation used in production.
41 class BluetoothGattCharacteristicClientImpl
42 : public BluetoothGattCharacteristicClient
,
43 public dbus::ObjectManager::Interface
{
45 BluetoothGattCharacteristicClientImpl()
46 : object_manager_(NULL
),
47 weak_ptr_factory_(this) {
50 virtual ~BluetoothGattCharacteristicClientImpl() {
51 object_manager_
->UnregisterInterface(
52 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface
);
55 // BluetoothGattCharacteristicClient override.
56 virtual void AddObserver(
57 BluetoothGattCharacteristicClient::Observer
* observer
) OVERRIDE
{
59 observers_
.AddObserver(observer
);
62 // BluetoothGattCharacteristicClient override.
63 virtual void RemoveObserver(
64 BluetoothGattCharacteristicClient::Observer
* observer
) OVERRIDE
{
66 observers_
.RemoveObserver(observer
);
69 // BluetoothGattCharacteristicClient override.
70 virtual std::vector
<dbus::ObjectPath
> GetCharacteristics() OVERRIDE
{
71 DCHECK(object_manager_
);
72 return object_manager_
->GetObjectsWithInterface(
73 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface
);
76 // BluetoothGattCharacteristicClient override.
77 virtual Properties
* GetProperties(
78 const dbus::ObjectPath
& object_path
) OVERRIDE
{
79 DCHECK(object_manager_
);
80 return static_cast<Properties
*>(
81 object_manager_
->GetProperties(
83 bluetooth_gatt_characteristic::
84 kBluetoothGattCharacteristicInterface
));
87 // BluetoothGattCharacteristicClient override.
88 virtual void ReadValue(const dbus::ObjectPath
& object_path
,
89 const ValueCallback
& callback
,
90 const ErrorCallback
& error_callback
) OVERRIDE
{
91 dbus::ObjectProxy
* object_proxy
=
92 object_manager_
->GetObjectProxy(object_path
);
94 error_callback
.Run(kUnknownCharacteristicError
, "");
98 dbus::MethodCall
method_call(
99 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface
,
100 bluetooth_gatt_characteristic::kReadValue
);
102 object_proxy
->CallMethodWithErrorCallback(
104 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
105 base::Bind(&BluetoothGattCharacteristicClientImpl::OnValueSuccess
,
106 weak_ptr_factory_
.GetWeakPtr(),
108 base::Bind(&BluetoothGattCharacteristicClientImpl::OnError
,
109 weak_ptr_factory_
.GetWeakPtr(),
113 // BluetoothGattCharacteristicClient override.
114 virtual void WriteValue(const dbus::ObjectPath
& object_path
,
115 const std::vector
<uint8
>& value
,
116 const base::Closure
& callback
,
117 const ErrorCallback
& error_callback
) OVERRIDE
{
118 dbus::ObjectProxy
* object_proxy
=
119 object_manager_
->GetObjectProxy(object_path
);
121 error_callback
.Run(kUnknownCharacteristicError
, "");
125 dbus::MethodCall
method_call(
126 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface
,
127 bluetooth_gatt_characteristic::kWriteValue
);
128 dbus::MessageWriter
writer(&method_call
);
129 writer
.AppendArrayOfBytes(value
.data(), value
.size());
131 object_proxy
->CallMethodWithErrorCallback(
133 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
134 base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess
,
135 weak_ptr_factory_
.GetWeakPtr(),
137 base::Bind(&BluetoothGattCharacteristicClientImpl::OnError
,
138 weak_ptr_factory_
.GetWeakPtr(),
142 // BluetoothGattCharacteristicClient override.
143 virtual void StartNotify(const dbus::ObjectPath
& object_path
,
144 const base::Closure
& callback
,
145 const ErrorCallback
& error_callback
) OVERRIDE
{
146 dbus::ObjectProxy
* object_proxy
=
147 object_manager_
->GetObjectProxy(object_path
);
149 error_callback
.Run(kUnknownCharacteristicError
, "");
153 dbus::MethodCall
method_call(
154 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface
,
155 bluetooth_gatt_characteristic::kStartNotify
);
157 object_proxy
->CallMethodWithErrorCallback(
159 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
160 base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess
,
161 weak_ptr_factory_
.GetWeakPtr(),
163 base::Bind(&BluetoothGattCharacteristicClientImpl::OnError
,
164 weak_ptr_factory_
.GetWeakPtr(),
168 // BluetoothGattCharacteristicClient override.
169 virtual void StopNotify(const dbus::ObjectPath
& object_path
,
170 const base::Closure
& callback
,
171 const ErrorCallback
& error_callback
) OVERRIDE
{
172 dbus::ObjectProxy
* object_proxy
=
173 object_manager_
->GetObjectProxy(object_path
);
175 error_callback
.Run(kUnknownCharacteristicError
, "");
179 dbus::MethodCall
method_call(
180 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface
,
181 bluetooth_gatt_characteristic::kStopNotify
);
183 object_proxy
->CallMethodWithErrorCallback(
185 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
186 base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess
,
187 weak_ptr_factory_
.GetWeakPtr(),
189 base::Bind(&BluetoothGattCharacteristicClientImpl::OnError
,
190 weak_ptr_factory_
.GetWeakPtr(),
194 // dbus::ObjectManager::Interface override.
195 virtual dbus::PropertySet
* CreateProperties(
196 dbus::ObjectProxy
*object_proxy
,
197 const dbus::ObjectPath
& object_path
,
198 const std::string
& interface_name
) OVERRIDE
{
199 Properties
* properties
= new Properties(
202 base::Bind(&BluetoothGattCharacteristicClientImpl::OnPropertyChanged
,
203 weak_ptr_factory_
.GetWeakPtr(),
205 return static_cast<dbus::PropertySet
*>(properties
);
208 // dbus::ObjectManager::Interface override.
209 virtual void ObjectAdded(const dbus::ObjectPath
& object_path
,
210 const std::string
& interface_name
) OVERRIDE
{
211 VLOG(2) << "Remote GATT characteristic added: " << object_path
.value();
212 FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer
, observers_
,
213 GattCharacteristicAdded(object_path
));
215 // Connect the "ValueUpdated" signal.
216 dbus::ObjectProxy
* object_proxy
=
217 object_manager_
->GetObjectProxy(object_path
);
218 DCHECK(object_proxy
);
220 object_proxy
->ConnectToSignal(
221 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface
,
222 bluetooth_gatt_characteristic::kValueUpdatedSignal
,
223 base::Bind(&BluetoothGattCharacteristicClientImpl::ValueUpdatedReceived
,
224 weak_ptr_factory_
.GetWeakPtr(),
227 &BluetoothGattCharacteristicClientImpl::ValueUpdatedConnected
,
228 weak_ptr_factory_
.GetWeakPtr()));
231 // dbus::ObjectManager::Interface override.
232 virtual void ObjectRemoved(const dbus::ObjectPath
& object_path
,
233 const std::string
& interface_name
) OVERRIDE
{
234 VLOG(2) << "Remote GATT characteristic removed: " << object_path
.value();
235 FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer
, observers_
,
236 GattCharacteristicRemoved(object_path
));
240 // chromeos::DBusClient override.
241 virtual void Init(dbus::Bus
* bus
) OVERRIDE
{
242 object_manager_
= bus
->GetObjectManager(
243 bluetooth_object_manager::kBluetoothObjectManagerServiceName
,
245 bluetooth_object_manager::kBluetoothObjectManagerServicePath
));
246 object_manager_
->RegisterInterface(
247 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface
,
252 // Called by dbus::PropertySet when a property value is changed, either by
253 // result of a signal or response to a GetAll() or Get() call. Informs
255 virtual void OnPropertyChanged(const dbus::ObjectPath
& object_path
,
256 const std::string
& property_name
) {
257 VLOG(2) << "Remote GATT characteristic property changed: "
258 << object_path
.value() << ": " << property_name
;
259 FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer
, observers_
,
260 GattCharacteristicPropertyChanged(object_path
,
264 // Called by dbus:: when a "ValueUpdated" signal is received.
265 void ValueUpdatedReceived(const dbus::ObjectPath
& object_path
,
266 dbus::Signal
* signal
) {
268 const uint8
* bytes
= NULL
;
270 dbus::MessageReader
reader(signal
);
271 if (!reader
.PopArrayOfBytes(&bytes
, &length
)) {
272 LOG(WARNING
) << "ValueUpdated signal has incorrect parameters: "
273 << signal
->ToString();
277 std::vector
<uint8
> value
;
279 value
.assign(bytes
, bytes
+ length
);
281 FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer
,
283 GattCharacteristicValueUpdated(object_path
, value
));
286 // Called by dbus:: when the "ValueUpdated" signal is initially connected.
287 void ValueUpdatedConnected(const std::string
& interface_name
,
288 const std::string
& signal_name
,
290 LOG_IF(WARNING
, !success
) << "Failed to connect to the ValueUpdated signal";
293 // Called when a response for successful method call is received.
294 void OnSuccess(const base::Closure
& callback
, dbus::Response
* response
) {
299 // Called when a characteristic value response for a successful method call
301 void OnValueSuccess(const ValueCallback
& callback
, dbus::Response
* response
) {
303 dbus::MessageReader
reader(response
);
305 const uint8
* bytes
= NULL
;
308 if (!reader
.PopArrayOfBytes(&bytes
, &length
))
309 VLOG(2) << "Error reading array of bytes in ValueCallback";
311 std::vector
<uint8
> value
;
314 value
.assign(bytes
, bytes
+ length
);
319 // Called when a response for a failed method call is received.
320 void OnError(const ErrorCallback
& error_callback
,
321 dbus::ErrorResponse
* response
) {
322 // Error response has optional error message argument.
323 std::string error_name
;
324 std::string error_message
;
326 dbus::MessageReader
reader(response
);
327 error_name
= response
->GetErrorName();
328 reader
.PopString(&error_message
);
330 error_name
= kNoResponseError
;
333 error_callback
.Run(error_name
, error_message
);
336 dbus::ObjectManager
* object_manager_
;
338 // List of observers interested in event notifications from us.
339 ObserverList
<BluetoothGattCharacteristicClient::Observer
> observers_
;
341 // Weak pointer factory for generating 'this' pointers that might live longer
343 // Note: This should remain the last member so it'll be destroyed and
344 // invalidate its weak pointers before any other members are destroyed.
345 base::WeakPtrFactory
<BluetoothGattCharacteristicClientImpl
>
348 DISALLOW_COPY_AND_ASSIGN(BluetoothGattCharacteristicClientImpl
);
351 BluetoothGattCharacteristicClient::BluetoothGattCharacteristicClient() {
354 BluetoothGattCharacteristicClient::~BluetoothGattCharacteristicClient() {
358 BluetoothGattCharacteristicClient
* BluetoothGattCharacteristicClient::Create() {
359 return new BluetoothGattCharacteristicClientImpl();
362 } // namespace chromeos