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