Index: chromeos/dbus/bluetooth_out_of_band_client.cc |
diff --git a/chromeos/dbus/bluetooth_out_of_band_client.cc b/chromeos/dbus/bluetooth_out_of_band_client.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..15768edd3a2f0ae4959c12720b6e7c1aee0ee011 |
--- /dev/null |
+++ b/chromeos/dbus/bluetooth_out_of_band_client.cc |
@@ -0,0 +1,199 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chromeos/dbus/bluetooth_out_of_band_client.h" |
+ |
+#include <map> |
+#include <string> |
+ |
+#include "base/bind.h" |
+#include "base/logging.h" |
+#include "chromeos/dbus/bluetooth_adapter_client.h" |
+#include "dbus/bus.h" |
+#include "dbus/message.h" |
+#include "dbus/object_path.h" |
+#include "dbus/object_proxy.h" |
+#include "third_party/cros_system_api/dbus/service_constants.h" |
+ |
+namespace chromeos { |
+ |
+// The BluetoothOutOfBandClient implementation used in production. |
+class BluetoothOutOfBandClientImpl: public BluetoothOutOfBandClient { |
+ public: |
+ explicit BluetoothOutOfBandClientImpl(dbus::Bus* bus) |
+ : weak_ptr_factory_(this), |
+ bus_(bus) {} |
+ |
+ virtual ~BluetoothOutOfBandClientImpl() {} |
+ |
+ // BluetoothOutOfBandClient override. |
+ virtual void ReadLocalData( |
+ const dbus::ObjectPath& object_path, |
+ const DataCallback& callback) OVERRIDE { |
+ dbus::MethodCall method_call( |
+ bluetooth_outofband::kBluetoothOutOfBandInterface, |
+ bluetooth_outofband::kReadLocalData); |
+ |
+ dbus::ObjectProxy* object_proxy = GetObjectProxy(object_path); |
+ |
+ object_proxy->CallMethod( |
+ &method_call, |
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
+ base::Bind(&BluetoothOutOfBandClientImpl::OnReadLocalData, |
+ weak_ptr_factory_.GetWeakPtr(), callback)); |
+ } |
+ |
+ // BluetoothOutOfBandClient override. |
+ virtual void AddRemoteData( |
+ const dbus::ObjectPath& object_path, |
+ const std::string& address, |
+ const BluetoothOutOfBandPairingData& data, |
+ const SuccessCallback& callback) OVERRIDE { |
+ dbus::MethodCall method_call( |
+ bluetooth_outofband::kBluetoothOutOfBandInterface, |
+ bluetooth_outofband::kAddRemoteData); |
+ |
+ dbus::MessageWriter writer(&method_call); |
+ writer.AppendString(address); |
+ writer.AppendArrayOfBytes(data.hash, kBluetoothOutOfBandPairingDataSize); |
+ writer.AppendArrayOfBytes(data.randomizer, |
+ kBluetoothOutOfBandPairingDataSize); |
+ |
+ dbus::ObjectProxy* object_proxy = GetObjectProxy(object_path); |
+ |
+ object_proxy->CallMethod( |
+ &method_call, |
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
+ base::Bind(&BluetoothOutOfBandClientImpl::ResponseToSuccessCallback, |
+ weak_ptr_factory_.GetWeakPtr(), callback)); |
+ } |
+ |
+ // BluetoothOutOfBandClient override. |
+ virtual void RemoveRemoteData( |
+ const dbus::ObjectPath& object_path, |
+ const std::string& address, |
+ const SuccessCallback& callback) OVERRIDE { |
+ dbus::MethodCall method_call( |
+ bluetooth_outofband::kBluetoothOutOfBandInterface, |
+ bluetooth_outofband::kRemoveRemoteData); |
+ |
+ dbus::MessageWriter writer(&method_call); |
+ writer.AppendString(address); |
+ |
+ dbus::ObjectProxy* object_proxy = GetObjectProxy(object_path); |
+ |
+ object_proxy->CallMethod( |
+ &method_call, |
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
+ base::Bind(&BluetoothOutOfBandClientImpl::ResponseToSuccessCallback, |
+ weak_ptr_factory_.GetWeakPtr(), callback)); |
+ } |
+ |
+ private: |
+ // We maintain a collection of dbus object proxies for each binding. |
+ typedef std::map<const dbus::ObjectPath, dbus::ObjectProxy*> ObjectMap; |
+ ObjectMap object_map_; |
+ |
+ // Returns a pointer to the object proxy for |object_path|, creating |
+ // it if necessary. This is cached in the ObjectMap. |
+ dbus::ObjectProxy* GetObjectProxy(const dbus::ObjectPath& object_path) { |
+ ObjectMap::iterator iter = object_map_.find(object_path); |
+ if (iter != object_map_.end()) |
+ return iter->second; |
+ |
+ DCHECK(bus_); |
+ dbus::ObjectProxy* object_proxy = bus_->GetObjectProxy( |
+ bluetooth_outofband::kBluetoothOutOfBandServiceName, object_path); |
+ |
+ object_map_[object_path] = object_proxy; |
+ return object_proxy; |
+ } |
+ |
+ // Called when a response from ReadLocalOutOfBandPairingData() is received. |
+ void OnReadLocalData(const DataCallback& callback, |
+ dbus::Response* response) { |
+ bool success = false; |
+ BluetoothOutOfBandPairingData data; |
+ if (response != NULL) { |
+ dbus::MessageReader reader(response); |
+ uint8_t* bytes = NULL; |
+ size_t length = kBluetoothOutOfBandPairingDataSize; |
+ if (reader.PopArrayOfBytes(&bytes, &length)) { |
+ if (length == kBluetoothOutOfBandPairingDataSize) { |
+ memcpy(&data.hash, bytes, length); |
+ if (reader.PopArrayOfBytes(&bytes, &length)) { |
+ if (length == kBluetoothOutOfBandPairingDataSize) { |
+ memcpy(&data.randomizer, bytes, length); |
+ success = true; |
+ } |
+ } |
+ } |
+ } |
+ } |
+ callback.Run(data, success); |
+ } |
+ |
+ // Translates a dbus::Response to a SuccessCallback by assuming success if |
+ // |response| is not NULL. |
+ void ResponseToSuccessCallback(const SuccessCallback& callback, |
+ dbus::Response* response) { |
+ callback.Run(response != NULL); |
+ } |
+ |
+ // Weak pointer factory for generating 'this' pointers that might live longer |
+ // than we do. |
+ base::WeakPtrFactory<BluetoothOutOfBandClientImpl> weak_ptr_factory_; |
+ |
+ dbus::Bus* bus_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(BluetoothOutOfBandClientImpl); |
+}; |
+ |
+// The BluetoothOutOfBandClient implementation used on Linux desktop, which does |
+// nothing. |
+class BluetoothOutOfBandClientStubImpl : public BluetoothOutOfBandClient { |
+ public: |
+ // BluetoothOutOfBandClient override. |
+ virtual void ReadLocalData( |
+ const dbus::ObjectPath& object_path, |
+ const DataCallback& callback) OVERRIDE { |
+ VLOG(1) << "ReadLocalData: " << object_path.value(); |
+ BluetoothOutOfBandPairingData data; |
+ callback.Run(data, false); |
+ } |
+ |
+ // BluetoothOutOfBandClient override. |
+ virtual void AddRemoteData( |
+ const dbus::ObjectPath& object_path, |
+ const std::string& address, |
+ const BluetoothOutOfBandPairingData& data, |
+ const SuccessCallback& callback) OVERRIDE { |
+ VLOG(1) << "AddRemoteData: " << object_path.value(); |
+ callback.Run(false); |
+ } |
+ |
+ // BluetoothOutOfBandClient override. |
+ virtual void RemoveRemoteData( |
+ const dbus::ObjectPath& object_path, |
+ const std::string& address, |
+ const SuccessCallback& callback) OVERRIDE { |
+ VLOG(1) << "RemoveRemoteData: " << object_path.value(); |
+ callback.Run(false); |
+ } |
+}; |
+ |
+BluetoothOutOfBandClient::BluetoothOutOfBandClient() {} |
+ |
+BluetoothOutOfBandClient::~BluetoothOutOfBandClient() {} |
+ |
+BluetoothOutOfBandClient* BluetoothOutOfBandClient::Create( |
+ DBusClientImplementationType type, |
+ dbus::Bus* bus) { |
+ if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) |
+ return new BluetoothOutOfBandClientImpl(bus); |
+ DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); |
+ return new BluetoothOutOfBandClientStubImpl(); |
+} |
+ |
+} // namespace chromeos |