OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "chromeos/dbus/bluetooth_out_of_band_client.h" | |
6 | |
7 #include <map> | |
8 #include <string> | |
9 | |
10 #include "base/bind.h" | |
11 #include "base/logging.h" | |
12 #include "chromeos/dbus/bluetooth_adapter_client.h" | |
13 #include "dbus/bus.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" | |
19 | |
20 namespace chromeos { | |
21 | |
22 // The BluetoothOutOfBandClient implementation used in production. | |
23 class BluetoothOutOfBandClientImpl: public BluetoothOutOfBandClient { | |
24 public: | |
25 explicit BluetoothOutOfBandClientImpl(dbus::Bus* bus) | |
26 : bus_(bus), | |
27 weak_ptr_factory_(this) {} | |
28 | |
29 virtual ~BluetoothOutOfBandClientImpl() {} | |
30 | |
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); | |
38 | |
39 dbus::ObjectProxy* object_proxy = GetObjectProxy(object_path); | |
40 | |
41 object_proxy->CallMethod( | |
42 &method_call, | |
43 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
44 base::Bind(&BluetoothOutOfBandClientImpl::OnReadLocalData, | |
45 weak_ptr_factory_.GetWeakPtr(), callback)); | |
46 } | |
47 | |
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); | |
57 | |
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); | |
64 | |
65 dbus::ObjectProxy* object_proxy = GetObjectProxy(object_path); | |
66 | |
67 object_proxy->CallMethod( | |
68 &method_call, | |
69 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
70 base::Bind(&BluetoothOutOfBandClientImpl::ResponseToSuccessCallback, | |
71 weak_ptr_factory_.GetWeakPtr(), callback)); | |
72 } | |
73 | |
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); | |
82 | |
83 dbus::MessageWriter writer(&method_call); | |
84 writer.AppendString(address); | |
85 | |
86 dbus::ObjectProxy* object_proxy = GetObjectProxy(object_path); | |
87 | |
88 object_proxy->CallMethod( | |
89 &method_call, | |
90 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
91 base::Bind(&BluetoothOutOfBandClientImpl::ResponseToSuccessCallback, | |
92 weak_ptr_factory_.GetWeakPtr(), callback)); | |
93 } | |
94 | |
95 private: | |
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_; | |
99 | |
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()) | |
105 return iter->second; | |
106 | |
107 DCHECK(bus_); | |
108 dbus::ObjectProxy* object_proxy = bus_->GetObjectProxy( | |
109 bluetooth_outofband::kBluetoothOutOfBandServiceName, object_path); | |
110 | |
111 object_map_[object_path] = object_proxy; | |
112 return object_proxy; | |
113 } | |
114 | |
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); | |
130 success = true; | |
131 } | |
132 } | |
133 } | |
134 } | |
135 } | |
136 callback.Run(data, success); | |
137 } | |
138 | |
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); | |
144 } | |
145 | |
146 dbus::Bus* bus_; | |
147 | |
148 // Weak pointer factory for generating 'this' pointers that might live longer | |
149 // than we do. | |
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_; | |
153 | |
154 DISALLOW_COPY_AND_ASSIGN(BluetoothOutOfBandClientImpl); | |
155 }; | |
156 | |
157 // The BluetoothOutOfBandClient implementation used on Linux desktop, which does | |
158 // nothing. | |
159 class BluetoothOutOfBandClientStubImpl : public BluetoothOutOfBandClient { | |
160 public: | |
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); | |
168 } | |
169 | |
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(); | |
177 callback.Run(false); | |
178 } | |
179 | |
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(); | |
186 callback.Run(false); | |
187 } | |
188 }; | |
189 | |
190 BluetoothOutOfBandClient::BluetoothOutOfBandClient() {} | |
191 | |
192 BluetoothOutOfBandClient::~BluetoothOutOfBandClient() {} | |
193 | |
194 BluetoothOutOfBandClient* BluetoothOutOfBandClient::Create( | |
195 DBusClientImplementationType type, | |
196 dbus::Bus* bus) { | |
197 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) | |
198 return new BluetoothOutOfBandClientImpl(bus); | |
199 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); | |
200 return new BluetoothOutOfBandClientStubImpl(); | |
201 } | |
202 | |
203 } // namespace chromeos | |
OLD | NEW |