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