Commit 85317221 authored by xiyuan@chromium.org's avatar xiyuan@chromium.org

Bluetooth: Implement socket API for Windows.

- BluetoothSocketWin::StartService -> BluetoothSocketWin::Listen;
- Update BluetoothSocketWin::Connect to use a new semantics;
- Impelment BluetoothDeviceWin::ConnectToService and
  BluetoothAdapterWin::CreateRfcommService using the above two;
- Remove no longer needed BluetoothProfileWin;

BUG=372494

Review URL: https://codereview.chromium.org/320463002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@275394 0039d316-1c4b-4281-b951-d872f2087c98
parent fbda35b8
...@@ -55,8 +55,6 @@ ...@@ -55,8 +55,6 @@
'bluetooth_profile.h', 'bluetooth_profile.h',
'bluetooth_profile_mac.h', 'bluetooth_profile_mac.h',
'bluetooth_profile_mac.mm', 'bluetooth_profile_mac.mm',
'bluetooth_profile_win.cc',
'bluetooth_profile_win.h',
'bluetooth_remote_gatt_characteristic_chromeos.cc', 'bluetooth_remote_gatt_characteristic_chromeos.cc',
'bluetooth_remote_gatt_characteristic_chromeos.h', 'bluetooth_remote_gatt_characteristic_chromeos.h',
'bluetooth_remote_gatt_descriptor_chromeos.cc', 'bluetooth_remote_gatt_descriptor_chromeos.cc',
......
...@@ -167,8 +167,16 @@ void BluetoothAdapterWin::CreateRfcommService( ...@@ -167,8 +167,16 @@ void BluetoothAdapterWin::CreateRfcommService(
bool insecure, bool insecure,
const CreateServiceCallback& callback, const CreateServiceCallback& callback,
const CreateServiceErrorCallback& error_callback) { const CreateServiceErrorCallback& error_callback) {
// TODO(keybuk): implement. // Note that |insecure| is ignored.
NOTIMPLEMENTED(); scoped_refptr<BluetoothSocketWin> socket =
BluetoothSocketWin::CreateBluetoothSocket(
ui_task_runner_,
socket_thread_,
NULL,
net::NetLog::Source());
socket->Listen(this, uuid, channel,
base::Bind(callback, socket),
error_callback);
} }
void BluetoothAdapterWin::CreateL2capService( void BluetoothAdapterWin::CreateL2capService(
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include "base/memory/scoped_vector.h" #include "base/memory/scoped_vector.h"
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "device/bluetooth/bluetooth_profile_win.h"
#include "device/bluetooth/bluetooth_service_record_win.h" #include "device/bluetooth/bluetooth_service_record_win.h"
#include "device/bluetooth/bluetooth_socket_thread.h" #include "device/bluetooth/bluetooth_socket_thread.h"
#include "device/bluetooth/bluetooth_socket_win.h" #include "device/bluetooth/bluetooth_socket_win.h"
...@@ -52,7 +51,7 @@ BluetoothDeviceWin::BluetoothDeviceWin( ...@@ -52,7 +51,7 @@ BluetoothDeviceWin::BluetoothDeviceWin(
std::copy((*iter)->sdp_bytes.begin(), std::copy((*iter)->sdp_bytes.begin(),
(*iter)->sdp_bytes.end(), (*iter)->sdp_bytes.end(),
sdp_bytes_buffer); sdp_bytes_buffer);
BluetoothServiceRecord* service_record = new BluetoothServiceRecordWin( BluetoothServiceRecordWin* service_record = new BluetoothServiceRecordWin(
(*iter)->name, (*iter)->name,
(*iter)->address, (*iter)->address,
(*iter)->sdp_bytes.size(), (*iter)->sdp_bytes.size(),
...@@ -203,21 +202,17 @@ void BluetoothDeviceWin::ConnectToProfile( ...@@ -203,21 +202,17 @@ void BluetoothDeviceWin::ConnectToProfile(
const base::Closure& callback, const base::Closure& callback,
const ConnectToProfileErrorCallback& error_callback) { const ConnectToProfileErrorCallback& error_callback) {
DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
static_cast<BluetoothProfileWin*>(profile)->Connect(this, error_callback.Run("Removed. Use chrome.bluetoothSocket.connect() instead.");
ui_task_runner_,
socket_thread_,
net_log_,
net_log_source_,
callback,
error_callback);
} }
void BluetoothDeviceWin::ConnectToService( void BluetoothDeviceWin::ConnectToService(
const BluetoothUUID& uuid, const BluetoothUUID& uuid,
const ConnectToServiceCallback& callback, const ConnectToServiceCallback& callback,
const ConnectToServiceErrorCallback& error_callback) { const ConnectToServiceErrorCallback& error_callback) {
// TODO(keybuk): implement scoped_refptr<BluetoothSocketWin> socket(
NOTIMPLEMENTED(); BluetoothSocketWin::CreateBluetoothSocket(
ui_task_runner_, socket_thread_, NULL, net::NetLog::Source()));
socket->Connect(this, uuid, base::Bind(callback, socket), error_callback);
} }
void BluetoothDeviceWin::StartConnectionMonitor( void BluetoothDeviceWin::StartConnectionMonitor(
...@@ -226,7 +221,7 @@ void BluetoothDeviceWin::StartConnectionMonitor( ...@@ -226,7 +221,7 @@ void BluetoothDeviceWin::StartConnectionMonitor(
NOTIMPLEMENTED(); NOTIMPLEMENTED();
} }
const BluetoothServiceRecord* BluetoothDeviceWin::GetServiceRecord( const BluetoothServiceRecordWin* BluetoothDeviceWin::GetServiceRecord(
const device::BluetoothUUID& uuid) const { const device::BluetoothUUID& uuid) const {
for (ServiceRecordList::const_iterator iter = service_record_list_.begin(); for (ServiceRecordList::const_iterator iter = service_record_list_.begin();
iter != service_record_list_.end(); iter != service_record_list_.end();
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
namespace device { namespace device {
class BluetoothAdapterWin; class BluetoothAdapterWin;
class BluetoothServiceRecord; class BluetoothServiceRecordWin;
class BluetoothSocketThread; class BluetoothSocketThread;
class BluetoothDeviceWin : public BluetoothDevice { class BluetoothDeviceWin : public BluetoothDevice {
...@@ -78,7 +78,7 @@ class BluetoothDeviceWin : public BluetoothDevice { ...@@ -78,7 +78,7 @@ class BluetoothDeviceWin : public BluetoothDevice {
// Used by BluetoothProfileWin to retrieve the service record for the given // Used by BluetoothProfileWin to retrieve the service record for the given
// |uuid|. // |uuid|.
const BluetoothServiceRecord* GetServiceRecord( const BluetoothServiceRecordWin* GetServiceRecord(
const device::BluetoothUUID& uuid) const; const device::BluetoothUUID& uuid) const;
protected: protected:
...@@ -123,7 +123,7 @@ class BluetoothDeviceWin : public BluetoothDevice { ...@@ -123,7 +123,7 @@ class BluetoothDeviceWin : public BluetoothDevice {
UUIDList uuids_; UUIDList uuids_;
// The service records retrieved from SDP. // The service records retrieved from SDP.
typedef ScopedVector<BluetoothServiceRecord> ServiceRecordList; typedef ScopedVector<BluetoothServiceRecordWin> ServiceRecordList;
ServiceRecordList service_record_list_; ServiceRecordList service_record_list_;
DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceWin); DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceWin);
......
...@@ -6,8 +6,6 @@ ...@@ -6,8 +6,6 @@
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
#include "base/mac/mac_util.h" #include "base/mac/mac_util.h"
#elif defined(OS_WIN)
#include "device/bluetooth/bluetooth_profile_win.h"
#endif #endif
namespace device { namespace device {
...@@ -51,10 +49,6 @@ void BluetoothProfile::Register(const BluetoothUUID& uuid, ...@@ -51,10 +49,6 @@ void BluetoothProfile::Register(const BluetoothUUID& uuid,
if (base::mac::IsOSLionOrLater()) if (base::mac::IsOSLionOrLater())
profile = CreateBluetoothProfileMac(uuid, options); profile = CreateBluetoothProfileMac(uuid, options);
callback.Run(profile); callback.Run(profile);
#elif defined(OS_WIN)
BluetoothProfileWin* profile = NULL;
profile = new BluetoothProfileWin();
profile->Init(uuid, options, callback);
#else #else
callback.Run(NULL); callback.Run(NULL);
#endif #endif
......
// Copyright 2013 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 "device/bluetooth/bluetooth_profile_win.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/stringprintf.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/bluetooth_adapter_win.h"
#include "device/bluetooth/bluetooth_device_win.h"
#include "device/bluetooth/bluetooth_service_record.h"
#include "device/bluetooth/bluetooth_socket_thread.h"
#include "device/bluetooth/bluetooth_socket_win.h"
namespace {
using device::BluetoothAdapter;
using device::BluetoothDevice;
using device::BluetoothProfileWin;
using device::BluetoothSocket;
using device::BluetoothSocketWin;
const char kNoConnectionCallback[] = "Connection callback not set";
const char kProfileNotFound[] = "Profile not found";
void OnConnectSuccessUIWithAdapter(
scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
const base::Closure& callback,
const BluetoothProfileWin::ConnectionCallback& connection_callback,
const std::string& device_address,
scoped_refptr<BluetoothSocketWin> socket,
scoped_refptr<BluetoothAdapter> adapter) {
DCHECK(ui_task_runner->RunsTasksOnCurrentThread());
const BluetoothDevice* device = adapter->GetDevice(device_address);
if (device) {
connection_callback.Run(device, socket);
callback.Run();
}
}
void OnConnectSuccessUI(
scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
const base::Closure& callback,
const BluetoothProfileWin::ConnectionCallback& connection_callback,
const std::string& device_address,
scoped_refptr<BluetoothSocketWin> socket) {
DCHECK(ui_task_runner->RunsTasksOnCurrentThread());
device::BluetoothAdapterFactory::GetAdapter(
base::Bind(&OnConnectSuccessUIWithAdapter,
ui_task_runner,
callback,
connection_callback,
device_address,
socket));
}
void OnConnectErrorUI(scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
const BluetoothProfileWin::ErrorCallback& error_callback,
const std::string& error) {
DCHECK(ui_task_runner->RunsTasksOnCurrentThread());
error_callback.Run(error);
}
std::string IPEndPointToBluetoothAddress(const net::IPEndPoint& end_point) {
if (end_point.address().size() != net::kBluetoothAddressSize)
return std::string();
// The address is copied from BTH_ADDR field of SOCKADDR_BTH, which is a
// 64-bit ULONGLONG that stores Bluetooth address in little-endian. Print in
// reverse order to preserve the correct ordering.
return base::StringPrintf("%02X:%02X:%02X:%02X:%02X:%02X",
end_point.address()[5],
end_point.address()[4],
end_point.address()[3],
end_point.address()[2],
end_point.address()[1],
end_point.address()[0]);
}
} // namespace
namespace device {
BluetoothProfileWin::BluetoothProfileWin()
: BluetoothProfile(), rfcomm_channel_(0), weak_ptr_factory_(this) {
}
BluetoothProfileWin::~BluetoothProfileWin() {
}
void BluetoothProfileWin::Unregister() {
if (profile_socket_)
profile_socket_->Close();
delete this;
}
void BluetoothProfileWin::SetConnectionCallback(
const ConnectionCallback& callback) {
connection_callback_ = callback;
}
void BluetoothProfileWin::Init(const BluetoothUUID& uuid,
const BluetoothProfile::Options& options,
const ProfileCallback& callback) {
uuid_ = uuid;
name_ = options.name;
rfcomm_channel_ = options.channel;
BluetoothAdapterFactory::GetAdapter(
base::Bind(&BluetoothProfileWin::OnGetAdapter,
weak_ptr_factory_.GetWeakPtr(),
callback));
}
void BluetoothProfileWin::Connect(
const BluetoothDeviceWin* device,
scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
scoped_refptr<BluetoothSocketThread> socket_thread,
net::NetLog* net_log,
const net::NetLog::Source& source,
const base::Closure& success_callback,
const ErrorCallback& error_callback) {
DCHECK(ui_task_runner->RunsTasksOnCurrentThread());
if (connection_callback_.is_null()) {
error_callback.Run(kNoConnectionCallback);
return;
}
const BluetoothServiceRecord* record = device->GetServiceRecord(uuid_);
if (!record) {
error_callback.Run(kProfileNotFound);
return;
}
scoped_refptr<BluetoothSocketWin> socket(
BluetoothSocketWin::CreateBluetoothSocket(
ui_task_runner, socket_thread, net_log, source));
socket->Connect(*record,
base::Bind(&OnConnectSuccessUI,
ui_task_runner,
success_callback,
connection_callback_,
device->GetAddress(),
socket),
error_callback);
}
void BluetoothProfileWin::OnGetAdapter(
const ProfileCallback& callback,
scoped_refptr<BluetoothAdapter> in_adapter) {
DCHECK(!adapter_);
DCHECK(!profile_socket_);
adapter_ = in_adapter;
profile_socket_ = BluetoothSocketWin::CreateBluetoothSocket(
adapter()->ui_task_runner(),
adapter()->socket_thread(),
NULL,
net::NetLog::Source());
profile_socket_->StartService(
uuid_,
name_,
rfcomm_channel_,
base::Bind(&BluetoothProfileWin::OnRegisterProfileSuccess,
weak_ptr_factory_.GetWeakPtr(),
callback),
base::Bind(&BluetoothProfileWin::OnRegisterProfileError,
weak_ptr_factory_.GetWeakPtr(),
callback),
base::Bind(&BluetoothProfileWin::OnNewConnection,
weak_ptr_factory_.GetWeakPtr()));
}
void BluetoothProfileWin::OnRegisterProfileSuccess(
const ProfileCallback& callback) {
callback.Run(this);
}
void BluetoothProfileWin::OnRegisterProfileError(
const ProfileCallback& callback,
const std::string& error_message) {
callback.Run(NULL);
delete this;
}
void BluetoothProfileWin::OnNewConnection(
scoped_refptr<BluetoothSocketWin> connected,
const net::IPEndPoint& peer_address) {
DCHECK(adapter()->ui_task_runner()->RunsTasksOnCurrentThread());
if (connection_callback_.is_null())
return;
std::string device_address = IPEndPointToBluetoothAddress(peer_address);
if (device_address.empty()) {
LOG(WARNING) << "Failed to accept connection for profile "
<< "uuid=" << uuid_.value()
<< ", unexpected peer device address.";
return;
}
BluetoothDevice* device = adapter_->GetDevice(device_address);
if (!device) {
LOG(WARNING) << "Failed to accept connection for profile"
<< ",uuid=" << uuid_.value()
<< ", unknown device=" << device_address;
return;
}
connection_callback_.Run(device, connected);
}
BluetoothAdapterWin* BluetoothProfileWin::adapter() const {
DCHECK(adapter_);
return static_cast<BluetoothAdapterWin*>(adapter_.get());
}
} // namespace device
// Copyright 2013 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 DEVICE_BLUETOOTH_BLUETOOTH_PROFILE_WIN_H_
#define DEVICE_BLUETOOTH_BLUETOOTH_PROFILE_WIN_H_
#include <string>
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "device/bluetooth/bluetooth_profile.h"
#include "device/bluetooth/bluetooth_uuid.h"
#include "net/base/net_log.h"
#include "net/socket/tcp_socket.h"
namespace net {
class IPEndPoint;
}
namespace device {
class BluetoothAdapter;
class BluetoothAdapterWin;
class BluetoothDeviceWin;
class BluetoothSocketThread;
class BluetoothSocketWin;
class BluetoothProfileWin : public BluetoothProfile {
public:
typedef base::Callback<void(const std::string&)> ErrorCallback;
// BluetoothProfile override.
virtual void Unregister() OVERRIDE;
virtual void SetConnectionCallback(
const ConnectionCallback& callback) OVERRIDE;
// Called by BluetoothProfile::Register to initialize the profile object
// asynchronously.
void Init(const BluetoothUUID& uuid,
const device::BluetoothProfile::Options& options,
const ProfileCallback& callback);
void Connect(const BluetoothDeviceWin* device,
scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
scoped_refptr<BluetoothSocketThread> socket_thread,
net::NetLog* net_log,
const net::NetLog::Source& source,
const base::Closure& callback,
const ErrorCallback& error_callback);
private:
friend BluetoothProfile;
BluetoothProfileWin();
virtual ~BluetoothProfileWin();
// Internal method run to get the adapter object during initialization.
void OnGetAdapter(const ProfileCallback& callback,
scoped_refptr<BluetoothAdapter> adapter);
// Callbacks for |profile_socket_|'s StartService call.
void OnRegisterProfileSuccess(const ProfileCallback& callback);
void OnRegisterProfileError(const ProfileCallback& callback,
const std::string& error_message);
// Callback when |profile_socket_| accepts a connection.
void OnNewConnection(scoped_refptr<BluetoothSocketWin> connected,
const net::IPEndPoint& peer_address);
BluetoothAdapterWin* adapter() const;
BluetoothUUID uuid_;
std::string name_;
int rfcomm_channel_;
ConnectionCallback connection_callback_;
scoped_refptr<BluetoothAdapter> adapter_;
scoped_refptr<BluetoothSocketWin> profile_socket_;
base::WeakPtrFactory<BluetoothProfileWin> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BluetoothProfileWin);
};
} // namespace device
#endif // DEVICE_BLUETOOTH_BLUETOOTH_PROFILE_WIN_H_
...@@ -11,9 +11,11 @@ ...@@ -11,9 +11,11 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
#include "device/bluetooth/bluetooth_device_win.h"
#include "device/bluetooth/bluetooth_init_win.h" #include "device/bluetooth/bluetooth_init_win.h"
#include "device/bluetooth/bluetooth_service_record_win.h" #include "device/bluetooth/bluetooth_service_record_win.h"
#include "device/bluetooth/bluetooth_socket_thread.h" #include "device/bluetooth/bluetooth_socket_thread.h"
...@@ -31,9 +33,25 @@ const char kFailedToCreateSocket[] = "Failed to create socket."; ...@@ -31,9 +33,25 @@ const char kFailedToCreateSocket[] = "Failed to create socket.";
const char kFailedToBindSocket[] = "Failed to bind socket."; const char kFailedToBindSocket[] = "Failed to bind socket.";
const char kFailedToListenOnSocket[] = "Failed to listen on socket."; const char kFailedToListenOnSocket[] = "Failed to listen on socket.";
const char kFailedToGetSockNameForSocket[] = "Failed to getsockname."; const char kFailedToGetSockNameForSocket[] = "Failed to getsockname.";
const char kBadUuid[] = "Bad uuid."; const char kFailedToAccept[] = "Failed to accept.";
const char kInvalidUUID[] = "Invalid UUID";
const char kWsaSetServiceError[] = "WSASetService error."; const char kWsaSetServiceError[] = "WSASetService error.";
std::string IPEndPointToBluetoothAddress(const net::IPEndPoint& end_point) {
if (end_point.address().size() != net::kBluetoothAddressSize)
return std::string();
// The address is copied from BTH_ADDR field of SOCKADDR_BTH, which is a
// 64-bit ULONGLONG that stores Bluetooth address in little-endian. Print in
// reverse order to preserve the correct ordering.
return base::StringPrintf("%02X:%02X:%02X:%02X:%02X:%02X",
end_point.address()[5],
end_point.address()[4],
end_point.address()[3],
end_point.address()[2],
end_point.address()[1],
end_point.address()[0]);
}
} // namespace } // namespace
namespace device { namespace device {
...@@ -80,37 +98,28 @@ BluetoothSocketWin::BluetoothSocketWin( ...@@ -80,37 +98,28 @@ BluetoothSocketWin::BluetoothSocketWin(
BluetoothSocketWin::~BluetoothSocketWin() { BluetoothSocketWin::~BluetoothSocketWin() {
} }
void BluetoothSocketWin::StartService(
const BluetoothUUID& uuid,
const std::string& name,
int rfcomm_channel,
const base::Closure& success_callback,
const ErrorCompletionCallback& error_callback,
const OnNewConnectionCallback& new_connection_callback) {
DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
socket_thread()->task_runner()->PostTask(
FROM_HERE,
base::Bind(&BluetoothSocketWin::DoStartService,
this,
uuid,
name,
rfcomm_channel,
success_callback,
error_callback,
new_connection_callback));
}
void BluetoothSocketWin::Connect( void BluetoothSocketWin::Connect(
const BluetoothServiceRecord& service_record, const BluetoothDeviceWin* device,
const BluetoothUUID& uuid,
const base::Closure& success_callback, const base::Closure& success_callback,
const ErrorCompletionCallback& error_callback) { const ErrorCompletionCallback& error_callback) {
DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
DCHECK(device);
if (!uuid.IsValid()) {
error_callback.Run(kInvalidUUID);
return;
}
const BluetoothServiceRecordWin* service_record_win = const BluetoothServiceRecordWin* service_record_win =
static_cast<const BluetoothServiceRecordWin*>(&service_record); device->GetServiceRecord(uuid);
if (!service_record_win) {
error_callback.Run(kInvalidUUID);
return;
}
device_address_ = service_record_win->address(); device_address_ = service_record_win->address();
if (service_record.SupportsRfcomm()) { if (service_record_win->SupportsRfcomm()) {
supports_rfcomm_ = true; supports_rfcomm_ = true;
rfcomm_channel_ = service_record_win->rfcomm_channel(); rfcomm_channel_ = service_record_win->rfcomm_channel();
bth_addr_ = service_record_win->bth_addr(); bth_addr_ = service_record_win->bth_addr();
...@@ -126,6 +135,24 @@ void BluetoothSocketWin::Connect( ...@@ -126,6 +135,24 @@ void BluetoothSocketWin::Connect(
&BluetoothSocketWin::PostErrorCompletion, this, error_callback))); &BluetoothSocketWin::PostErrorCompletion, this, error_callback)));
} }
void BluetoothSocketWin::Listen(scoped_refptr<BluetoothAdapter> adapter,
const BluetoothUUID& uuid,
int rfcomm_channel,
const base::Closure& success_callback,
const ErrorCompletionCallback& error_callback) {
DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
adapter_ = adapter;
socket_thread()->task_runner()->PostTask(
FROM_HERE,
base::Bind(&BluetoothSocketWin::DoListen,
this,
uuid,
rfcomm_channel,
success_callback,
error_callback));
}
void BluetoothSocketWin::ResetData() { void BluetoothSocketWin::ResetData() {
if (service_reg_data_) { if (service_reg_data_) {
...@@ -140,7 +167,14 @@ void BluetoothSocketWin::ResetData() { ...@@ -140,7 +167,14 @@ void BluetoothSocketWin::ResetData() {
void BluetoothSocketWin::Accept( void BluetoothSocketWin::Accept(
const AcceptCompletionCallback& success_callback, const AcceptCompletionCallback& success_callback,
const ErrorCompletionCallback& error_callback) { const ErrorCompletionCallback& error_callback) {
NOTIMPLEMENTED(); DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
socket_thread()->task_runner()->PostTask(
FROM_HERE,
base::Bind(&BluetoothSocketWin::DoAccept,
this,
success_callback,
error_callback));
} }
void BluetoothSocketWin::DoConnect( void BluetoothSocketWin::DoConnect(
...@@ -196,17 +230,13 @@ void BluetoothSocketWin::DoConnect( ...@@ -196,17 +230,13 @@ void BluetoothSocketWin::DoConnect(
success_callback.Run(); success_callback.Run();
} }
void BluetoothSocketWin::DoStartService( void BluetoothSocketWin::DoListen(
const BluetoothUUID& uuid, const BluetoothUUID& uuid,
const std::string& name,
int rfcomm_channel, int rfcomm_channel,
const base::Closure& success_callback, const base::Closure& success_callback,
const ErrorCompletionCallback& error_callback, const ErrorCompletionCallback& error_callback) {
const OnNewConnectionCallback& new_connection_callback) {
DCHECK(socket_thread()->task_runner()->RunsTasksOnCurrentThread()); DCHECK(socket_thread()->task_runner()->RunsTasksOnCurrentThread());
DCHECK(!tcp_socket() && DCHECK(!tcp_socket() && !service_reg_data_);
!service_reg_data_ &&
on_new_connection_callback_.is_null());
// The valid range is 0-30. 0 means BT_PORT_ANY and 1-30 are the // The valid range is 0-30. 0 means BT_PORT_ANY and 1-30 are the
// valid RFCOMM port numbers of SOCKADDR_BTH. // valid RFCOMM port numbers of SOCKADDR_BTH.
...@@ -255,7 +285,7 @@ void BluetoothSocketWin::DoStartService( ...@@ -255,7 +285,7 @@ void BluetoothSocketWin::DoStartService(
} }
scoped_ptr<ServiceRegData> reg_data(new ServiceRegData); scoped_ptr<ServiceRegData> reg_data(new ServiceRegData);
reg_data->name = base::UTF8ToUTF16(name); reg_data->name = base::UTF8ToUTF16(uuid.canonical_value());
if (getsockname(socket_fd, sock_addr, &sock_addr_len)) { if (getsockname(socket_fd, sock_addr, &sock_addr_len)) {
LOG(WARNING) << "Failed to start service: getsockname, " LOG(WARNING) << "Failed to start service: getsockname, "
...@@ -275,8 +305,8 @@ void BluetoothSocketWin::DoStartService( ...@@ -275,8 +305,8 @@ void BluetoothSocketWin::DoStartService(
uuid.canonical_value()) + L"}"; uuid.canonical_value()) + L"}";
if (!SUCCEEDED(CLSIDFromString(cannonical_uuid.c_str(), &reg_data->uuid))) { if (!SUCCEEDED(CLSIDFromString(cannonical_uuid.c_str(), &reg_data->uuid))) {
LOG(WARNING) << "Failed to start service: " LOG(WARNING) << "Failed to start service: "
<< ", bad uuid=" << cannonical_uuid; << ", invalid uuid=" << cannonical_uuid;
PostErrorCompletion(error_callback, kBadUuid); PostErrorCompletion(error_callback, kInvalidUUID);
return; return;
} }
...@@ -298,26 +328,35 @@ void BluetoothSocketWin::DoStartService( ...@@ -298,26 +328,35 @@ void BluetoothSocketWin::DoStartService(
SetTCPSocket(scoped_socket.Pass()); SetTCPSocket(scoped_socket.Pass());
service_reg_data_ = reg_data.Pass(); service_reg_data_ = reg_data.Pass();
on_new_connection_callback_ = new_connection_callback;
DoAccept();
PostSuccess(success_callback); PostSuccess(success_callback);
} }
void BluetoothSocketWin::DoAccept() { void BluetoothSocketWin::DoAccept(
const AcceptCompletionCallback& success_callback,
const ErrorCompletionCallback& error_callback) {
DCHECK(socket_thread()->task_runner()->RunsTasksOnCurrentThread()); DCHECK(socket_thread()->task_runner()->RunsTasksOnCurrentThread());
int result = tcp_socket()->Accept( int result = tcp_socket()->Accept(
&accept_socket_, &accept_socket_,
&accept_address_, &accept_address_,
base::Bind(&BluetoothSocketWin::OnAcceptOnSocketThread, this)); base::Bind(&BluetoothSocketWin::OnAcceptOnSocketThread,
if (result != net::OK && result != net::ERR_IO_PENDING) this,
success_callback,
error_callback));
if (result != net::OK && result != net::ERR_IO_PENDING) {
LOG(WARNING) << "Failed to accept, net err=" << result; LOG(WARNING) << "Failed to accept, net err=" << result;
PostErrorCompletion(error_callback, kFailedToAccept);
}
} }
void BluetoothSocketWin::OnAcceptOnSocketThread(int accept_result) { void BluetoothSocketWin::OnAcceptOnSocketThread(
const AcceptCompletionCallback& success_callback,
const ErrorCompletionCallback& error_callback,
int accept_result) {
DCHECK(socket_thread()->task_runner()->RunsTasksOnCurrentThread()); DCHECK(socket_thread()->task_runner()->RunsTasksOnCurrentThread());
if (accept_result != net::OK) { if (accept_result != net::OK) {
LOG(WARNING) << "OnAccept error, net err=" << accept_result; LOG(WARNING) << "OnAccept error, net err=" << accept_result;
PostErrorCompletion(error_callback, kFailedToAccept);
return; return;
} }
...@@ -326,23 +365,35 @@ void BluetoothSocketWin::OnAcceptOnSocketThread(int accept_result) { ...@@ -326,23 +365,35 @@ void BluetoothSocketWin::OnAcceptOnSocketThread(int accept_result) {
base::Bind(&BluetoothSocketWin::OnAcceptOnUI, base::Bind(&BluetoothSocketWin::OnAcceptOnUI,
this, this,
base::Passed(&accept_socket_), base::Passed(&accept_socket_),
accept_address_)); accept_address_,
DoAccept(); success_callback,
error_callback));
} }
void BluetoothSocketWin::OnAcceptOnUI( void BluetoothSocketWin::OnAcceptOnUI(
scoped_ptr<net::TCPSocket> accept_socket, scoped_ptr<net::TCPSocket> accept_socket,
const net::IPEndPoint& peer_address) { const net::IPEndPoint& peer_address,
const AcceptCompletionCallback& success_callback,
const ErrorCompletionCallback& error_callback) {
DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
scoped_refptr<BluetoothSocketWin> peer = CreateBluetoothSocket( const std::string peer_device_address =
IPEndPointToBluetoothAddress(peer_address);
const BluetoothDevice* peer_device = adapter_->GetDevice(peer_device_address);
if (!peer_device) {
LOG(WARNING) << "OnAccept failed with unknown device, addr="
<< peer_device_address;
error_callback.Run(kFailedToAccept);
return;
}
scoped_refptr<BluetoothSocketWin> peer_socket = CreateBluetoothSocket(
ui_task_runner(), ui_task_runner(),
socket_thread(), socket_thread(),
net_log(), net_log(),
source()); source());
peer->SetTCPSocket(accept_socket.Pass()); peer_socket->SetTCPSocket(accept_socket.Pass());
success_callback.Run(peer_device, peer_socket);
on_new_connection_callback_.Run(peer, peer_address);
} }
} // namespace device } // namespace device
...@@ -13,45 +13,43 @@ ...@@ -13,45 +13,43 @@
#include "device/bluetooth/bluetooth_service_record_win.h" #include "device/bluetooth/bluetooth_service_record_win.h"
#include "device/bluetooth/bluetooth_socket.h" #include "device/bluetooth/bluetooth_socket.h"
#include "device/bluetooth/bluetooth_socket_net.h" #include "device/bluetooth/bluetooth_socket_net.h"
#include "device/bluetooth/bluetooth_uuid.h"
#include "net/base/ip_endpoint.h" #include "net/base/ip_endpoint.h"
#include "net/socket/tcp_socket.h" #include "net/socket/tcp_socket.h"
namespace device { namespace device {
class BluetoothServiceRecord; class BluetoothAdapter;
class BluetoothDeviceWin;
// The BluetoothSocketWin class implements BluetoothSocket for the Microsoft // The BluetoothSocketWin class implements BluetoothSocket for the Microsoft
// Windows platform. // Windows platform.
class BluetoothSocketWin : public BluetoothSocketNet { class BluetoothSocketWin : public BluetoothSocketNet {
public: public:
typedef base::Callback<void(scoped_refptr<BluetoothSocketWin>,
const net::IPEndPoint&)> OnNewConnectionCallback;
static scoped_refptr<BluetoothSocketWin> CreateBluetoothSocket( static scoped_refptr<BluetoothSocketWin> CreateBluetoothSocket(
scoped_refptr<base::SequencedTaskRunner> ui_task_runner, scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
scoped_refptr<BluetoothSocketThread> socket_thread, scoped_refptr<BluetoothSocketThread> socket_thread,
net::NetLog* net_log, net::NetLog* net_log,
const net::NetLog::Source& source); const net::NetLog::Source& source);
// Starts a service with the given uuid, name and rfcomm_channel. // Connect to the peer device and calls |success_callback| when the
// |success_callback| is invoked when the underlying socket is created
// and the service is published successfully. Otherwise, |error_callback| is
// called with an error message. |new_connection_callback| is invoked when
// an incoming connection is accepted by the underlying socket.
void StartService(
const BluetoothUUID& uuid,
const std::string& name,
int rfcomm_channel,
const base::Closure& success_callback,
const ErrorCompletionCallback& error_callback,
const OnNewConnectionCallback& new_connection_callback);
// connection has been established successfully. If an error occurs, calls // connection has been established successfully. If an error occurs, calls
// |error_callback| with a system error message. // |error_callback| with a system error message.
void Connect(const BluetoothServiceRecord& service_record, void Connect(const BluetoothDeviceWin* device,
const BluetoothUUID& uuid,
const base::Closure& success_callback, const base::Closure& success_callback,
const ErrorCompletionCallback& error_callback); const ErrorCompletionCallback& error_callback);
// Listens using this socket using an RFCOMM service published as UUID |uuid|
// with Channel |channel|. |success_callback| will be called if the service
// is successfully registered, |error_callback| on failure with a message
// explaining the cause.
void Listen(scoped_refptr<BluetoothAdapter> adapter,
const BluetoothUUID& uuid,
int rfcomm_channel,
const base::Closure& success_callback,
const ErrorCompletionCallback& error_callback);
// BluetoothSocketNet: // BluetoothSocketNet:
void ResetData(); void ResetData();
...@@ -59,7 +57,6 @@ class BluetoothSocketWin : public BluetoothSocketNet { ...@@ -59,7 +57,6 @@ class BluetoothSocketWin : public BluetoothSocketNet {
virtual void Accept(const AcceptCompletionCallback& success_callback, virtual void Accept(const AcceptCompletionCallback& success_callback,
const ErrorCompletionCallback& error_callback) OVERRIDE; const ErrorCompletionCallback& error_callback) OVERRIDE;
protected: protected:
virtual ~BluetoothSocketWin(); virtual ~BluetoothSocketWin();
...@@ -74,26 +71,30 @@ class BluetoothSocketWin : public BluetoothSocketNet { ...@@ -74,26 +71,30 @@ class BluetoothSocketWin : public BluetoothSocketNet {
void DoConnect(const base::Closure& success_callback, void DoConnect(const base::Closure& success_callback,
const ErrorCompletionCallback& error_callback); const ErrorCompletionCallback& error_callback);
void DoStartService(const BluetoothUUID& uuid, void DoListen(const BluetoothUUID& uuid,
const std::string& name,
int rfcomm_channel, int rfcomm_channel,
const base::Closure& success_callback, const base::Closure& success_callback,
const ErrorCompletionCallback& error_callback, const ErrorCompletionCallback& error_callback);
const OnNewConnectionCallback& new_connection_callback); void DoAccept(const AcceptCompletionCallback& success_callback,
void DoAccept(); const ErrorCompletionCallback& error_callback);
void OnAcceptOnSocketThread(int accept_result); void OnAcceptOnSocketThread(const AcceptCompletionCallback& success_callback,
const ErrorCompletionCallback& error_callback,
int accept_result);
void OnAcceptOnUI(scoped_ptr<net::TCPSocket> accept_socket, void OnAcceptOnUI(scoped_ptr<net::TCPSocket> accept_socket,
const net::IPEndPoint& peer_address); const net::IPEndPoint& peer_address,
const AcceptCompletionCallback& success_callback,
const ErrorCompletionCallback& error_callback);
std::string device_address_; std::string device_address_;
bool supports_rfcomm_; bool supports_rfcomm_;
uint8 rfcomm_channel_; uint8 rfcomm_channel_;
BTH_ADDR bth_addr_; BTH_ADDR bth_addr_;
// Data members below are only used when listening.
scoped_refptr<device::BluetoothAdapter> adapter_;
scoped_ptr<ServiceRegData> service_reg_data_; scoped_ptr<ServiceRegData> service_reg_data_;
scoped_ptr<net::TCPSocket> accept_socket_; scoped_ptr<net::TCPSocket> accept_socket_;
net::IPEndPoint accept_address_; net::IPEndPoint accept_address_;
OnNewConnectionCallback on_new_connection_callback_;
DISALLOW_COPY_AND_ASSIGN(BluetoothSocketWin); DISALLOW_COPY_AND_ASSIGN(BluetoothSocketWin);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment