diff options
author | youngki@chromium.org <youngki@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-18 21:07:03 +0000 |
---|---|---|
committer | youngki@chromium.org <youngki@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-18 21:07:03 +0000 |
commit | 6cc9b8da83a5ed6c44a8e32b570cd0783fae1073 (patch) | |
tree | 57e29d09d7dd515438ad99729fad1219b80e2fb7 /device | |
parent | 90c82955e2f76f7e393983653193e02302efecd4 (diff) | |
download | chromium_src-6cc9b8da83a5ed6c44a8e32b570cd0783fae1073.zip chromium_src-6cc9b8da83a5ed6c44a8e32b570cd0783fae1073.tar.gz chromium_src-6cc9b8da83a5ed6c44a8e32b570cd0783fae1073.tar.bz2 |
Implemented BluetoothSocketMac.
BUG=135472
Review URL: https://chromiumcodereview.appspot.com/12693010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@188816 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'device')
-rw-r--r-- | device/bluetooth/bluetooth_adapter_win.h | 2 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_device_win.h | 3 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_socket_mac.h | 66 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_socket_mac.mm | 141 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_socket_win.h | 2 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_task_manager_win.h | 4 | ||||
-rw-r--r-- | device/device.gyp | 2 |
7 files changed, 215 insertions, 5 deletions
diff --git a/device/bluetooth/bluetooth_adapter_win.h b/device/bluetooth/bluetooth_adapter_win.h index 178a995..76581d9 100644 --- a/device/bluetooth/bluetooth_adapter_win.h +++ b/device/bluetooth/bluetooth_adapter_win.h @@ -77,7 +77,7 @@ class BluetoothAdapterWin : public BluetoothAdapter, DISCOVERY_STOPPING }; - BluetoothAdapterWin(const InitCallback& init_callback); + explicit BluetoothAdapterWin(const InitCallback& init_callback); virtual ~BluetoothAdapterWin(); void TrackDefaultAdapter(); diff --git a/device/bluetooth/bluetooth_device_win.h b/device/bluetooth/bluetooth_device_win.h index 9e56bc0..b1e9d80 100644 --- a/device/bluetooth/bluetooth_device_win.h +++ b/device/bluetooth/bluetooth_device_win.h @@ -18,7 +18,8 @@ class BluetoothAdapterWin; class BluetoothDeviceWin : public BluetoothDevice { public: - BluetoothDeviceWin(const BluetoothTaskManagerWin::DeviceState& state); + explicit BluetoothDeviceWin( + const BluetoothTaskManagerWin::DeviceState& state); virtual ~BluetoothDeviceWin(); void SetVisible(bool visible); diff --git a/device/bluetooth/bluetooth_socket_mac.h b/device/bluetooth/bluetooth_socket_mac.h new file mode 100644 index 0000000..5689a42 --- /dev/null +++ b/device/bluetooth/bluetooth_socket_mac.h @@ -0,0 +1,66 @@ +// 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 <string> + +#include "base/memory/ref_counted.h" +#include "device/bluetooth/bluetooth_socket.h" + +#ifdef __OBJC__ +@class BluetoothRFCOMMChannelDelegate; +@class IOBluetoothRFCOMMChannel; +#else +class BluetoothRFCOMMChannelDelegate; +class IOBluetoothRFCOMMChannel; +#endif + +namespace net { + +class DrainableIOBuffer; +class GrowableIOBuffer; + +} // namespace net + +namespace device { + +class BluetoothServiceRecord; + +// This class is an implementation of BluetoothSocket class for OSX platform. +class BluetoothSocketMac : public BluetoothSocket { + public: + static scoped_refptr<BluetoothSocket> CreateBluetoothSocket( + const BluetoothServiceRecord& service_record); + + // BluetoothSocket override + virtual bool Receive(net::GrowableIOBuffer* buffer) OVERRIDE; + virtual bool Send(net::DrainableIOBuffer* buffer) OVERRIDE; + virtual std::string GetLastErrorMessage() const OVERRIDE; + + // called by BluetoothRFCOMMChannelDelegate. + void OnDataReceived(IOBluetoothRFCOMMChannel* rfcomm_channel, + void* data, + size_t length); + + protected: + virtual ~BluetoothSocketMac(); + + private: + explicit BluetoothSocketMac(IOBluetoothRFCOMMChannel* rfcomm_channel); + + void ResetIncomingDataBuffer(); + + IOBluetoothRFCOMMChannel* rfcomm_channel_; + BluetoothRFCOMMChannelDelegate* delegate_; + scoped_refptr<net::GrowableIOBuffer> incoming_data_buffer_; + std::string error_message_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothSocketMac); +}; + +} // namespace device + +#endif // DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_MAC_H_ diff --git a/device/bluetooth/bluetooth_socket_mac.mm b/device/bluetooth/bluetooth_socket_mac.mm new file mode 100644 index 0000000..83b30a8 --- /dev/null +++ b/device/bluetooth/bluetooth_socket_mac.mm @@ -0,0 +1,141 @@ +// 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/objc/IOBluetoothDevice.h> +#import <IOBluetooth/objc/IOBluetoothRFCOMMChannel.h> + +#include <limits> +#include <string> + +#include "base/memory/ref_counted.h" +#include "base/stringprintf.h" +#include "device/bluetooth/bluetooth_service_record.h" +#include "device/bluetooth/bluetooth_service_record_mac.h" +#include "net/base/io_buffer.h" + +@interface BluetoothRFCOMMChannelDelegate + : NSObject <IOBluetoothRFCOMMChannelDelegate> { + @private + device::BluetoothSocketMac* socket_; // weak +} + +- (id)initWithSocket:(device::BluetoothSocketMac*)socket; + +@end + +@implementation BluetoothRFCOMMChannelDelegate + +- (id)initWithSocket:(device::BluetoothSocketMac*)socket { + if ((self = [super init])) + socket_ = socket; + + return self; +} + +- (void)rfcommChannelData:(IOBluetoothRFCOMMChannel*)rfcommChannel + data:(void*)dataPointer + length:(size_t)dataLength { + socket_->OnDataReceived(rfcommChannel, dataPointer, dataLength); +} + +@end + +namespace device { + +BluetoothSocketMac::BluetoothSocketMac(IOBluetoothRFCOMMChannel* rfcomm_channel) + : rfcomm_channel_(rfcomm_channel), + delegate_([[BluetoothRFCOMMChannelDelegate alloc] initWithSocket:this]) { + [rfcomm_channel_ setDelegate:delegate_]; + ResetIncomingDataBuffer(); +} + +BluetoothSocketMac::~BluetoothSocketMac() { + [rfcomm_channel_ release]; + [delegate_ release]; +} + +// static +scoped_refptr<BluetoothSocket> BluetoothSocketMac::CreateBluetoothSocket( + const BluetoothServiceRecord& service_record) { + BluetoothSocketMac* bluetooth_socket = NULL; + if (service_record.SupportsRfcomm()) { + const BluetoothServiceRecordMac* service_record_mac = + static_cast<const BluetoothServiceRecordMac*>(&service_record); + IOBluetoothDevice* device = service_record_mac->GetIOBluetoothDevice(); + IOBluetoothRFCOMMChannel* rfcomm_channel; + IOReturn status = + [device openRFCOMMChannelAsync:&rfcomm_channel + withChannelID:service_record.rfcomm_channel() + delegate:nil]; + if (status == kIOReturnSuccess) { + bluetooth_socket = new BluetoothSocketMac(rfcomm_channel); + } else { + LOG(ERROR) << "Failed to connect bluetooth socket (" + << service_record.address() << "): (" << status << ")"; + } + } + // TODO(youngki): add support for L2CAP sockets as well. + + return scoped_refptr<BluetoothSocketMac>(bluetooth_socket); +} + +bool BluetoothSocketMac::Receive(net::GrowableIOBuffer* buffer) { + CHECK(buffer->offset() == 0); + int length = incoming_data_buffer_->offset(); + if (length > 0) { + buffer->SetCapacity(length); + memcpy(buffer->data(), incoming_data_buffer_->StartOfBuffer(), length); + buffer->set_offset(length); + + ResetIncomingDataBuffer(); + } + return true; +} + +bool BluetoothSocketMac::Send(net::DrainableIOBuffer* buffer) { + int bytes_written = buffer->BytesRemaining(); + IOReturn status = [rfcomm_channel_ writeAsync:buffer->data() + length:bytes_written + refcon:nil]; + if (status != kIOReturnSuccess) { + error_message_ = base::StringPrintf( + "Failed to send data. IOReturn code: %u", status); + return false; + } + + buffer->DidConsume(bytes_written); + return true; +} + +std::string BluetoothSocketMac::GetLastErrorMessage() const { + return error_message_; +} + +void BluetoothSocketMac::OnDataReceived( + IOBluetoothRFCOMMChannel* rfcomm_channel, void* data, size_t length) { + DCHECK(rfcomm_channel_ == rfcomm_channel); + CHECK_LT(length, static_cast<size_t>(std::numeric_limits<int>::max())); + int data_size = static_cast<int>(length); + if (incoming_data_buffer_->RemainingCapacity() < data_size) { + int additional_capacity = + std::max(data_size, incoming_data_buffer_->capacity()); + CHECK_LT( + additional_capacity, + std::numeric_limits<int>::max() - incoming_data_buffer_->capacity()); + incoming_data_buffer_->SetCapacity( + incoming_data_buffer_->capacity() + additional_capacity); + } + memcpy(incoming_data_buffer_->data(), data, data_size); + incoming_data_buffer_->set_offset( + incoming_data_buffer_->offset() + data_size); +} + +void BluetoothSocketMac::ResetIncomingDataBuffer() { + incoming_data_buffer_ = new net::GrowableIOBuffer(); + incoming_data_buffer_->SetCapacity(1024); +} + +} // namespace device diff --git a/device/bluetooth/bluetooth_socket_win.h b/device/bluetooth/bluetooth_socket_win.h index 59f7761..41713e7 100644 --- a/device/bluetooth/bluetooth_socket_win.h +++ b/device/bluetooth/bluetooth_socket_win.h @@ -39,7 +39,7 @@ class BluetoothSocketWin : public BluetoothSocket { virtual ~BluetoothSocketWin(); private: - BluetoothSocketWin(SOCKET fd); + explicit BluetoothSocketWin(SOCKET fd); const SOCKET fd_; std::string error_message_; diff --git a/device/bluetooth/bluetooth_task_manager_win.h b/device/bluetooth/bluetooth_task_manager_win.h index 9b8d690..3608667 100644 --- a/device/bluetooth/bluetooth_task_manager_win.h +++ b/device/bluetooth/bluetooth_task_manager_win.h @@ -67,7 +67,7 @@ class BluetoothTaskManagerWin virtual void DevicesDiscovered(const ScopedVector<DeviceState>& devices) {} }; - BluetoothTaskManagerWin( + explicit BluetoothTaskManagerWin( scoped_refptr<base::SequencedTaskRunner> ui_task_runner); void AddObserver(Observer* observer); @@ -154,4 +154,4 @@ class BluetoothTaskManagerWin } // namespace device -#endif // DEVICE_BLUETOOTH_BLUETOOTH_TASK_MANAGER_WIN_H_
\ No newline at end of file +#endif // DEVICE_BLUETOOTH_BLUETOOTH_TASK_MANAGER_WIN_H_ diff --git a/device/device.gyp b/device/device.gyp index 83bc1d2..ff6454d 100644 --- a/device/device.gyp +++ b/device/device.gyp @@ -51,6 +51,8 @@ 'bluetooth/bluetooth_socket.h', 'bluetooth/bluetooth_socket_chromeos.cc', 'bluetooth/bluetooth_socket_chromeos.h', + 'bluetooth/bluetooth_socket_mac.h', + 'bluetooth/bluetooth_socket_mac.mm', 'bluetooth/bluetooth_socket_win.cc', 'bluetooth/bluetooth_socket_win.h', 'bluetooth/bluetooth_task_manager_win.cc', |