1 // Copyright (c) 2012 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_out_of_band_client.h"
10 #include "base/bind.h"
11 #include "base/logging.h"
12 #include "chromeos/dbus/bluetooth_adapter_client.h"
14 #include "dbus/message.h"
15 #include "dbus/object_path.h"
16 #include "dbus/object_proxy.h"
17 #include "device/bluetooth/bluetooth_out_of_band_pairing_data.h"
18 #include "third_party/cros_system_api/dbus/service_constants.h"
22 // The BluetoothOutOfBandClient implementation used in production.
23 class BluetoothOutOfBandClientImpl
: public BluetoothOutOfBandClient
{
25 explicit BluetoothOutOfBandClientImpl(dbus::Bus
* bus
)
27 weak_ptr_factory_(this) {}
29 virtual ~BluetoothOutOfBandClientImpl() {}
31 // BluetoothOutOfBandClient override.
32 virtual void ReadLocalData(
33 const dbus::ObjectPath
& object_path
,
34 const DataCallback
& callback
) OVERRIDE
{
35 dbus::MethodCall
method_call(
36 bluetooth_outofband::kBluetoothOutOfBandInterface
,
37 bluetooth_outofband::kReadLocalData
);
39 dbus::ObjectProxy
* object_proxy
= GetObjectProxy(object_path
);
41 object_proxy
->CallMethod(
43 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
44 base::Bind(&BluetoothOutOfBandClientImpl::OnReadLocalData
,
45 weak_ptr_factory_
.GetWeakPtr(), callback
));
48 // BluetoothOutOfBandClient override.
49 virtual void AddRemoteData(
50 const dbus::ObjectPath
& object_path
,
51 const std::string
& address
,
52 const device::BluetoothOutOfBandPairingData
& data
,
53 const SuccessCallback
& callback
) OVERRIDE
{
54 dbus::MethodCall
method_call(
55 bluetooth_outofband::kBluetoothOutOfBandInterface
,
56 bluetooth_outofband::kAddRemoteData
);
58 dbus::MessageWriter
writer(&method_call
);
59 writer
.AppendString(address
);
60 writer
.AppendArrayOfBytes(
61 data
.hash
, device::kBluetoothOutOfBandPairingDataSize
);
62 writer
.AppendArrayOfBytes(
63 data
.randomizer
, device::kBluetoothOutOfBandPairingDataSize
);
65 dbus::ObjectProxy
* object_proxy
= GetObjectProxy(object_path
);
67 object_proxy
->CallMethod(
69 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
70 base::Bind(&BluetoothOutOfBandClientImpl::ResponseToSuccessCallback
,
71 weak_ptr_factory_
.GetWeakPtr(), callback
));
74 // BluetoothOutOfBandClient override.
75 virtual void RemoveRemoteData(
76 const dbus::ObjectPath
& object_path
,
77 const std::string
& address
,
78 const SuccessCallback
& callback
) OVERRIDE
{
79 dbus::MethodCall
method_call(
80 bluetooth_outofband::kBluetoothOutOfBandInterface
,
81 bluetooth_outofband::kRemoveRemoteData
);
83 dbus::MessageWriter
writer(&method_call
);
84 writer
.AppendString(address
);
86 dbus::ObjectProxy
* object_proxy
= GetObjectProxy(object_path
);
88 object_proxy
->CallMethod(
90 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
91 base::Bind(&BluetoothOutOfBandClientImpl::ResponseToSuccessCallback
,
92 weak_ptr_factory_
.GetWeakPtr(), callback
));
96 // We maintain a collection of dbus object proxies for each binding.
97 typedef std::map
<const dbus::ObjectPath
, dbus::ObjectProxy
*> ObjectMap
;
98 ObjectMap object_map_
;
100 // Returns a pointer to the object proxy for |object_path|, creating
101 // it if necessary. This is cached in the ObjectMap.
102 dbus::ObjectProxy
* GetObjectProxy(const dbus::ObjectPath
& object_path
) {
103 ObjectMap::iterator iter
= object_map_
.find(object_path
);
104 if (iter
!= object_map_
.end())
108 dbus::ObjectProxy
* object_proxy
= bus_
->GetObjectProxy(
109 bluetooth_outofband::kBluetoothOutOfBandServiceName
, object_path
);
111 object_map_
[object_path
] = object_proxy
;
115 // Called when a response from ReadLocalOutOfBandPairingData() is received.
116 void OnReadLocalData(const DataCallback
& callback
,
117 dbus::Response
* response
) {
118 bool success
= false;
119 device::BluetoothOutOfBandPairingData data
;
120 if (response
!= NULL
) {
121 dbus::MessageReader
reader(response
);
122 uint8_t* bytes
= NULL
;
123 size_t length
= device::kBluetoothOutOfBandPairingDataSize
;
124 if (reader
.PopArrayOfBytes(&bytes
, &length
)) {
125 if (length
== device::kBluetoothOutOfBandPairingDataSize
) {
126 memcpy(&data
.hash
, bytes
, length
);
127 if (reader
.PopArrayOfBytes(&bytes
, &length
)) {
128 if (length
== device::kBluetoothOutOfBandPairingDataSize
) {
129 memcpy(&data
.randomizer
, bytes
, length
);
136 callback
.Run(data
, success
);
139 // Translates a dbus::Response to a SuccessCallback by assuming success if
140 // |response| is not NULL.
141 void ResponseToSuccessCallback(const SuccessCallback
& callback
,
142 dbus::Response
* response
) {
143 callback
.Run(response
!= NULL
);
148 // Weak pointer factory for generating 'this' pointers that might live longer
150 // Note: This should remain the last member so it'll be destroyed and
151 // invalidate its weak pointers before any other members are destroyed.
152 base::WeakPtrFactory
<BluetoothOutOfBandClientImpl
> weak_ptr_factory_
;
154 DISALLOW_COPY_AND_ASSIGN(BluetoothOutOfBandClientImpl
);
157 // The BluetoothOutOfBandClient implementation used on Linux desktop, which does
159 class BluetoothOutOfBandClientStubImpl
: public BluetoothOutOfBandClient
{
161 // BluetoothOutOfBandClient override.
162 virtual void ReadLocalData(
163 const dbus::ObjectPath
& object_path
,
164 const DataCallback
& callback
) OVERRIDE
{
165 VLOG(1) << "ReadLocalData: " << object_path
.value();
166 device::BluetoothOutOfBandPairingData data
;
167 callback
.Run(data
, false);
170 // BluetoothOutOfBandClient override.
171 virtual void AddRemoteData(
172 const dbus::ObjectPath
& object_path
,
173 const std::string
& address
,
174 const device::BluetoothOutOfBandPairingData
& data
,
175 const SuccessCallback
& callback
) OVERRIDE
{
176 VLOG(1) << "AddRemoteData: " << object_path
.value();
180 // BluetoothOutOfBandClient override.
181 virtual void RemoveRemoteData(
182 const dbus::ObjectPath
& object_path
,
183 const std::string
& address
,
184 const SuccessCallback
& callback
) OVERRIDE
{
185 VLOG(1) << "RemoveRemoteData: " << object_path
.value();
190 BluetoothOutOfBandClient::BluetoothOutOfBandClient() {}
192 BluetoothOutOfBandClient::~BluetoothOutOfBandClient() {}
194 BluetoothOutOfBandClient
* BluetoothOutOfBandClient::Create(
195 DBusClientImplementationType type
,
197 if (type
== REAL_DBUS_CLIENT_IMPLEMENTATION
)
198 return new BluetoothOutOfBandClientImpl(bus
);
199 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION
, type
);
200 return new BluetoothOutOfBandClientStubImpl();
203 } // namespace chromeos