1 // Copyright 2013 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. 4 5 #ifndef DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_CHROMEOS_H_ 6 #define DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_CHROMEOS_H_ 7 8 #include <queue> 9 #include <string> 10 11 #include "base/memory/linked_ptr.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "chromeos/chromeos_export.h" 14 #include "chromeos/dbus/bluetooth_profile_manager_client.h" 15 #include "chromeos/dbus/bluetooth_profile_service_provider.h" 16 #include "dbus/object_path.h" 17 #include "device/bluetooth/bluetooth_adapter.h" 18 #include "device/bluetooth/bluetooth_socket.h" 19 #include "device/bluetooth/bluetooth_socket_net.h" 20 #include "device/bluetooth/bluetooth_uuid.h" 21 22 namespace dbus { 23 class FileDescriptor; 24 } // namespace dbus 25 26 namespace chromeos { 27 28 class BluetoothDeviceChromeOS; 29 30 // The BluetoothSocketChromeOS class implements BluetoothSocket for the 31 // Chrome OS platform. 32 class CHROMEOS_EXPORT BluetoothSocketChromeOS 33 : public device::BluetoothSocketNet, 34 public device::BluetoothAdapter::Observer, 35 public BluetoothProfileServiceProvider::Delegate { 36 public: 37 static scoped_refptr<BluetoothSocketChromeOS> CreateBluetoothSocket( 38 scoped_refptr<base::SequencedTaskRunner> ui_task_runner, 39 scoped_refptr<device::BluetoothSocketThread> socket_thread, 40 net::NetLog* net_log, 41 const net::NetLog::Source& source); 42 43 // Connects this socket to the service on |device| published as UUID |uuid|, 44 // the underlying protocol and PSM or Channel is obtained through service 45 // discovery. On a successful connection the socket properties will be updated 46 // and |success_callback| called. On failure |error_callback| will be called 47 // with a message explaining the cause of the failure. 48 virtual void Connect(const BluetoothDeviceChromeOS* device, 49 const device::BluetoothUUID& uuid, 50 const base::Closure& success_callback, 51 const ErrorCompletionCallback& error_callback); 52 53 // Listens using this socket using a service published on |adapter|. The 54 // service is either RFCOMM or L2CAP depending on |socket_type| and published 55 // as UUID |uuid|. The |psm_or_channel| argument is interpreted according to 56 // |socket_type|. |success_callback| will be called if the service is 57 // successfully registered, |error_callback| on failure with a message 58 // explaining the cause. 59 enum SocketType { kRfcomm, kL2cap }; 60 virtual void Listen(scoped_refptr<device::BluetoothAdapter> adapter, 61 SocketType socket_type, 62 const device::BluetoothUUID& uuid, 63 int psm_or_channel, 64 const base::Closure& success_callback, 65 const ErrorCompletionCallback& error_callback); 66 67 // BluetoothSocket: 68 virtual void Close() OVERRIDE; 69 virtual void Disconnect(const base::Closure& callback) OVERRIDE; 70 virtual void Accept(const AcceptCompletionCallback& success_callback, 71 const ErrorCompletionCallback& error_callback) OVERRIDE; 72 73 // Returns the object path of the socket. 74 const dbus::ObjectPath& object_path() const { return object_path_; } 75 76 protected: 77 virtual ~BluetoothSocketChromeOS(); 78 79 private: 80 BluetoothSocketChromeOS( 81 scoped_refptr<base::SequencedTaskRunner> ui_task_runner, 82 scoped_refptr<device::BluetoothSocketThread> socket_thread, 83 net::NetLog* net_log, 84 const net::NetLog::Source& source); 85 86 // Register the underlying profile client object with the Bluetooth Daemon. 87 void RegisterProfile(const base::Closure& success_callback, 88 const ErrorCompletionCallback& error_callback); 89 void OnRegisterProfile(const base::Closure& success_callback, 90 const ErrorCompletionCallback& error_callback); 91 void OnRegisterProfileError(const ErrorCompletionCallback& error_callback, 92 const std::string& error_name, 93 const std::string& error_message); 94 95 // Called by dbus:: on completion of the ConnectProfile() method. 96 void OnConnectProfile(const base::Closure& success_callback); 97 void OnConnectProfileError(const ErrorCompletionCallback& error_callback, 98 const std::string& error_name, 99 const std::string& error_message); 100 101 // BluetoothAdapter::Observer: 102 virtual void AdapterPresentChanged(device::BluetoothAdapter* adapter, 103 bool present) OVERRIDE; 104 105 // Called by dbus:: on completion of the RegisterProfile() method call 106 // triggered as a result of the adapter becoming present again. 107 void OnInternalRegisterProfile(); 108 void OnInternalRegisterProfileError(const std::string& error_name, 109 const std::string& error_message); 110 111 // BluetoothProfileServiceProvider::Delegate: 112 virtual void Released() OVERRIDE; 113 virtual void NewConnection( 114 const dbus::ObjectPath& device_path, 115 scoped_ptr<dbus::FileDescriptor> fd, 116 const BluetoothProfileServiceProvider::Delegate::Options& options, 117 const ConfirmationCallback& callback) OVERRIDE; 118 virtual void RequestDisconnection( 119 const dbus::ObjectPath& device_path, 120 const ConfirmationCallback& callback) OVERRIDE; 121 virtual void Cancel() OVERRIDE; 122 123 // Method run to accept a single incoming connection. 124 void AcceptConnectionRequest(); 125 126 // Method run on the socket thread to validate the file descriptor of a new 127 // connection and set up the underlying net::TCPSocket() for it. 128 void DoNewConnection( 129 const dbus::ObjectPath& device_path, 130 scoped_ptr<dbus::FileDescriptor> fd, 131 const BluetoothProfileServiceProvider::Delegate::Options& options, 132 const ConfirmationCallback& callback); 133 134 // Method run on the UI thread after a new connection has been accepted and 135 // a socket allocated in |socket|. Takes care of calling the Accept() 136 // callback and |callback| with the right arguments based on |status|. 137 void OnNewConnection(scoped_refptr<BluetoothSocket> socket, 138 const ConfirmationCallback& callback, 139 Status status); 140 141 // Method run on the socket thread with a valid file descriptor |fd|, once 142 // complete calls |callback| on the UI thread with an appropriate argument 143 // indicating success or failure. 144 void DoConnect(scoped_ptr<dbus::FileDescriptor> fd, 145 const ConfirmationCallback& callback); 146 147 // Method run to clean-up a listening socket. 148 void DoCloseListening(); 149 150 // Unregister the underlying profile client object from the Bluetooth Daemon. 151 void UnregisterProfile(); 152 void OnUnregisterProfile(const dbus::ObjectPath& object_path); 153 void OnUnregisterProfileError(const dbus::ObjectPath& object_path, 154 const std::string& error_name, 155 const std::string& error_message); 156 157 // Adapter the profile is registered against; this is only present when the 158 // socket is listening. 159 scoped_refptr<device::BluetoothAdapter> adapter_; 160 161 // Address and D-Bus object path of the device being connected to, empty and 162 // ignored if the socket is listening. 163 std::string device_address_; 164 dbus::ObjectPath device_path_; 165 166 // UUID of the profile being connected to, or listening on. 167 device::BluetoothUUID uuid_; 168 169 // Copy of the profile options used for registering the profile. 170 scoped_ptr<BluetoothProfileManagerClient::Options> options_; 171 172 // Object path of the local profile D-Bus object. 173 dbus::ObjectPath object_path_; 174 175 // Local profile D-Bus object used for receiving profile delegate methods 176 // from BlueZ. 177 scoped_ptr<BluetoothProfileServiceProvider> profile_; 178 179 // Pending request to an Accept() call. 180 struct AcceptRequest { 181 AcceptRequest(); 182 ~AcceptRequest(); 183 184 AcceptCompletionCallback success_callback; 185 ErrorCompletionCallback error_callback; 186 }; 187 scoped_ptr<AcceptRequest> accept_request_; 188 189 // Queue of incoming connection requests. 190 struct ConnectionRequest { 191 ConnectionRequest(); 192 ~ConnectionRequest(); 193 194 dbus::ObjectPath device_path; 195 scoped_ptr<dbus::FileDescriptor> fd; 196 BluetoothProfileServiceProvider::Delegate::Options options; 197 ConfirmationCallback callback; 198 bool accepting; 199 bool cancelled; 200 }; 201 std::queue<linked_ptr<ConnectionRequest> > connection_request_queue_; 202 203 DISALLOW_COPY_AND_ASSIGN(BluetoothSocketChromeOS); 204 }; 205 206 } // namespace chromeos 207 208 #endif // DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_CHROMEOS_H_ 209