// 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.

#include "device/bluetooth/bluetooth_socket_mac.h"

#import <IOBluetooth/IOBluetooth.h>
#include <stdint.h>

#include <limits>
#include <memory>
#include <sstream>
#include <string>
#include <utility>

#include "base/bind.h"
#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/containers/queue.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/ref_counted.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "device/bluetooth/bluetooth_adapter_mac.h"
#include "device/bluetooth/bluetooth_channel_mac.h"
#include "device/bluetooth/bluetooth_classic_device_mac.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_l2cap_channel_mac.h"
#include "device/bluetooth/bluetooth_rfcomm_channel_mac.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"

using device::BluetoothSocket;

// A simple helper class that forwards SDP query completed notifications to its
// wrapped |socket_|.
@interface SDPQueryListener : NSObject {
 @private
  // The socket that registered for notifications.
  scoped_refptr<device::BluetoothSocketMac> socket_;

  // Callbacks associated with the request that triggered this SDP query.
  base::Closure success_callback_;
  BluetoothSocket::ErrorCompletionCallback error_callback_;

  // The device being queried.
  IOBluetoothDevice* device_;  // weak
}

- (id)initWithSocket:(scoped_refptr<device::BluetoothSocketMac>)socket
              device:(IOBluetoothDevice*)device
    success_callback:(base::Closure)success_callback
      error_callback:(BluetoothSocket::ErrorCompletionCallback)error_callback;
- (void)sdpQueryComplete:(IOBluetoothDevice*)device status:(IOReturn)status;

@end

@implementation SDPQueryListener

- (id)initWithSocket:(scoped_refptr<device::BluetoothSocketMac>)socket
              device:(IOBluetoothDevice*)device
    success_callback:(base::Closure)success_callback
      error_callback:(BluetoothSocket::ErrorCompletionCallback)error_callback {
  if ((self = [super init])) {
    socket_ = socket;
    device_ = device;
    success_callback_ = success_callback;
    error_callback_ = error_callback;
  }

  return self;
}

- (void)sdpQueryComplete:(IOBluetoothDevice*)device status:(IOReturn)status {
  DCHECK_EQ(device, device_);
  socket_->OnSDPQueryComplete(
      status, device, success_callback_, error_callback_);
}

@end

// A simple helper class that forwards RFCOMM channel opened notifications to
// its wrapped |socket_|.
@interface BluetoothRfcommConnectionListener : NSObject {
 @private
  // The socket that owns |self|.
  device::BluetoothSocketMac* socket_;  // weak

  // The OS mechanism used to subscribe to and unsubscribe from RFCOMM channel
  // creation notifications.
  IOBluetoothUserNotification* rfcommNewChannelNotification_;  // weak
}

- (id)initWithSocket:(device::BluetoothSocketMac*)socket
           channelID:(BluetoothRFCOMMChannelID)channelID;
- (void)rfcommChannelOpened:(IOBluetoothUserNotification*)notification
                    channel:(IOBluetoothRFCOMMChannel*)rfcommChannel;

@end

@implementation BluetoothRfcommConnectionListener

- (id)initWithSocket:(device::BluetoothSocketMac*)socket
           channelID:(BluetoothRFCOMMChannelID)channelID {
  if ((self = [super init])) {
    socket_ = socket;

    SEL selector = @selector(rfcommChannelOpened:channel:);
    const auto kIncomingDirection =
        kIOBluetoothUserNotificationChannelDirectionIncoming;
    rfcommNewChannelNotification_ =
        [IOBluetoothRFCOMMChannel
          registerForChannelOpenNotifications:self
                                     selector:selector
                                withChannelID:channelID
                                    direction:kIncomingDirection];
  }

  return self;
}

- (void)dealloc {
  [rfcommNewChannelNotification_ unregister];
  [super dealloc];
}

- (void)rfcommChannelOpened:(IOBluetoothUserNotification*)notification
                    channel:(IOBluetoothRFCOMMChannel*)rfcommChannel {
  if (notification != rfcommNewChannelNotification_) {
    // This case is reachable if there are pre-existing RFCOMM channels open at
    // the time that the listener is created. In that case, each existing
    // channel calls into this method with a different notification than the one
    // this class registered with. Ignore those; this class is only interested
    // in channels that have opened since it registered for notifications.
    return;
  }

  socket_->OnChannelOpened(std::unique_ptr<device::BluetoothChannelMac>(
      new device::BluetoothRfcommChannelMac(NULL, [rfcommChannel retain])));
}

@end

// A simple helper class that forwards L2CAP channel opened notifications to
// its wrapped |socket_|.
@interface BluetoothL2capConnectionListener : NSObject {
 @private
  // The socket that owns |self|.
  device::BluetoothSocketMac* socket_;  // weak

  // The OS mechanism used to subscribe to and unsubscribe from L2CAP channel
  // creation notifications.
  IOBluetoothUserNotification* l2capNewChannelNotification_;  // weak
}

- (id)initWithSocket:(device::BluetoothSocketMac*)socket
                 psm:(BluetoothL2CAPPSM)psm;
- (void)l2capChannelOpened:(IOBluetoothUserNotification*)notification
                   channel:(IOBluetoothL2CAPChannel*)l2capChannel;

@end

@implementation BluetoothL2capConnectionListener

- (id)initWithSocket:(device::BluetoothSocketMac*)socket
                 psm:(BluetoothL2CAPPSM)psm {
  if ((self = [super init])) {
    socket_ = socket;

    SEL selector = @selector(l2capChannelOpened:channel:);
    const auto kIncomingDirection =
        kIOBluetoothUserNotificationChannelDirectionIncoming;
    l2capNewChannelNotification_ =
        [IOBluetoothL2CAPChannel
          registerForChannelOpenNotifications:self
                                     selector:selector
                                      withPSM:psm
                                    direction:kIncomingDirection];
  }

  return self;
}

- (void)dealloc {
  [l2capNewChannelNotification_ unregister];
  [super dealloc];
}

- (void)l2capChannelOpened:(IOBluetoothUserNotification*)notification
                   channel:(IOBluetoothL2CAPChannel*)l2capChannel {
  if (notification != l2capNewChannelNotification_) {
    // This case is reachable if there are pre-existing L2CAP channels open at
    // the time that the listener is created. In that case, each existing
    // channel calls into this method with a different notification than the one
    // this class registered with. Ignore those; this class is only interested
    // in channels that have opened since it registered for notifications.
    return;
  }

  socket_->OnChannelOpened(std::unique_ptr<device::BluetoothChannelMac>(
      new device::BluetoothL2capChannelMac(NULL, [l2capChannel retain])));
}

@end

namespace device {
namespace {

// It's safe to use 0 to represent invalid channel or PSM port numbers, as both
// are required to be non-zero for valid services.
const BluetoothRFCOMMChannelID kInvalidRfcommChannelId = 0;
const BluetoothL2CAPPSM kInvalidL2capPsm = 0;

const char kInvalidOrUsedChannel[] = "Invalid channel or already in use";
const char kInvalidOrUsedPsm[] = "Invalid PSM or already in use";
const char kProfileNotFound[] = "Profile not found";
const char kSDPQueryFailed[] = "SDP query failed";
const char kSocketConnecting[] = "The socket is currently connecting";
const char kSocketAlreadyConnected[] = "The socket is already connected";
const char kSocketNotConnected[] = "The socket is not connected";
const char kReceivePending[] = "A Receive operation is pending";

template <class T>
void empty_queue(base::queue<T>& queue) {
  base::queue<T> empty;
  std::swap(queue, empty);
}

// Converts |uuid| to a IOBluetoothSDPUUID instance.
IOBluetoothSDPUUID* GetIOBluetoothSDPUUID(const BluetoothUUID& uuid) {
  // The canonical UUID format is XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.
  const std::string uuid_str = uuid.canonical_value();
  DCHECK_EQ(uuid_str.size(), 36U);
  DCHECK_EQ(uuid_str[8], '-');
  DCHECK_EQ(uuid_str[13], '-');
  DCHECK_EQ(uuid_str[18], '-');
  DCHECK_EQ(uuid_str[23], '-');
  std::string numbers_only = uuid_str;
  numbers_only.erase(23, 1);
  numbers_only.erase(18, 1);
  numbers_only.erase(13, 1);
  numbers_only.erase(8, 1);
  std::vector<uint8_t> uuid_bytes_vector;
  base::HexStringToBytes(numbers_only, &uuid_bytes_vector);
  DCHECK_EQ(uuid_bytes_vector.size(), 16U);

  return [IOBluetoothSDPUUID uuidWithBytes:&uuid_bytes_vector.front()
                                    length:uuid_bytes_vector.size()];
}

// Converts the given |integer| to a string.
NSString* IntToNSString(int integer) {
  return [@(integer) stringValue];
}

// Returns a dictionary containing the Bluetooth service definition
// corresponding to the provided |uuid|, |name|, and |protocol_definition|. Does
// not include a service name in the definition if |name| is null.
NSDictionary* BuildServiceDefinition(const BluetoothUUID& uuid,
                                     const std::string* name,
                                     NSArray* protocol_definition) {
  NSMutableDictionary* service_definition = [NSMutableDictionary dictionary];

  if (name) {
    // TODO(isherman): The service's language is currently hardcoded to English.
    // The language should ideally be specified in the chrome.bluetooth API
    // instead.
    const int kEnglishLanguageBase = 100;
    const int kServiceNameKey =
        kEnglishLanguageBase + kBluetoothSDPAttributeIdentifierServiceName;
    NSString* service_name = base::SysUTF8ToNSString(*name);
    [service_definition setObject:service_name
                           forKey:IntToNSString(kServiceNameKey)];
  }

  const int kUUIDsKey = kBluetoothSDPAttributeIdentifierServiceClassIDList;
  NSArray* uuids = @[GetIOBluetoothSDPUUID(uuid)];
  [service_definition setObject:uuids forKey:IntToNSString(kUUIDsKey)];

  const int kProtocolDefinitionsKey =
      kBluetoothSDPAttributeIdentifierProtocolDescriptorList;
  [service_definition setObject:protocol_definition
                         forKey:IntToNSString(kProtocolDefinitionsKey)];

  return service_definition;
}

// Returns a dictionary containing the Bluetooth RFCOMM service definition
// corresponding to the provided |uuid| and |options|.
NSDictionary* BuildRfcommServiceDefinition(
    const BluetoothUUID& uuid,
    const BluetoothAdapter::ServiceOptions& options) {
  int channel_id = options.channel ? *options.channel : kInvalidRfcommChannelId;
  NSArray* rfcomm_protocol_definition = @[
    @[ [IOBluetoothSDPUUID uuid16:kBluetoothSDPUUID16L2CAP] ],
    @[
      [IOBluetoothSDPUUID uuid16:kBluetoothSDPUUID16RFCOMM],
      @{
        @"DataElementType" : @1,  // Unsigned integer.
        @"DataElementSize" : @1,  // 1 byte.
        @"DataElementValue" : @(channel_id),
      },
    ],
  ];
  return BuildServiceDefinition(
      uuid, options.name.get(), rfcomm_protocol_definition);
}

// Returns a dictionary containing the Bluetooth L2CAP service definition
// corresponding to the provided |uuid| and |options|.
NSDictionary* BuildL2capServiceDefinition(
    const BluetoothUUID& uuid,
    const BluetoothAdapter::ServiceOptions& options) {
  int psm = options.psm ? *options.psm : kInvalidL2capPsm;
  NSArray* l2cap_protocol_definition = @[
    @[
      [IOBluetoothSDPUUID uuid16:kBluetoothSDPUUID16L2CAP],
      @{
        @"DataElementType" : @1,  // Unsigned integer.
        @"DataElementSize" : @2,  // 2 bytes.
        @"DataElementValue" : @(psm),
      },
    ],
  ];
  return BuildServiceDefinition(
      uuid, options.name.get(), l2cap_protocol_definition);
}

// Registers a Bluetooth service with the specified |service_definition| in the
// system SDP server. Returns the registered service on success. If the service
// could not be registered, or if |verify_service_callback| indicates that the
// to-be-registered service was not configured correctly, returns nil.
IOBluetoothSDPServiceRecord* RegisterService(
    NSDictionary* service_definition,
    const base::Callback<bool(IOBluetoothSDPServiceRecord*)>&
        verify_service_callback) {
  // Attempt to register the service.
  IOBluetoothSDPServiceRecord* service_record = [IOBluetoothSDPServiceRecord
      publishedServiceRecordWithDictionary:service_definition];

  // Verify that the registered service was configured correctly. If not,
  // withdraw the service.
  if (!service_record || !verify_service_callback.Run(service_record)) {
    [service_record removeServiceRecord];
    service_record = nil;
  }

  return service_record;
}

// Returns true iff the |requested_channel_id| was registered in the RFCOMM
// |service_record|. If it was, also updates |registered_channel_id| with the
// registered value, as the requested id may have been left unspecified.
bool VerifyRfcommService(const int* requested_channel_id,
                         BluetoothRFCOMMChannelID* registered_channel_id,
                         IOBluetoothSDPServiceRecord* service_record) {
  // Test whether the requested channel id was available.
  // TODO(isherman): The OS doesn't seem to actually pick a random channel if we
  // pass in |kInvalidRfcommChannelId|.
  BluetoothRFCOMMChannelID rfcomm_channel_id;
  IOReturn result = [service_record getRFCOMMChannelID:&rfcomm_channel_id];
  if (result != kIOReturnSuccess ||
      (requested_channel_id && rfcomm_channel_id != *requested_channel_id)) {
    return false;
  }

  *registered_channel_id = rfcomm_channel_id;
  return true;
}

// Registers an RFCOMM service with the specified |uuid|, |options.channel_id|,
// and |options.name| in the system SDP server. Automatically allocates a
// channel if |options.channel_id| is null. Does not specify a name if
// |options.name| is null. Returns a handle to the registered service and
// updates |registered_channel_id| to the actual channel id, or returns nil if
// the service could not be registered.
IOBluetoothSDPServiceRecord* RegisterRfcommService(
    const BluetoothUUID& uuid,
    const BluetoothAdapter::ServiceOptions& options,
    BluetoothRFCOMMChannelID* registered_channel_id) {
  return RegisterService(
      BuildRfcommServiceDefinition(uuid, options),
      base::Bind(
          &VerifyRfcommService, options.channel.get(), registered_channel_id));
}

// Returns true iff the |requested_psm| was registered in the L2CAP
// |service_record|. If it was, also updates |registered_psm| with the
// registered value, as the requested PSM may have been left unspecified.
bool VerifyL2capService(const int* requested_psm,
                        BluetoothL2CAPPSM* registered_psm,
                        IOBluetoothSDPServiceRecord* service_record) {
  // Test whether the requested PSM was available.
  // TODO(isherman): The OS doesn't seem to actually pick a random PSM if we
  // pass in |kInvalidL2capPsm|.
  BluetoothL2CAPPSM l2cap_psm;
  IOReturn result = [service_record getL2CAPPSM:&l2cap_psm];
  if (result != kIOReturnSuccess ||
      (requested_psm && l2cap_psm != *requested_psm)) {
    return false;
  }

  *registered_psm = l2cap_psm;
  return true;
}

// Registers an L2CAP service with the specified |uuid|, |options.psm|, and
// |options.name| in the system SDP server. Automatically allocates a PSM if
// |options.psm| is null. Does not register a name if |options.name| is null.
// Returns a handle to the registered service and updates |registered_psm| to
// the actual PSM, or returns nil if the service could not be registered.
IOBluetoothSDPServiceRecord* RegisterL2capService(
    const BluetoothUUID& uuid,
    const BluetoothAdapter::ServiceOptions& options,
    BluetoothL2CAPPSM* registered_psm) {
  return RegisterService(
      BuildL2capServiceDefinition(uuid, options),
      base::Bind(&VerifyL2capService, options.psm.get(), registered_psm));
}

}  // namespace

// static
scoped_refptr<BluetoothSocketMac> BluetoothSocketMac::CreateSocket() {
  return base::WrapRefCounted(new BluetoothSocketMac());
}

void BluetoothSocketMac::Connect(
    IOBluetoothDevice* device,
    const BluetoothUUID& uuid,
    const base::Closure& success_callback,
    const ErrorCompletionCallback& error_callback) {
  DCHECK(thread_checker_.CalledOnValidThread());

  uuid_ = uuid;

  // Perform an SDP query on the |device| to refresh the cache, in case the
  // services that the |device| advertises have changed since the previous
  // query.
  DVLOG(1) << BluetoothClassicDeviceMac::GetDeviceAddress(device) << " "
           << uuid_.canonical_value() << ": Sending SDP query.";
  SDPQueryListener* listener =
      [[SDPQueryListener alloc] initWithSocket:this
                                        device:device
                              success_callback:success_callback
                                error_callback:error_callback];
  [device performSDPQuery:[listener autorelease]
                    uuids:@[GetIOBluetoothSDPUUID(uuid_)]];
}

void BluetoothSocketMac::ListenUsingRfcomm(
    scoped_refptr<BluetoothAdapterMac> adapter,
    const BluetoothUUID& uuid,
    const BluetoothAdapter::ServiceOptions& options,
    const base::Closure& success_callback,
    const ErrorCompletionCallback& error_callback) {
  DCHECK(thread_checker_.CalledOnValidThread());

  adapter_ = adapter;
  uuid_ = uuid;

  DVLOG(1) << uuid_.canonical_value() << ": Registering RFCOMM service.";
  BluetoothRFCOMMChannelID registered_channel_id;
  service_record_.reset(
      RegisterRfcommService(uuid, options, &registered_channel_id));
  if (!service_record_.get()) {
    error_callback.Run(kInvalidOrUsedChannel);
    return;
  }

  rfcomm_connection_listener_.reset(
      [[BluetoothRfcommConnectionListener alloc]
          initWithSocket:this
               channelID:registered_channel_id]);

  success_callback.Run();
}

void BluetoothSocketMac::ListenUsingL2cap(
    scoped_refptr<BluetoothAdapterMac> adapter,
    const BluetoothUUID& uuid,
    const BluetoothAdapter::ServiceOptions& options,
    const base::Closure& success_callback,
    const ErrorCompletionCallback& error_callback) {
  DCHECK(thread_checker_.CalledOnValidThread());

  adapter_ = adapter;
  uuid_ = uuid;

  DVLOG(1) << uuid_.canonical_value() << ": Registering L2CAP service.";
  BluetoothL2CAPPSM registered_psm;
  service_record_.reset(RegisterL2capService(uuid, options, &registered_psm));
  if (!service_record_.get()) {
    error_callback.Run(kInvalidOrUsedPsm);
    return;
  }

  l2cap_connection_listener_.reset(
      [[BluetoothL2capConnectionListener alloc] initWithSocket:this
                                                           psm:registered_psm]);

  success_callback.Run();
}

void BluetoothSocketMac::OnSDPQueryComplete(
      IOReturn status,
      IOBluetoothDevice* device,
      const base::Closure& success_callback,
      const ErrorCompletionCallback& error_callback) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DVLOG(1) << BluetoothClassicDeviceMac::GetDeviceAddress(device) << " "
           << uuid_.canonical_value() << ": SDP query complete.";

  if (status != kIOReturnSuccess) {
    error_callback.Run(kSDPQueryFailed);
    return;
  }

  IOBluetoothSDPServiceRecord* record = [device
      getServiceRecordForUUID:GetIOBluetoothSDPUUID(uuid_)];
  if (record == nil) {
    error_callback.Run(kProfileNotFound);
    return;
  }

  if (is_connecting()) {
    error_callback.Run(kSocketConnecting);
    return;
  }

  if (channel_) {
    error_callback.Run(kSocketAlreadyConnected);
    return;
  }

  // Since RFCOMM is built on top of L2CAP, a service record with both should
  // always be treated as RFCOMM.
  BluetoothRFCOMMChannelID rfcomm_channel_id = kInvalidRfcommChannelId;
  BluetoothL2CAPPSM l2cap_psm = kInvalidL2capPsm;
  status = [record getRFCOMMChannelID:&rfcomm_channel_id];
  if (status != kIOReturnSuccess) {
    status = [record getL2CAPPSM:&l2cap_psm];
    if (status != kIOReturnSuccess) {
      error_callback.Run(kProfileNotFound);
      return;
    }
  }

  if (rfcomm_channel_id != kInvalidRfcommChannelId) {
    DVLOG(1) << BluetoothClassicDeviceMac::GetDeviceAddress(device) << " "
             << uuid_.canonical_value()
             << ": Opening RFCOMM channel: " << rfcomm_channel_id;
  } else {
    DCHECK_NE(l2cap_psm, kInvalidL2capPsm);
    DVLOG(1) << BluetoothClassicDeviceMac::GetDeviceAddress(device) << " "
             << uuid_.canonical_value()
             << ": Opening L2CAP channel: " << l2cap_psm;
  }

  // Note: It's important to set the connect callbacks *prior* to opening the
  // channel, as opening the channel can synchronously call into
  // OnChannelOpenComplete().
  connect_callbacks_.reset(new ConnectCallbacks());
  connect_callbacks_->success_callback = success_callback;
  connect_callbacks_->error_callback = error_callback;

  if (rfcomm_channel_id != kInvalidRfcommChannelId) {
    channel_ = BluetoothRfcommChannelMac::OpenAsync(
        this, device, rfcomm_channel_id, &status);
  } else {
    DCHECK_NE(l2cap_psm, kInvalidL2capPsm);
    channel_ =
        BluetoothL2capChannelMac::OpenAsync(this, device, l2cap_psm, &status);
  }
  if (status != kIOReturnSuccess) {
    ReleaseChannel();
    std::stringstream error;
    error << "Failed to connect bluetooth socket ("
          << BluetoothClassicDeviceMac::GetDeviceAddress(device) << "): ("
          << status << ")";
    error_callback.Run(error.str());
    return;
  }

  DVLOG(1) << BluetoothClassicDeviceMac::GetDeviceAddress(device) << " "
           << uuid_.canonical_value() << ": channel opening in background.";
}

void BluetoothSocketMac::OnChannelOpened(
    std::unique_ptr<BluetoothChannelMac> channel) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DVLOG(1) << uuid_.canonical_value() << ": Incoming channel pending.";

  accept_queue_.push(std::move(channel));
  if (accept_request_)
    AcceptConnectionRequest();

  // TODO(isherman): Currently, the socket remains alive even after the app that
  // requested it is closed. That's not great, as a misbehaving app could
  // saturate all of the system's RFCOMM channels, and then they would not be
  // freed until the user restarts Chrome.  http://crbug.com/367316
  // TODO(isherman): Likewise, the socket currently remains alive even if the
  // underlying channel is closed, e.g. via the client disconnecting, or the
  // user closing the Bluetooth connection via the system menu. This functions
  // essentially as a minor memory leak.  http://crbug.com/367319
}

void BluetoothSocketMac::OnChannelOpenComplete(
    const std::string& device_address,
    IOReturn status) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(is_connecting());

  DVLOG(1) << device_address << " " << uuid_.canonical_value()
           << ": channel open complete.";

  std::unique_ptr<ConnectCallbacks> temp = std::move(connect_callbacks_);
  if (status != kIOReturnSuccess) {
    ReleaseChannel();
    std::stringstream error;
    error << "Failed to connect bluetooth socket (" << device_address << "): ("
          << status << ")";
    temp->error_callback.Run(error.str());
    return;
  }

  temp->success_callback.Run();
}

void BluetoothSocketMac::Close() {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (channel_)
    ReleaseChannel();
  else if (service_record_.get())
    ReleaseListener();
}

void BluetoothSocketMac::Disconnect(const base::Closure& callback) {
  DCHECK(thread_checker_.CalledOnValidThread());

  Close();
  callback.Run();
}

void BluetoothSocketMac::Receive(
    int /* buffer_size */,
    const ReceiveCompletionCallback& success_callback,
    const ReceiveErrorCompletionCallback& error_callback) {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (is_connecting()) {
    error_callback.Run(BluetoothSocket::kSystemError, kSocketConnecting);
    return;
  }

  if (!channel_) {
    error_callback.Run(BluetoothSocket::kDisconnected, kSocketNotConnected);
    return;
  }

  // Only one pending read at a time
  if (receive_callbacks_) {
    error_callback.Run(BluetoothSocket::kIOPending, kReceivePending);
    return;
  }

  // If there is at least one packet, consume it and succeed right away.
  if (!receive_queue_.empty()) {
    scoped_refptr<net::IOBufferWithSize> buffer = receive_queue_.front();
    receive_queue_.pop();
    success_callback.Run(buffer->size(), buffer);
    return;
  }

  // Set the receive callback to use when data is received.
  receive_callbacks_.reset(new ReceiveCallbacks());
  receive_callbacks_->success_callback = success_callback;
  receive_callbacks_->error_callback = error_callback;
}

void BluetoothSocketMac::OnChannelDataReceived(void* data, size_t length) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!is_connecting());

  int data_size = base::checked_cast<int>(length);
  auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(data_size);
  memcpy(buffer->data(), data, buffer->size());

  // If there is a pending read callback, call it now.
  if (receive_callbacks_) {
    std::unique_ptr<ReceiveCallbacks> temp = std::move(receive_callbacks_);
    temp->success_callback.Run(buffer->size(), buffer);
    return;
  }

  // Otherwise, enqueue the buffer for later use
  receive_queue_.push(buffer);
}

void BluetoothSocketMac::Send(scoped_refptr<net::IOBuffer> buffer,
                              int buffer_size,
                              const SendCompletionCallback& success_callback,
                              const ErrorCompletionCallback& error_callback) {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (is_connecting()) {
    error_callback.Run(kSocketConnecting);
    return;
  }

  if (!channel_) {
    error_callback.Run(kSocketNotConnected);
    return;
  }

  // Create and enqueue request in preparation of async writes.
  auto request = std::make_unique<SendRequest>();
  SendRequest* request_ptr = request.get();
  request->buffer_size = buffer_size;
  request->success_callback = success_callback;
  request->error_callback = error_callback;
  send_queue_.push(std::move(request));

  // |writeAsync| accepts buffers of max. mtu bytes per call, so we need to emit
  // multiple write operations if buffer_size > mtu.
  uint16_t mtu = channel_->GetOutgoingMTU();
  auto send_buffer =
      base::MakeRefCounted<net::DrainableIOBuffer>(buffer.get(), buffer_size);
  while (send_buffer->BytesRemaining() > 0) {
    int byte_count = send_buffer->BytesRemaining();
    if (byte_count > mtu)
      byte_count = mtu;
    IOReturn status =
        channel_->WriteAsync(send_buffer->data(), byte_count, request_ptr);

    if (status != kIOReturnSuccess) {
      std::stringstream error;
      error << "Failed to connect bluetooth socket ("
            << channel_->GetDeviceAddress() << "): (" << status << ")";
      // Remember the first error only
      if (request_ptr->status == kIOReturnSuccess)
        request_ptr->status = status;
      request_ptr->error_signaled = true;
      request_ptr->error_callback.Run(error.str());
      // We may have failed to issue any write operation. In that case, there
      // will be no corresponding completion callback for this particular
      // request, so we must forget about it now.
      if (request_ptr->active_async_writes == 0) {
        send_queue_.pop();
      }
      return;
    }

    request_ptr->active_async_writes++;
    send_buffer->DidConsume(byte_count);
  }
}

void BluetoothSocketMac::OnChannelWriteComplete(void* refcon, IOReturn status) {
  DCHECK(thread_checker_.CalledOnValidThread());

  SendRequest* request_ptr = send_queue_.front().get();
  // Note: We use "CHECK" below to ensure we never run into unforeseen
  // occurrences of asynchronous callbacks, which could lead to data
  // corruption.
  CHECK_EQ(static_cast<SendRequest*>(refcon), request_ptr);

  // Remember the first error only.
  if (status != kIOReturnSuccess) {
    if (request_ptr->status == kIOReturnSuccess)
      request_ptr->status = status;
  }

  // Figure out if we are done with this async request.
  request_ptr->active_async_writes--;
  if (request_ptr->active_async_writes > 0)
    return;

  // If this was the last active async write for this request, remove it from
  // the queue and call the appropriate callback associated to the request.
  std::unique_ptr<SendRequest> request = std::move(send_queue_.front());
  send_queue_.pop();
  if (request->status != kIOReturnSuccess) {
    if (!request->error_signaled) {
      std::stringstream error;
      error << "Failed to connect bluetooth socket ("
            << channel_->GetDeviceAddress() << "): (" << status << ")";
      request->error_signaled = true;
      request->error_callback.Run(error.str());
    }
  } else {
    request->success_callback.Run(request->buffer_size);
  }
}

void BluetoothSocketMac::OnChannelClosed() {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (receive_callbacks_) {
    std::unique_ptr<ReceiveCallbacks> temp = std::move(receive_callbacks_);
    temp->error_callback.Run(BluetoothSocket::kDisconnected,
                             kSocketNotConnected);
  }

  ReleaseChannel();
}

void BluetoothSocketMac::Accept(
    const AcceptCompletionCallback& success_callback,
    const ErrorCompletionCallback& error_callback) {
  DCHECK(thread_checker_.CalledOnValidThread());

  // Allow only one pending accept at a time.
  if (accept_request_) {
    error_callback.Run(net::ErrorToString(net::ERR_IO_PENDING));
    return;
  }

  accept_request_.reset(new AcceptRequest);
  accept_request_->success_callback = success_callback;
  accept_request_->error_callback = error_callback;

  if (accept_queue_.size() >= 1)
    AcceptConnectionRequest();
}

void BluetoothSocketMac::AcceptConnectionRequest() {
  DCHECK(thread_checker_.CalledOnValidThread());
  DVLOG(1) << uuid_.canonical_value() << ": Accepting pending connection.";

  std::unique_ptr<BluetoothChannelMac> channel =
      std::move(accept_queue_.front());
  accept_queue_.pop();

  adapter_->DeviceConnected(channel->GetDevice());
  BluetoothDevice* device = adapter_->GetDevice(channel->GetDeviceAddress());
  DCHECK(device);

  scoped_refptr<BluetoothSocketMac> client_socket =
      BluetoothSocketMac::CreateSocket();

  client_socket->uuid_ = uuid_;
  client_socket->channel_ = std::move(channel);

  // Associating the socket can synchronously call into OnChannelOpenComplete().
  // Make sure to first set the new socket to be connecting and hook it up to
  // run the accept callback with the device object.
  client_socket->connect_callbacks_.reset(new ConnectCallbacks());
  client_socket->connect_callbacks_->success_callback =
      base::Bind(accept_request_->success_callback, device, client_socket);
  client_socket->connect_callbacks_->error_callback =
      accept_request_->error_callback;
  accept_request_.reset();

  // Now it's safe to associate the socket with the channel.
  client_socket->channel_->SetSocket(client_socket.get());

  DVLOG(1) << uuid_.canonical_value() << ": Accept complete.";
}

BluetoothSocketMac::AcceptRequest::AcceptRequest() {}

BluetoothSocketMac::AcceptRequest::~AcceptRequest() {}

BluetoothSocketMac::SendRequest::SendRequest()
    : status(kIOReturnSuccess), active_async_writes(0), error_signaled(false) {}

BluetoothSocketMac::SendRequest::~SendRequest() {}

BluetoothSocketMac::ReceiveCallbacks::ReceiveCallbacks() {}

BluetoothSocketMac::ReceiveCallbacks::~ReceiveCallbacks() {}

BluetoothSocketMac::ConnectCallbacks::ConnectCallbacks() {}

BluetoothSocketMac::ConnectCallbacks::~ConnectCallbacks() {}

BluetoothSocketMac::BluetoothSocketMac() {}

BluetoothSocketMac::~BluetoothSocketMac() {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!channel_);
  DCHECK(!rfcomm_connection_listener_);
}

void BluetoothSocketMac::ReleaseChannel() {
  DCHECK(thread_checker_.CalledOnValidThread());
  channel_.reset();

  // Closing the channel above prevents the callback delegate from being called
  // so it is now safe to release all callback state.
  connect_callbacks_.reset();
  receive_callbacks_.reset();
  empty_queue(receive_queue_);
  empty_queue(send_queue_);
}

void BluetoothSocketMac::ReleaseListener() {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(service_record_.get());

  [service_record_ removeServiceRecord];
  service_record_.reset();
  rfcomm_connection_listener_.reset();
  l2cap_connection_listener_.reset();

  // Destroying the listener above prevents the callback delegate from being
  // called so it is now safe to release all callback state.
  accept_request_.reset();
  empty_queue(accept_queue_);
}

}  // namespace device
