Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Unified Diff: device/bluetooth/bluetooth_rfcomm_channel_mac.mm

Issue 328903002: Factor out a BluetoothChannelMac base class and a BluetoothRfcommChannelMac subclass. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: git-add new files Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « device/bluetooth/bluetooth_rfcomm_channel_mac.h ('k') | device/bluetooth/bluetooth_socket_mac.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: device/bluetooth/bluetooth_rfcomm_channel_mac.mm
diff --git a/device/bluetooth/bluetooth_rfcomm_channel_mac.mm b/device/bluetooth/bluetooth_rfcomm_channel_mac.mm
new file mode 100644
index 0000000000000000000000000000000000000000..8697ef6e929b2af7a8c597d217efd640686506ff
--- /dev/null
+++ b/device/bluetooth/bluetooth_rfcomm_channel_mac.mm
@@ -0,0 +1,168 @@
+// Copyright 2014 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_rfcomm_channel_mac.h"
+
+#include "base/logging.h"
+#include "device/bluetooth/bluetooth_device_mac.h"
+#include "device/bluetooth/bluetooth_socket_mac.h"
+
+// A simple delegate class for an open RFCOMM channel that forwards methods to
+// its wrapped |channel_|.
+@interface BluetoothRfcommChannelDelegate
+ : NSObject <IOBluetoothRFCOMMChannelDelegate> {
+ @private
+ device::BluetoothRfcommChannelMac* channel_; // weak
+}
+
+- (id)initWithChannel:(device::BluetoothRfcommChannelMac*)channel;
+
+@end
+
+@implementation BluetoothRfcommChannelDelegate
+
+- (id)initWithChannel:(device::BluetoothRfcommChannelMac*)channel {
+ if ((self = [super init]))
+ channel_ = channel;
+
+ return self;
+}
+
+- (void)rfcommChannelOpenComplete:(IOBluetoothRFCOMMChannel*)rfcommChannel
+ status:(IOReturn)error {
+ channel_->OnChannelOpenComplete(rfcommChannel, error);
+}
+
+- (void)rfcommChannelWriteComplete:(IOBluetoothRFCOMMChannel*)rfcommChannel
+ refcon:(void*)refcon
+ status:(IOReturn)error {
+ channel_->OnChannelWriteComplete(rfcommChannel, refcon, error);
+}
+
+- (void)rfcommChannelData:(IOBluetoothRFCOMMChannel*)rfcommChannel
+ data:(void*)dataPointer
+ length:(size_t)dataLength {
+ channel_->OnChannelDataReceived(rfcommChannel, dataPointer, dataLength);
+}
+
+- (void)rfcommChannelClosed:(IOBluetoothRFCOMMChannel*)rfcommChannel {
+ channel_->OnChannelClosed(rfcommChannel);
+}
+
+@end
+
+namespace device {
+
+BluetoothRfcommChannelMac::BluetoothRfcommChannelMac(
+ BluetoothSocketMac* socket,
+ IOBluetoothRFCOMMChannel* channel)
+ : channel_(channel),
+ delegate_(nil) {
+ SetSocket(socket);
+}
+
+BluetoothRfcommChannelMac::~BluetoothRfcommChannelMac() {
+ [channel_ setDelegate:nil];
+ [channel_ closeChannel];
+}
+
+// static
+scoped_ptr<BluetoothRfcommChannelMac> BluetoothRfcommChannelMac::OpenAsync(
+ BluetoothSocketMac* socket,
+ IOBluetoothDevice* device,
+ uint8 channel_id,
+ IOReturn* status) {
+ DCHECK(socket);
+ scoped_ptr<BluetoothRfcommChannelMac> channel(
+ new BluetoothRfcommChannelMac(socket, nil));
+
+ // Retain the delegate, because IOBluetoothDevice's
+ // |-openRFCOMMChannelAsync:withChannelID:delegate:| assumes that it can take
+ // ownership of the delegate without calling |-retain| on it...
+ DCHECK(channel->delegate_);
+ [channel->delegate_ retain];
+ IOBluetoothRFCOMMChannel* rfcomm_channel;
+ *status = [device openRFCOMMChannelAsync:&rfcomm_channel
+ withChannelID:channel_id
+ delegate:channel->delegate_];
+ if (*status == kIOReturnSuccess) {
+ // Note: No need to retain the |rfcomm_channel| -- the returned channel is
+ // already retained.
+ channel->channel_.reset(rfcomm_channel);
+ } else {
+ channel.reset();
+ }
+
+ return channel.Pass();
+}
+
+void BluetoothRfcommChannelMac::SetSocket(BluetoothSocketMac* socket) {
+ BluetoothChannelMac::SetSocket(socket);
+ if (!this->socket())
+ return;
+
+ // Now that the socket is set, it's safe to associate a delegate, which can
+ // call back to the socket.
+ DCHECK(!delegate_);
+ delegate_.reset(
+ [[BluetoothRfcommChannelDelegate alloc] initWithChannel:this]);
+ [channel_ setDelegate:delegate_];
+}
+
+std::string BluetoothRfcommChannelMac::GetDeviceAddress() {
+ return BluetoothDeviceMac::GetDeviceAddress([channel_ getDevice]);
+}
+
+uint16_t BluetoothRfcommChannelMac::GetOutgoingMTU() {
+ return [channel_ getMTU];
+}
+
+IOReturn BluetoothRfcommChannelMac::WriteAsync(void* data,
+ uint16_t length,
+ void* refcon) {
+ DCHECK_LE(length, GetOutgoingMTU());
+ return [channel_ writeAsync:data length:length refcon:refcon];
+}
+
+void BluetoothRfcommChannelMac::OnChannelOpenComplete(
+ IOBluetoothRFCOMMChannel* channel,
+ IOReturn status) {
+ if (channel_) {
+ DCHECK_EQ(channel_, channel);
+ } else {
+ // The (potentially) asynchronous connection occurred synchronously.
+ // Should only be reachable from OpenAsync().
+ DCHECK_EQ(status, kIOReturnSuccess);
+ }
+
+ socket()->OnChannelOpenComplete(
+ BluetoothDeviceMac::GetDeviceAddress([channel getDevice]), status);
+}
+
+void BluetoothRfcommChannelMac::OnChannelClosed(
+ IOBluetoothRFCOMMChannel* channel) {
+ DCHECK_EQ(channel_, channel);
+ socket()->OnChannelClosed();
+}
+
+void BluetoothRfcommChannelMac::OnChannelDataReceived(
+ IOBluetoothRFCOMMChannel* channel,
+ void* data,
+ size_t length) {
+ DCHECK_EQ(channel_, channel);
+ socket()->OnChannelDataReceived(data, length);
+}
+
+void BluetoothRfcommChannelMac::OnChannelWriteComplete(
+ IOBluetoothRFCOMMChannel* channel,
+ void* refcon,
+ IOReturn status) {
+ // Note: We use "CHECK" below to ensure we never run into unforeseen
+ // occurrences of asynchronous callbacks, which could lead to data
+ // corruption.
+ CHECK_EQ(channel_, channel);
+ socket()->OnChannelWriteComplete(refcon, status);
+}
+
+} // namespace device
« no previous file with comments | « device/bluetooth/bluetooth_rfcomm_channel_mac.h ('k') | device/bluetooth/bluetooth_socket_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698