Chromium Code Reviews| Index: chrome/browser/chromeos/bluetooth/bluetooth_device.cc |
| diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_device.cc b/chrome/browser/chromeos/bluetooth/bluetooth_device.cc |
| index 22d9d19e4caed1a3de3f9678e941cd3d789e8796..26880fc0aa3574b9a31e2766fce655d48703f096 100644 |
| --- a/chrome/browser/chromeos/bluetooth/bluetooth_device.cc |
| +++ b/chrome/browser/chromeos/bluetooth/bluetooth_device.cc |
| @@ -4,17 +4,26 @@ |
| #include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" |
| +#include <map> |
| #include <string> |
| #include <vector> |
| +#include <bluetooth/bluetooth.h> |
| +#include <bluetooth/rfcomm.h> |
| +#include <errno.h> |
| +#include <sys/socket.h> |
| +#include <sys/types.h> |
| + |
| #include "base/bind.h" |
| #include "base/logging.h" |
| +#include "base/memory/weak_ptr.h" |
| #include "base/string16.h" |
| #include "base/string_util.h" |
| #include "base/utf_string_conversions.h" |
| #include "base/values.h" |
| #include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" |
| #include "chrome/browser/chromeos/bluetooth/bluetooth_service_record.h" |
| +#include "chrome/browser/chromeos/bluetooth/bluetooth_socket.h" |
| #include "chrome/browser/chromeos/dbus/introspect_util.h" |
| #include "chromeos/dbus/bluetooth_adapter_client.h" |
| #include "chromeos/dbus/bluetooth_agent_service_provider.h" |
| @@ -456,6 +465,75 @@ void BluetoothDevice::Forget(ErrorCallback error_callback) { |
| error_callback)); |
| } |
| +scoped_refptr<BluetoothSocket> BluetoothDevice::OpenSocket( |
| + const std::string& service_uuid, uint8_t channel) { |
| + // TODO(bryeung): add support for L2CAP sockets as well. |
|
keybuk
2012/04/19 01:05:40
This seems to be in the wrong place, I was expecti
bryeung
2012/04/19 19:42:43
I put the code here because I wasn't sure how to d
|
| + |
| + // open a non-blocking socket, so the call to connect below will not block |
| + int socket_fd = socket( |
| + AF_BLUETOOTH, SOCK_STREAM | SOCK_NONBLOCK, BTPROTO_RFCOMM); |
| + struct sockaddr_rc socket_address = { 0 }; |
| + socket_address.rc_family = AF_BLUETOOTH; |
| + socket_address.rc_channel = channel; |
| + bdaddr_t* bluetooth_address = strtoba(address().c_str()); |
| + bacpy(&(socket_address.rc_bdaddr), bluetooth_address); |
| + free(bluetooth_address); |
| + |
| + // If EINPROGRESS, optimisticly assume that it will succeed eventually |
|
keybuk
2012/04/19 01:05:40
I believe EINPROGRESS is the only likely return va
bryeung
2012/04/19 19:42:43
Done.
|
| + int status = connect(socket_fd, (struct sockaddr *)&socket_address, |
| + sizeof(socket_address)); |
| + if (status == 0 || status == EINPROGRESS) { |
|
keybuk
2012/04/19 01:05:40
connect doesn't return EINPROGRESS, it sets errno
bryeung
2012/04/19 19:42:43
Oops. Good catch. Thanks.
|
| + BluetoothSocket* socket = new BluetoothSocket( |
| + this, service_uuid, socket_fd); |
| + return scoped_refptr<BluetoothSocket>(socket); |
| + } |
| + |
| + return NULL; |
| +} |
| + |
| +void BluetoothDevice::ConnectToMatchingService( |
| + const std::string& service_uuid, |
| + base::Callback<void(scoped_refptr<BluetoothSocket>)> callback, |
| + const dbus::ObjectPath& object_path, |
| + const BluetoothDeviceClient::ServiceMap& service_map, |
| + bool success) { |
| + if (success) { |
| + // If multiple service records are found, use the first one that works. |
| + BluetoothServiceRecord service_record; |
| + for (BluetoothDeviceClient::ServiceMap::const_iterator i = |
| + service_map.begin(); i != service_map.end(); ++i) { |
| + if (!service_record.Init(i->second)) |
|
keybuk
2012/04/19 01:05:40
Didn't we drop this Init stuff for a constructor?
bryeung
2012/04/19 19:42:43
Yep: we hadn't finished iterating on the other CL
|
| + continue; |
| + |
|
keybuk
2012/04/19 01:05:40
You don't check if this is an rfcomm service?
bryeung
2012/04/19 19:42:43
Done.
|
| + scoped_refptr<BluetoothSocket> socket = OpenSocket( |
| + service_uuid, service_record.rfcomm_channel()); |
|
keybuk
2012/04/19 01:05:40
Would be cleaner if this was a BluetoothSocket con
bryeung
2012/04/19 19:42:43
Done.
|
| + if (socket.get() != NULL) { |
| + callback.Run(socket); |
| + break; |
| + } |
| + } |
| + } |
| + callback.Run(NULL); |
| +} |
| + |
| +void BluetoothDevice::ConnectToService(const std::string& service_uuid, |
| + base::Callback<void(scoped_refptr<BluetoothSocket>)> callback) { |
| + // quick sanity check |
| + if (!ProvidesServiceWithUUID(service_uuid)) { |
| + callback.Run(NULL); |
| + return; |
| + } |
| + |
| + DBusThreadManager::Get()->GetBluetoothDeviceClient()-> |
| + DiscoverServices( |
| + object_path_, |
| + service_uuid, |
| + base::Bind(&BluetoothDevice::ConnectToMatchingService, |
| + weak_ptr_factory_.GetWeakPtr(), |
| + service_uuid, |
| + callback)); |
| +} |
| + |
| void BluetoothDevice::ForgetCallback(ErrorCallback error_callback, |
| const dbus::ObjectPath& adapter_path, |
| bool success) { |