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_MAC_H_ 6 #define DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_MAC_H_ 7 8 #include <queue> 9 #include <string> 10 11 #import <IOBluetooth/IOBluetooth.h> 12 #import <IOKit/IOReturn.h> 13 14 #include "base/mac/scoped_nsobject.h" 15 #include "base/memory/linked_ptr.h" 16 #include "base/memory/ref_counted.h" 17 #include "base/memory/scoped_ptr.h" 18 #include "base/threading/thread_checker.h" 19 #include "device/bluetooth/bluetooth_socket.h" 20 #include "device/bluetooth/bluetooth_uuid.h" 21 22 @class BluetoothRfcommConnectionListener; 23 @class BluetoothL2capConnectionListener; 24 25 namespace net { 26 class IOBuffer; 27 class IOBufferWithSize; 28 } 29 30 namespace device { 31 32 class BluetoothAdapterMac; 33 class BluetoothChannelMac; 34 35 // Implements the BluetoothSocket class for the Mac OS X platform. 36 class BluetoothSocketMac : public BluetoothSocket { 37 public: 38 static scoped_refptr<BluetoothSocketMac> CreateSocket(); 39 40 // Connects this socket to the service on |device| published as UUID |uuid|. 41 // The underlying protocol and PSM or Channel is obtained through service 42 // discovery. On a successful connection, the socket properties will be 43 // updated and |success_callback| called. On failure, |error_callback| will be 44 // called with a message explaining the cause of failure. 45 void Connect(IOBluetoothDevice* device, 46 const BluetoothUUID& uuid, 47 const base::Closure& success_callback, 48 const ErrorCompletionCallback& error_callback); 49 50 // Listens for incoming RFCOMM connections using this socket: Publishes an 51 // RFCOMM service on the |adapter| as UUID |uuid| with Channel |channel_id|. 52 // |success_callback| will be called if the service is successfully 53 // registered, |error_callback| on failure with a message explaining the 54 // cause. 55 void ListenUsingRfcomm(scoped_refptr<BluetoothAdapterMac> adapter, 56 const BluetoothUUID& uuid, 57 int channel_id, 58 const base::Closure& success_callback, 59 const ErrorCompletionCallback& error_callback); 60 61 // Listens for incoming L2CAP connections using this socket: Publishes an 62 // L2CAP service on the |adapter| as UUID |uuid| with PSM |psm|. 63 // |success_callback| will be called if the service is successfully 64 // registered, |error_callback| on failure with a message explaining the 65 // cause. 66 void ListenUsingL2cap(scoped_refptr<BluetoothAdapterMac> adapter, 67 const BluetoothUUID& uuid, 68 int psm, 69 const base::Closure& success_callback, 70 const ErrorCompletionCallback& error_callback); 71 72 // BluetoothSocket: 73 virtual void Close() OVERRIDE; 74 virtual void Disconnect(const base::Closure& callback) OVERRIDE; 75 virtual void Receive( 76 int /* buffer_size */, 77 const ReceiveCompletionCallback& success_callback, 78 const ReceiveErrorCompletionCallback& error_callback) OVERRIDE; 79 virtual void Send(scoped_refptr<net::IOBuffer> buffer, 80 int buffer_size, 81 const SendCompletionCallback& success_callback, 82 const ErrorCompletionCallback& error_callback) OVERRIDE; 83 virtual void Accept(const AcceptCompletionCallback& success_callback, 84 const ErrorCompletionCallback& error_callback) OVERRIDE; 85 86 // Callback that is invoked when the OS completes an SDP query. 87 // |status| is the returned status from the SDP query, |device| is the 88 // IOBluetoothDevice for which the query was made. The remaining 89 // parameters are those from |Connect()|. 90 void OnSDPQueryComplete( 91 IOReturn status, 92 IOBluetoothDevice* device, 93 const base::Closure& success_callback, 94 const ErrorCompletionCallback& error_callback); 95 96 // Called by BluetoothRfcommConnectionListener and 97 // BluetoothL2capConnectionListener. 98 void OnChannelOpened(scoped_ptr<BluetoothChannelMac> channel); 99 100 // Called by |channel_|. 101 // Note: OnChannelOpenComplete might be called before the |channel_| is set. 102 void OnChannelOpenComplete(const std::string& device_address, 103 IOReturn status); 104 void OnChannelClosed(); 105 void OnChannelDataReceived(void* data, size_t length); 106 void OnChannelWriteComplete(void* refcon, IOReturn status); 107 108 private: 109 struct AcceptRequest { 110 AcceptRequest(); 111 ~AcceptRequest(); 112 113 AcceptCompletionCallback success_callback; 114 ErrorCompletionCallback error_callback; 115 }; 116 117 struct SendRequest { 118 SendRequest(); 119 ~SendRequest(); 120 int buffer_size; 121 SendCompletionCallback success_callback; 122 ErrorCompletionCallback error_callback; 123 IOReturn status; 124 int active_async_writes; 125 bool error_signaled; 126 }; 127 128 struct ReceiveCallbacks { 129 ReceiveCallbacks(); 130 ~ReceiveCallbacks(); 131 ReceiveCompletionCallback success_callback; 132 ReceiveErrorCompletionCallback error_callback; 133 }; 134 135 struct ConnectCallbacks { 136 ConnectCallbacks(); 137 ~ConnectCallbacks(); 138 base::Closure success_callback; 139 ErrorCompletionCallback error_callback; 140 }; 141 142 BluetoothSocketMac(); 143 virtual ~BluetoothSocketMac(); 144 145 // Accepts a single incoming connection. 146 void AcceptConnectionRequest(); 147 148 void ReleaseChannel(); 149 void ReleaseListener(); 150 151 bool is_connecting() const { return connect_callbacks_; } 152 153 // Used to verify that all methods are called on the same thread. 154 base::ThreadChecker thread_checker_; 155 156 // Adapter the socket is registered against. This is only present when the 157 // socket is listening. 158 scoped_refptr<BluetoothAdapterMac> adapter_; 159 160 // UUID of the profile being connected to, or that the socket is listening on. 161 device::BluetoothUUID uuid_; 162 163 // Simple helpers that register for OS notifications and forward them to 164 // |this| profile. 165 base::scoped_nsobject<BluetoothRfcommConnectionListener> 166 rfcomm_connection_listener_; 167 base::scoped_nsobject<BluetoothL2capConnectionListener> 168 l2cap_connection_listener_; 169 170 // A handle to the service record registered in the system SDP server. 171 // Used to eventually unregister the service. 172 BluetoothSDPServiceRecordHandle service_record_handle_; 173 174 // The channel used to issue commands. 175 scoped_ptr<BluetoothChannelMac> channel_; 176 177 // Connection callbacks -- when a pending async connection is active. 178 scoped_ptr<ConnectCallbacks> connect_callbacks_; 179 180 // Packets received while there is no pending "receive" callback. 181 std::queue<scoped_refptr<net::IOBufferWithSize> > receive_queue_; 182 183 // Receive callbacks -- when a receive call is active. 184 scoped_ptr<ReceiveCallbacks> receive_callbacks_; 185 186 // Send queue -- one entry per pending send operation. 187 std::queue<linked_ptr<SendRequest>> send_queue_; 188 189 // The pending request to an Accept() call, or null if there is no pending 190 // request. 191 scoped_ptr<AcceptRequest> accept_request_; 192 193 // Queue of incoming connections. 194 std::queue<linked_ptr<BluetoothChannelMac>> accept_queue_; 195 196 DISALLOW_COPY_AND_ASSIGN(BluetoothSocketMac); 197 }; 198 199 } // namespace device 200 201 #endif // DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_MAC_H_ 202