Index: device/bluetooth/bluetooth_profile_win.cc |
diff --git a/device/bluetooth/bluetooth_profile_win.cc b/device/bluetooth/bluetooth_profile_win.cc |
index 79848caf074fc2a931b307695e946dca9f8bde09..647ebf2f495c1c087b81b0ec45fc718ff05d0bc3 100644 |
--- a/device/bluetooth/bluetooth_profile_win.cc |
+++ b/device/bluetooth/bluetooth_profile_win.cc |
@@ -5,9 +5,12 @@ |
#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_win.h" |
@@ -62,19 +65,36 @@ void OnConnectErrorUI(scoped_refptr<base::SequencedTaskRunner> ui_task_runner, |
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(const BluetoothUUID& uuid, |
- const std::string& name) |
- : BluetoothProfile(), uuid_(uuid), name_(name) { |
+BluetoothProfileWin::BluetoothProfileWin() |
+ : BluetoothProfile(), rfcomm_channel_(0), weak_ptr_factory_(this) { |
} |
BluetoothProfileWin::~BluetoothProfileWin() { |
} |
void BluetoothProfileWin::Unregister() { |
+ if (profile_socket_) |
+ profile_socket_->Close(); |
+ |
delete this; |
} |
@@ -83,6 +103,19 @@ void BluetoothProfileWin::SetConnectionCallback( |
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, |
@@ -105,9 +138,10 @@ void BluetoothProfileWin::Connect( |
scoped_refptr<BluetoothSocketWin> socket( |
BluetoothSocketWin::CreateBluetoothSocket( |
- *record, ui_task_runner, socket_thread, net_log, source)); |
+ ui_task_runner, socket_thread, net_log, source)); |
- socket->Connect(base::Bind(&OnConnectSuccessUI, |
+ socket->Connect(*record, |
+ base::Bind(&OnConnectSuccessUI, |
ui_task_runner, |
success_callback, |
connection_callback_, |
@@ -116,4 +150,73 @@ void BluetoothProfileWin::Connect( |
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 |