#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/mac/scoped_nsobject.h"
#include "base/memory/scoped_refptr.h"
#include "base/threading/thread_checker.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;
namespace net {
class IOBuffer;
class IOBufferWithSize;
}
namespace device {
class BluetoothAdapterMac;
class BluetoothChannelMac;
class BluetoothSocketMac : public BluetoothSocket {
public:
static scoped_refptr<BluetoothSocketMac> CreateSocket();
BluetoothSocketMac(const BluetoothSocketMac&) = delete;
BluetoothSocketMac& operator=(const BluetoothSocketMac&) = delete;
void Connect(IOBluetoothDevice* device,
const BluetoothUUID& uuid,
base::OnceClosure success_callback,
ErrorCompletionCallback error_callback);
void ListenUsingRfcomm(scoped_refptr<BluetoothAdapterMac> adapter,
const BluetoothUUID& uuid,
const BluetoothAdapter::ServiceOptions& options,
base::OnceClosure success_callback,
ErrorCompletionCallback error_callback);
void ListenUsingL2cap(scoped_refptr<BluetoothAdapterMac> adapter,
const BluetoothUUID& uuid,
const BluetoothAdapter::ServiceOptions& options,
base::OnceClosure success_callback,
ErrorCompletionCallback error_callback);
void Disconnect(base::OnceClosure callback) override;
void Receive(int ,
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;
void OnSDPQueryComplete(IOReturn status,
IOBluetoothDevice* device,
base::OnceClosure success_callback,
ErrorCompletionCallback error_callback);
void OnChannelOpened(std::unique_ptr<BluetoothChannelMac> channel);
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::OnceClosure success_callback;
ErrorCompletionCallback error_callback;
};
BluetoothSocketMac();
~BluetoothSocketMac() override;
void AcceptConnectionRequest();
void ReleaseChannel();
void ReleaseListener();
bool is_connecting() const { return !!connect_callbacks_; }
base::ThreadChecker thread_checker_;
scoped_refptr<BluetoothAdapterMac> adapter_;
device::BluetoothUUID uuid_;
base::scoped_nsobject<BluetoothRfcommConnectionListener>
rfcomm_connection_listener_;
base::scoped_nsobject<BluetoothL2capConnectionListener>
l2cap_connection_listener_;
base::scoped_nsobject<IOBluetoothSDPServiceRecord> service_record_;
std::unique_ptr<BluetoothChannelMac> channel_;
std::unique_ptr<ConnectCallbacks> connect_callbacks_;
base::queue<scoped_refptr<net::IOBufferWithSize>> receive_queue_;
std::unique_ptr<ReceiveCallbacks> receive_callbacks_;
base::queue<std::unique_ptr<SendRequest>> send_queue_;
std::unique_ptr<AcceptRequest> accept_request_;
base::queue<std::unique_ptr<BluetoothChannelMac>> accept_queue_;
};
}
#endif