1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
|
// Copyright 2013 The Chromium Authors
// 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_
#import <IOBluetooth/IOBluetooth.h>
#import <IOKit/IOReturn.h>
#include <stddef.h>
#include <memory>
#include <string>
#include "base/containers/queue.h"
#include "base/memory/scoped_refptr.h"
#include "base/threading/thread_checker.h"
#include "base/timer/timer.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_socket.h"
#include "device/bluetooth/public/cpp/bluetooth_uuid.h"
@class BluetoothRfcommConnectionListener;
@class BluetoothL2capConnectionListener;
@class SDPQueryListener;
namespace net {
class IOBuffer;
class IOBufferWithSize;
}
namespace device {
class BluetoothAdapterMac;
class BluetoothChannelMac;
// Implements the BluetoothSocket class for the macOS platform.
class BluetoothSocketMac : public BluetoothSocket {
public:
static scoped_refptr<BluetoothSocketMac> CreateSocket();
BluetoothSocketMac(const BluetoothSocketMac&) = delete;
BluetoothSocketMac& operator=(const BluetoothSocketMac&) = delete;
// 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,
base::OnceClosure success_callback,
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<BluetoothAdapterMac> adapter,
const BluetoothUUID& uuid,
const BluetoothAdapter::ServiceOptions& options,
base::OnceClosure success_callback,
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<BluetoothAdapterMac> adapter,
const BluetoothUUID& uuid,
const BluetoothAdapter::ServiceOptions& options,
base::OnceClosure success_callback,
ErrorCompletionCallback error_callback);
// BluetoothSocket:
void Disconnect(base::OnceClosure callback) override;
void Receive(int /* buffer_size */,
ReceiveCompletionCallback success_callback,
ReceiveErrorCompletionCallback error_callback) override;
void Send(scoped_refptr<net::IOBuffer> buffer,
int buffer_size,
SendCompletionCallback success_callback,
ErrorCompletionCallback error_callback) override;
void Accept(AcceptCompletionCallback success_callback,
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,
base::OnceClosure success_callback,
ErrorCompletionCallback error_callback);
// Called by BluetoothRfcommConnectionListener and
// BluetoothL2capConnectionListener.
void OnChannelOpened(std::unique_ptr<BluetoothChannelMac> 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);
void OnChannelOpeningTimeout();
void OnSDPQueryTimeout();
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 = kIOReturnSuccess;
int active_async_writes = 0;
bool error_signaled = false;
};
struct ReceiveCallbacks {
ReceiveCallbacks();
~ReceiveCallbacks();
ReceiveCompletionCallback success_callback;
ReceiveErrorCompletionCallback error_callback;
};
struct ConnectCallbacks {
ConnectCallbacks();
~ConnectCallbacks();
base::OnceClosure 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<BluetoothAdapterMac> 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.
BluetoothRfcommConnectionListener* __strong rfcomm_connection_listener_;
BluetoothL2capConnectionListener* __strong l2cap_connection_listener_;
SDPQueryListener* __strong sdp_query_listener_;
// The service record registered in the system SDP server, used to
// eventually unregister the service.
IOBluetoothSDPServiceRecord* __strong service_record_;
// The channel used to issue commands.
std::unique_ptr<BluetoothChannelMac> channel_;
// Connection callbacks -- when a pending async connection is active.
std::unique_ptr<ConnectCallbacks> connect_callbacks_;
// Packets received while there is no pending "receive" callback.
base::queue<scoped_refptr<net::IOBufferWithSize>> receive_queue_;
// Receive callbacks -- when a receive call is active.
std::unique_ptr<ReceiveCallbacks> receive_callbacks_;
// Send queue -- one entry per pending send operation.
base::queue<std::unique_ptr<SendRequest>> send_queue_;
// The pending request to an Accept() call, or null if there is no pending
// request.
std::unique_ptr<AcceptRequest> accept_request_;
// Queue of incoming connections.
base::queue<std::unique_ptr<BluetoothChannelMac>> accept_queue_;
// One shot timer for detecting SDP query or channel opening timeout.
base::OneShotTimer timer_;
};
} // namespace device
#endif // DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_MAC_H_
|