// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_MAC_H_ #define DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_MAC_H_ #include #include #import #import #include #include "base/mac/scoped_nsobject.h" #include "base/macros.h" #include "base/memory/linked_ptr.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/threading/thread_checker.h" #include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_socket.h" #include "device/bluetooth/bluetooth_uuid.h" @class BluetoothRfcommConnectionListener; @class BluetoothL2capConnectionListener; namespace net { class IOBuffer; class IOBufferWithSize; } namespace device { class BluetoothAdapterMac; class BluetoothChannelMac; // Implements the BluetoothSocket class for the Mac OS X platform. class BluetoothSocketMac : public BluetoothSocket { public: static scoped_refptr CreateSocket(); // Connects this socket to the service on |device| published as UUID |uuid|. // The underlying protocol and PSM or Channel is obtained through service // discovery. On a successful connection, the socket properties will be // updated and |success_callback| called. On failure, |error_callback| will be // called with a message explaining the cause of failure. void Connect(IOBluetoothDevice* device, const BluetoothUUID& uuid, const base::Closure& success_callback, const ErrorCompletionCallback& error_callback); // Listens for incoming RFCOMM connections using this socket: Publishes an // RFCOMM service on the |adapter| as UUID |uuid| with Channel // |options.channel|, or an automatically allocated Channel if // |options.channel| is left null. The service is published with English name // |options.name| if that is non-null. |success_callback| will be called if // the service is successfully registered, |error_callback| on failure with a // message explaining the cause. void ListenUsingRfcomm(scoped_refptr adapter, const BluetoothUUID& uuid, const BluetoothAdapter::ServiceOptions& options, const base::Closure& success_callback, const ErrorCompletionCallback& error_callback); // Listens for incoming L2CAP connections using this socket: Publishes an // L2CAP service on the |adapter| as UUID |uuid| with PSM |options.psm|, or an // automatically allocated PSM if |options.psm| is left null. The service is // published with English name |options.name| if that is non-null. // |success_callback| will be called if the service is successfully // registered, |error_callback| on failure with a message explaining the // cause. void ListenUsingL2cap(scoped_refptr adapter, const BluetoothUUID& uuid, const BluetoothAdapter::ServiceOptions& options, const base::Closure& success_callback, const ErrorCompletionCallback& error_callback); // BluetoothSocket: void Close() override; void Disconnect(const base::Closure& callback) override; void Receive(int /* buffer_size */, const ReceiveCompletionCallback& success_callback, const ReceiveErrorCompletionCallback& error_callback) override; void Send(scoped_refptr buffer, int buffer_size, const SendCompletionCallback& success_callback, const ErrorCompletionCallback& error_callback) override; void Accept(const AcceptCompletionCallback& success_callback, const ErrorCompletionCallback& error_callback) override; // Callback that is invoked when the OS completes an SDP query. // |status| is the returned status from the SDP query, |device| is the // IOBluetoothDevice for which the query was made. The remaining // parameters are those from |Connect()|. void OnSDPQueryComplete( IOReturn status, IOBluetoothDevice* device, const base::Closure& success_callback, const ErrorCompletionCallback& error_callback); // Called by BluetoothRfcommConnectionListener and // BluetoothL2capConnectionListener. void OnChannelOpened(scoped_ptr channel); // Called by |channel_|. // Note: OnChannelOpenComplete might be called before the |channel_| is set. void OnChannelOpenComplete(const std::string& device_address, IOReturn status); void OnChannelClosed(); void OnChannelDataReceived(void* data, size_t length); void OnChannelWriteComplete(void* refcon, IOReturn status); private: struct AcceptRequest { AcceptRequest(); ~AcceptRequest(); AcceptCompletionCallback success_callback; ErrorCompletionCallback error_callback; }; struct SendRequest { SendRequest(); ~SendRequest(); int buffer_size; SendCompletionCallback success_callback; ErrorCompletionCallback error_callback; IOReturn status; int active_async_writes; bool error_signaled; }; struct ReceiveCallbacks { ReceiveCallbacks(); ~ReceiveCallbacks(); ReceiveCompletionCallback success_callback; ReceiveErrorCompletionCallback error_callback; }; struct ConnectCallbacks { ConnectCallbacks(); ~ConnectCallbacks(); base::Closure success_callback; ErrorCompletionCallback error_callback; }; BluetoothSocketMac(); ~BluetoothSocketMac() override; // Accepts a single incoming connection. void AcceptConnectionRequest(); void ReleaseChannel(); void ReleaseListener(); bool is_connecting() const { return connect_callbacks_; } // Used to verify that all methods are called on the same thread. base::ThreadChecker thread_checker_; // Adapter the socket is registered against. This is only present when the // socket is listening. scoped_refptr adapter_; // UUID of the profile being connected to, or that the socket is listening on. device::BluetoothUUID uuid_; // Simple helpers that register for OS notifications and forward them to // |this| profile. base::scoped_nsobject rfcomm_connection_listener_; base::scoped_nsobject l2cap_connection_listener_; // A handle to the service record registered in the system SDP server. // Used to eventually unregister the service. BluetoothSDPServiceRecordHandle service_record_handle_; // The channel used to issue commands. scoped_ptr channel_; // Connection callbacks -- when a pending async connection is active. scoped_ptr connect_callbacks_; // Packets received while there is no pending "receive" callback. std::queue > receive_queue_; // Receive callbacks -- when a receive call is active. scoped_ptr receive_callbacks_; // Send queue -- one entry per pending send operation. std::queue> send_queue_; // The pending request to an Accept() call, or null if there is no pending // request. scoped_ptr accept_request_; // Queue of incoming connections. std::queue> accept_queue_; DISALLOW_COPY_AND_ASSIGN(BluetoothSocketMac); }; } // namespace device #endif // DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_MAC_H_