diff options
author | bryeung@chromium.org <bryeung@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-15 03:50:45 +0000 |
---|---|---|
committer | bryeung@chromium.org <bryeung@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-15 03:50:45 +0000 |
commit | 2b7c40da625aabd2cd1e2b3f4acb3e3da52f32e7 (patch) | |
tree | 4f23aeaba864a42cd259afb0fa33a5d910e87d5f /chromeos | |
parent | 5aee7bef490cabc7c93c372b5dc712673f41dbca (diff) | |
download | chromium_src-2b7c40da625aabd2cd1e2b3f4acb3e3da52f32e7.zip chromium_src-2b7c40da625aabd2cd1e2b3f4acb3e3da52f32e7.tar.gz chromium_src-2b7c40da625aabd2cd1e2b3f4acb3e3da52f32e7.tar.bz2 |
Implement support for the OOB Pairing APIs.
TEST=none (though tests are included with the extension APIs)
BUG=119473
Review URL: https://chromiumcodereview.appspot.com/10546010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@142337 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chromeos')
-rw-r--r-- | chromeos/chromeos.gyp | 4 | ||||
-rw-r--r-- | chromeos/dbus/bluetooth_out_of_band_client.cc | 199 | ||||
-rw-r--r-- | chromeos/dbus/bluetooth_out_of_band_client.h | 80 | ||||
-rw-r--r-- | chromeos/dbus/dbus_thread_manager.cc | 9 | ||||
-rw-r--r-- | chromeos/dbus/dbus_thread_manager.h | 6 | ||||
-rw-r--r-- | chromeos/dbus/mock_bluetooth_out_of_band_client.cc | 13 | ||||
-rw-r--r-- | chromeos/dbus/mock_bluetooth_out_of_band_client.h | 37 | ||||
-rw-r--r-- | chromeos/dbus/mock_dbus_thread_manager.cc | 4 | ||||
-rw-r--r-- | chromeos/dbus/mock_dbus_thread_manager.h | 6 |
9 files changed, 358 insertions, 0 deletions
diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp index 4ab0e3c..92fb4a4 100644 --- a/chromeos/chromeos.gyp +++ b/chromeos/chromeos.gyp @@ -40,6 +40,8 @@ 'dbus/bluetooth_manager_client.h', 'dbus/bluetooth_node_client.cc', 'dbus/bluetooth_node_client.h', + 'dbus/bluetooth_out_of_band_client.cc', + 'dbus/bluetooth_out_of_band_client.h', 'dbus/bluetooth_property.cc', 'dbus/bluetooth_property.h', 'dbus/cashew_client.cc', @@ -134,6 +136,8 @@ 'dbus/mock_bluetooth_manager_client.h', 'dbus/mock_bluetooth_node_client.cc', 'dbus/mock_bluetooth_node_client.h', + 'dbus/mock_bluetooth_out_of_band_client.cc', + 'dbus/mock_bluetooth_out_of_band_client.h', 'dbus/mock_cros_disks_client.cc', 'dbus/mock_cros_disks_client.h', 'dbus/mock_cashew_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 0000000..15768ed --- /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 diff --git a/chromeos/dbus/bluetooth_out_of_band_client.h b/chromeos/dbus/bluetooth_out_of_band_client.h new file mode 100644 index 0000000..52dafab --- /dev/null +++ b/chromeos/dbus/bluetooth_out_of_band_client.h @@ -0,0 +1,80 @@ +// 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. + +#ifndef CHROMEOS_DBUS_BLUETOOTH_OUT_OF_BAND_CLIENT_H_ +#define CHROMEOS_DBUS_BLUETOOTH_OUT_OF_BAND_CLIENT_H_ +#pragma once + +#include <string> + +#include "base/callback.h" +#include "chromeos/chromeos_export.h" +#include "chromeos/dbus/dbus_client_implementation_type.h" +#include "dbus/object_path.h" + +namespace dbus { +class Bus; +} // namespace dbus + +namespace chromeos { + +const size_t kBluetoothOutOfBandPairingDataSize = 16; + +// A simple structure representing the data required to perform Out Of Band +// Pairing. See +// http://mclean-linsky.net/joel/cv/Simple%20Pairing_WP_V10r00.pdf +struct BluetoothOutOfBandPairingData { + // Simple Pairing Hash C. + uint8_t hash[kBluetoothOutOfBandPairingDataSize]; + + // Simple Pairing Randomizer R. + uint8_t randomizer[kBluetoothOutOfBandPairingDataSize]; +}; + +// BluetoothOutOfBandClient is used to manage Out Of Band Pairing +// Data for the local adapter and remote devices. +class CHROMEOS_EXPORT BluetoothOutOfBandClient { + public: + virtual ~BluetoothOutOfBandClient(); + + typedef base::Callback<void(const BluetoothOutOfBandPairingData& data, + bool success)> DataCallback; + + typedef base::Callback<void(bool success)> SuccessCallback; + + // Reads the local Out Of Band Pairing Data and return it in |callback|. + virtual void ReadLocalData( + const dbus::ObjectPath& object_path, + const DataCallback& callback) = 0; + + // Sets the Out Of Band Pairing Data for the device at |address| to |data|, + // indicating success via |callback|. Makes a copy of |data|. + virtual void AddRemoteData( + const dbus::ObjectPath& object_path, + const std::string& address, + const BluetoothOutOfBandPairingData& data, + const SuccessCallback& callback) = 0; + + // Clears the Out Of Band Pairing Data for the device at |address|, indicating + // success via |callback|. + virtual void RemoveRemoteData( + const dbus::ObjectPath& object_path, + const std::string& address, + const SuccessCallback& callback) = 0; + + // Creates the instance. + static BluetoothOutOfBandClient* Create( + DBusClientImplementationType type, + dbus::Bus* bus); + + protected: + BluetoothOutOfBandClient(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothOutOfBandClient); +}; + +} // namespace chromeos + +#endif // CHROMEOS_DBUS_BLUETOOTH_OUT_OF_BAND_CLIENT_H_ diff --git a/chromeos/dbus/dbus_thread_manager.cc b/chromeos/dbus/dbus_thread_manager.cc index cc35a9a..d747eed 100644 --- a/chromeos/dbus/dbus_thread_manager.cc +++ b/chromeos/dbus/dbus_thread_manager.cc @@ -13,6 +13,7 @@ #include "chromeos/dbus/bluetooth_input_client.h" #include "chromeos/dbus/bluetooth_manager_client.h" #include "chromeos/dbus/bluetooth_node_client.h" +#include "chromeos/dbus/bluetooth_out_of_band_client.h" #include "chromeos/dbus/cashew_client.h" #include "chromeos/dbus/cros_disks_client.h" #include "chromeos/dbus/cryptohome_client.h" @@ -77,6 +78,8 @@ class DBusThreadManagerImpl : public DBusThreadManager { client_type, system_bus_.get(), bluetooth_adapter_client_.get())); bluetooth_node_client_.reset(BluetoothNodeClient::Create( client_type, system_bus_.get(), bluetooth_device_client_.get())); + bluetooth_out_of_band_client_.reset(BluetoothOutOfBandClient::Create( + client_type, system_bus_.get())); // Create the Cashew client. cashew_client_.reset(CashewClient::Create(client_type, system_bus_.get())); // Create the cros-disks client. @@ -208,6 +211,11 @@ class DBusThreadManagerImpl : public DBusThreadManager { } // DBusThreadManager override. + virtual BluetoothOutOfBandClient* GetBluetoothOutOfBandClient() OVERRIDE { + return bluetooth_out_of_band_client_.get(); + } + + // DBusThreadManager override. virtual CashewClient* GetCashewClient() OVERRIDE { return cashew_client_.get(); } @@ -320,6 +328,7 @@ class DBusThreadManagerImpl : public DBusThreadManager { scoped_ptr<BluetoothInputClient> bluetooth_input_client_; scoped_ptr<BluetoothManagerClient> bluetooth_manager_client_; scoped_ptr<BluetoothNodeClient> bluetooth_node_client_; + scoped_ptr<BluetoothOutOfBandClient> bluetooth_out_of_band_client_; scoped_ptr<CashewClient> cashew_client_; scoped_ptr<CrosDisksClient> cros_disks_client_; scoped_ptr<CryptohomeClient> cryptohome_client_; diff --git a/chromeos/dbus/dbus_thread_manager.h b/chromeos/dbus/dbus_thread_manager.h index 3a69528..c65d827 100644 --- a/chromeos/dbus/dbus_thread_manager.h +++ b/chromeos/dbus/dbus_thread_manager.h @@ -28,6 +28,7 @@ class BluetoothDeviceClient; class BluetoothInputClient; class BluetoothManagerClient; class BluetoothNodeClient; +class BluetoothOutOfBandClient; class CashewClient; class CrosDisksClient; class CryptohomeClient; @@ -126,6 +127,11 @@ class CHROMEOS_EXPORT DBusThreadManager { // down. virtual BluetoothNodeClient* GetBluetoothNodeClient() = 0; + // Returns the bluetooth node client, owned by DBusThreadManager. + // Do not cache this pointer and use it after DBusThreadManager is shut + // down. + virtual BluetoothOutOfBandClient* GetBluetoothOutOfBandClient() = 0; + // Returns the Cashew client, owned by DBusThreadManager. // Do not cache this pointer and use it after DBusThreadManager is shut // down. diff --git a/chromeos/dbus/mock_bluetooth_out_of_band_client.cc b/chromeos/dbus/mock_bluetooth_out_of_band_client.cc new file mode 100644 index 0000000..da6ef011 --- /dev/null +++ b/chromeos/dbus/mock_bluetooth_out_of_band_client.cc @@ -0,0 +1,13 @@ +// 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/mock_bluetooth_out_of_band_client.h" + +namespace chromeos { + +MockBluetoothOutOfBandClient::MockBluetoothOutOfBandClient() {} + +MockBluetoothOutOfBandClient::~MockBluetoothOutOfBandClient() {} + +} // namespace chromeos diff --git a/chromeos/dbus/mock_bluetooth_out_of_band_client.h b/chromeos/dbus/mock_bluetooth_out_of_band_client.h new file mode 100644 index 0000000..0a56995 --- /dev/null +++ b/chromeos/dbus/mock_bluetooth_out_of_band_client.h @@ -0,0 +1,37 @@ +// 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. + +#ifndef CHROMEOS_DBUS_MOCK_BLUETOOTH_OUT_OF_BAND_CLIENT_H_ +#define CHROMEOS_DBUS_MOCK_BLUETOOTH_OUT_OF_BAND_CLIENT_H_ + +#include <string> + +#include "base/memory/scoped_ptr.h" +#include "chromeos/dbus/bluetooth_out_of_band_client.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace chromeos { + +class MockBluetoothOutOfBandClient : public BluetoothOutOfBandClient { + public: + MockBluetoothOutOfBandClient(); + virtual ~MockBluetoothOutOfBandClient(); + + MOCK_METHOD2(ReadLocalData, + void(const dbus::ObjectPath&, + const DataCallback&)); + MOCK_METHOD4(AddRemoteData, + void(const dbus::ObjectPath&, + const std::string&, + const BluetoothOutOfBandPairingData&, + const SuccessCallback&)); + MOCK_METHOD3(RemoveRemoteData, + void(const dbus::ObjectPath&, + const std::string&, + const SuccessCallback&)); +}; + +} // namespace chromeos + +#endif // CHROMEOS_DBUS_MOCK_BLUETOOTH_OUT_OF_BAND_CLIENT_H_ diff --git a/chromeos/dbus/mock_dbus_thread_manager.cc b/chromeos/dbus/mock_dbus_thread_manager.cc index 2db9c66..d4be373 100644 --- a/chromeos/dbus/mock_dbus_thread_manager.cc +++ b/chromeos/dbus/mock_dbus_thread_manager.cc @@ -11,6 +11,7 @@ #include "chromeos/dbus/mock_bluetooth_input_client.h" #include "chromeos/dbus/mock_bluetooth_manager_client.h" #include "chromeos/dbus/mock_bluetooth_node_client.h" +#include "chromeos/dbus/mock_bluetooth_out_of_band_client.h" #include "chromeos/dbus/mock_cashew_client.h" #include "chromeos/dbus/mock_cros_disks_client.h" #include "chromeos/dbus/mock_cryptohome_client.h" @@ -43,6 +44,7 @@ MockDBusThreadManager::MockDBusThreadManager() mock_bluetooth_input_client_(new MockBluetoothInputClient), mock_bluetooth_manager_client_(new MockBluetoothManagerClient), mock_bluetooth_node_client_(new MockBluetoothNodeClient), + mock_bluetooth_out_of_band_client_(new MockBluetoothOutOfBandClient), mock_cashew_client_(new MockCashewClient), mock_cros_disks_client_(new MockCrosDisksClient), mock_cryptohome_client_(new MockCryptohomeClient), @@ -74,6 +76,8 @@ MockDBusThreadManager::MockDBusThreadManager() .WillRepeatedly(Return(mock_bluetooth_manager_client())); EXPECT_CALL(*this, GetBluetoothNodeClient()) .WillRepeatedly(Return(mock_bluetooth_node_client_.get())); + EXPECT_CALL(*this, GetBluetoothOutOfBandClient()) + .WillRepeatedly(Return(mock_bluetooth_out_of_band_client_.get())); EXPECT_CALL(*this, GetCashewClient()) .WillRepeatedly(Return(mock_cashew_client())); EXPECT_CALL(*this, GetCrosDisksClient()) diff --git a/chromeos/dbus/mock_dbus_thread_manager.h b/chromeos/dbus/mock_dbus_thread_manager.h index 6a1a12d..9d0f0b7 100644 --- a/chromeos/dbus/mock_dbus_thread_manager.h +++ b/chromeos/dbus/mock_dbus_thread_manager.h @@ -23,6 +23,7 @@ class MockBluetoothDeviceClient; class MockBluetoothInputClient; class MockBluetoothManagerClient; class MockBluetoothNodeClient; +class MockBluetoothOutOfBandClient; class MockCashewClient; class MockCrosDisksClient; class MockCryptohomeClient; @@ -61,6 +62,7 @@ class MockDBusThreadManager : public DBusThreadManager { MOCK_METHOD0(GetBluetoothInputClient, BluetoothInputClient*(void)); MOCK_METHOD0(GetBluetoothManagerClient, BluetoothManagerClient*(void)); MOCK_METHOD0(GetBluetoothNodeClient, BluetoothNodeClient*(void)); + MOCK_METHOD0(GetBluetoothOutOfBandClient, BluetoothOutOfBandClient*(void)); MOCK_METHOD0(GetCashewClient, CashewClient*(void)); MOCK_METHOD0(GetCrosDisksClient, CrosDisksClient*(void)); MOCK_METHOD0(GetCryptohomeClient, CryptohomeClient*(void)); @@ -98,6 +100,9 @@ class MockDBusThreadManager : public DBusThreadManager { MockBluetoothNodeClient* mock_bluetooth_node_client() { return mock_bluetooth_node_client_.get(); } + MockBluetoothOutOfBandClient* mock_bluetooth_out_of_band_client() { + return mock_bluetooth_out_of_band_client_.get(); + } MockCashewClient* mock_cashew_client() { return mock_cashew_client_.get(); } @@ -168,6 +173,7 @@ class MockDBusThreadManager : public DBusThreadManager { scoped_ptr<MockBluetoothInputClient> mock_bluetooth_input_client_; scoped_ptr<MockBluetoothManagerClient> mock_bluetooth_manager_client_; scoped_ptr<MockBluetoothNodeClient> mock_bluetooth_node_client_; + scoped_ptr<MockBluetoothOutOfBandClient> mock_bluetooth_out_of_band_client_; scoped_ptr<MockCashewClient> mock_cashew_client_; scoped_ptr<MockCrosDisksClient> mock_cros_disks_client_; scoped_ptr<MockCryptohomeClient> mock_cryptohome_client_; |