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 "components/copresence_sockets/public/copresence_peer.h"
10 #include "base/bind_helpers.h"
11 #include "base/format_macros.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/rand_util.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/stringprintf.h"
16 #include "components/copresence_sockets/transports/bluetooth/copresence_socket_bluetooth.h"
17 #include "device/bluetooth/bluetooth_adapter.h"
18 #include "device/bluetooth/bluetooth_adapter_factory.h"
19 #include "device/bluetooth/bluetooth_device.h"
20 #include "device/bluetooth/bluetooth_socket.h"
21 #include "device/bluetooth/bluetooth_uuid.h"
25 const char kAdapterError
[] = "NOADAPTER";
27 device::BluetoothUUID
GenerateRandomUuid() {
28 // Random hex string of the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
29 return device::BluetoothUUID(base::StringPrintf(
30 "%08" PRIx64
"-%04" PRIx64
"-%04" PRIx64
"-%04" PRIx64
"-%012" PRIx64
,
31 base::RandGenerator(UINT32_MAX
),
32 base::RandGenerator(UINT16_MAX
),
33 base::RandGenerator(UINT16_MAX
),
34 base::RandGenerator(UINT16_MAX
),
35 base::RandGenerator(static_cast<uint64
>(UINT16_MAX
) + UINT32_MAX
)));
38 // This class will confirm pairing for a device that is expecting a pairing
40 class DefaultApprovalDelegate
41 : public device::BluetoothDevice::PairingDelegate
{
43 DefaultApprovalDelegate() {}
44 ~DefaultApprovalDelegate() override
{}
46 // device::BluetoothDevice::PairingDelegate overrides:
47 void RequestPinCode(device::BluetoothDevice
* device
) override
{}
48 void RequestPasskey(device::BluetoothDevice
* device
) override
{}
49 void DisplayPinCode(device::BluetoothDevice
* device
,
50 const std::string
& pincode
) override
{}
51 void DisplayPasskey(device::BluetoothDevice
* device
,
52 uint32 passkey
) override
{}
53 void KeysEntered(device::BluetoothDevice
* device
, uint32 entered
) override
{}
54 void ConfirmPasskey(device::BluetoothDevice
* device
,
55 uint32 passkey
) override
{}
56 void AuthorizePairing(device::BluetoothDevice
* device
) override
{
57 if (device
->ExpectingConfirmation())
58 device
->ConfirmPairing();
64 namespace copresence_sockets
{
66 CopresencePeer::CopresencePeer(const CreatePeerCallback
& create_callback
,
67 const AcceptCallback
& accept_callback
)
68 : create_callback_(create_callback
),
69 accept_callback_(accept_callback
),
71 weak_ptr_factory_(this) {
72 DCHECK(!create_callback
.is_null());
73 DCHECK(!accept_callback
.is_null());
75 if (!device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) {
76 create_callback_
.Run(std::string());
80 device::BluetoothAdapterFactory::GetAdapter(base::Bind(
81 &CopresencePeer::OnGetAdapter
, weak_ptr_factory_
.GetWeakPtr()));
84 std::string
CopresencePeer::GetLocatorData() {
87 // TODO(rkc): Fix the "1." once we have finalized the locator format with
88 // other platforms. http://crbug.com/418616
89 return "1." + adapter_
->GetAddress() + "." + service_uuid_
.value();
92 CopresencePeer::~CopresencePeer() {
93 server_socket_
->Disconnect(base::Bind(&base::DoNothing
));
94 server_socket_
->Close();
96 adapter_
->RemovePairingDelegate(delegate_
.get());
101 void CopresencePeer::OnGetAdapter(
102 scoped_refptr
<device::BluetoothAdapter
> adapter
) {
103 if (!adapter
.get() || !adapter
->IsPresent() || !adapter
->IsPowered()) {
104 create_callback_
.Run(std::string());
109 service_uuid_
= GenerateRandomUuid();
111 delegate_
= make_scoped_ptr(new DefaultApprovalDelegate());
112 VLOG(2) << "Creating service with UUID: " << service_uuid_
.value();
113 adapter_
->AddPairingDelegate(
115 device::BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH
);
116 adapter_
->CreateRfcommService(
118 device::BluetoothAdapter::ServiceOptions(),
119 base::Bind(&CopresencePeer::OnCreateService
,
120 weak_ptr_factory_
.GetWeakPtr()),
121 base::Bind(&CopresencePeer::OnCreateServiceError
,
122 weak_ptr_factory_
.GetWeakPtr()));
125 void CopresencePeer::OnCreateService(
126 scoped_refptr
<device::BluetoothSocket
> socket
) {
128 create_callback_
.Run(std::string());
132 server_socket_
= socket
;
133 create_callback_
.Run(GetLocatorData());
134 server_socket_
->Accept(
135 base::Bind(&CopresencePeer::OnAccept
, weak_ptr_factory_
.GetWeakPtr()),
136 base::Bind(&CopresencePeer::OnAcceptError
,
137 weak_ptr_factory_
.GetWeakPtr()));
140 void CopresencePeer::OnCreateServiceError(const std::string
& message
) {
141 LOG(WARNING
) << "Couldn't create Bluetooth service: " << message
;
142 create_callback_
.Run(std::string());
145 void CopresencePeer::OnAccept(const device::BluetoothDevice
* device
,
146 scoped_refptr
<device::BluetoothSocket
> socket
) {
149 accept_callback_
.Run(make_scoped_ptr(new CopresenceSocketBluetooth(socket
)));
152 void CopresencePeer::OnAcceptError(const std::string
& message
) {
153 LOG(WARNING
) << "Couldn't accept Bluetooth connection: " << message
;
156 } // namespace copresence_sockets