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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "device/bluetooth/bluetooth_rfcomm_channel_mac.h"
6
7 #include "base/logging.h"
8 #include "device/bluetooth/bluetooth_device_mac.h"
9 #include "device/bluetooth/bluetooth_socket_mac.h"
10
11 // A simple delegate class for an open RFCOMM channel that forwards methods to
12 // its wrapped |channel_|.
13 @interface BluetoothRfcommChannelDelegate
14 : NSObject <IOBluetoothRFCOMMChannelDelegate> {
15 @private
16 device::BluetoothRfcommChannelMac* channel_; // weak
17 }
18
19 - (id)initWithChannel:(device::BluetoothRfcommChannelMac*)channel;
20
21 @end
22
23 @implementation BluetoothRfcommChannelDelegate
24
25 - (id)initWithChannel:(device::BluetoothRfcommChannelMac*)channel {
26 if ((self = [super init]))
27 channel_ = channel;
28
29 return self;
30 }
31
32 - (void)rfcommChannelOpenComplete:(IOBluetoothRFCOMMChannel*)rfcommChannel
33 status:(IOReturn)error {
34 channel_->OnChannelOpenComplete(rfcommChannel, error);
35 }
36
37 - (void)rfcommChannelWriteComplete:(IOBluetoothRFCOMMChannel*)rfcommChannel
38 refcon:(void*)refcon
39 status:(IOReturn)error {
40 channel_->OnChannelWriteComplete(rfcommChannel, refcon, error);
41 }
42
43 - (void)rfcommChannelData:(IOBluetoothRFCOMMChannel*)rfcommChannel
44 data:(void*)dataPointer
45 length:(size_t)dataLength {
46 channel_->OnChannelDataReceived(rfcommChannel, dataPointer, dataLength);
47 }
48
49 - (void)rfcommChannelClosed:(IOBluetoothRFCOMMChannel*)rfcommChannel {
50 channel_->OnChannelClosed(rfcommChannel);
51 }
52
53 @end
54
55 namespace device {
56
57 BluetoothRfcommChannelMac::BluetoothRfcommChannelMac(
58 BluetoothSocketMac* socket,
59 IOBluetoothRFCOMMChannel* channel)
60 : channel_(channel),
61 delegate_(nil) {
62 SetSocket(socket);
63 }
64
65 BluetoothRfcommChannelMac::~BluetoothRfcommChannelMac() {
66 [channel_ setDelegate:nil];
67 [channel_ closeChannel];
68 }
69
70 // static
71 scoped_ptr<BluetoothRfcommChannelMac> BluetoothRfcommChannelMac::OpenAsync(
72 BluetoothSocketMac* socket,
73 IOBluetoothDevice* device,
74 uint8 channel_id,
75 IOReturn* status) {
76 DCHECK(socket);
77 scoped_ptr<BluetoothRfcommChannelMac> channel(
78 new BluetoothRfcommChannelMac(socket, nil));
79
80 // Retain the delegate, because IOBluetoothDevice's
81 // |-openRFCOMMChannelAsync:withChannelID:delegate:| assumes that it can take
82 // ownership of the delegate without calling |-retain| on it...
83 DCHECK(channel->delegate_);
84 [channel->delegate_ retain];
85 IOBluetoothRFCOMMChannel* rfcomm_channel;
86 *status = [device openRFCOMMChannelAsync:&rfcomm_channel
87 withChannelID:channel_id
88 delegate:channel->delegate_];
89 if (*status == kIOReturnSuccess) {
90 // Note: No need to retain the |rfcomm_channel| -- the returned channel is
91 // already retained.
92 channel->channel_.reset(rfcomm_channel);
93 } else {
94 channel.reset();
95 }
96
97 return channel.Pass();
98 }
99
100 void BluetoothRfcommChannelMac::SetSocket(BluetoothSocketMac* socket) {
101 BluetoothChannelMac::SetSocket(socket);
102 if (!this->socket())
103 return;
104
105 // Now that the socket is set, it's safe to associate a delegate, which can
106 // call back to the socket.
107 DCHECK(!delegate_);
108 delegate_.reset(
109 [[BluetoothRfcommChannelDelegate alloc] initWithChannel:this]);
110 [channel_ setDelegate:delegate_];
111 }
112
113 std::string BluetoothRfcommChannelMac::GetDeviceAddress() {
114 return BluetoothDeviceMac::GetDeviceAddress([channel_ getDevice]);
115 }
116
117 uint16_t BluetoothRfcommChannelMac::GetOutgoingMTU() {
118 return [channel_ getMTU];
119 }
120
121 IOReturn BluetoothRfcommChannelMac::WriteAsync(void* data,
122 uint16_t length,
123 void* refcon) {
124 DCHECK_LE(length, GetOutgoingMTU());
125 return [channel_ writeAsync:data length:length refcon:refcon];
126 }
127
128 void BluetoothRfcommChannelMac::OnChannelOpenComplete(
129 IOBluetoothRFCOMMChannel* channel,
130 IOReturn status) {
131 if (channel_) {
132 DCHECK_EQ(channel_, channel);
133 } else {
134 // The (potentially) asynchronous connection occurred synchronously.
135 // Should only be reachable from OpenAsync().
136 DCHECK_EQ(status, kIOReturnSuccess);
137 }
138
139 socket()->OnChannelOpenComplete(
140 BluetoothDeviceMac::GetDeviceAddress([channel getDevice]), status);
141 }
142
143 void BluetoothRfcommChannelMac::OnChannelClosed(
144 IOBluetoothRFCOMMChannel* channel) {
145 DCHECK_EQ(channel_, channel);
146 socket()->OnChannelClosed();
147 }
148
149 void BluetoothRfcommChannelMac::OnChannelDataReceived(
150 IOBluetoothRFCOMMChannel* channel,
151 void* data,
152 size_t length) {
153 DCHECK_EQ(channel_, channel);
154 socket()->OnChannelDataReceived(data, length);
155 }
156
157 void BluetoothRfcommChannelMac::OnChannelWriteComplete(
158 IOBluetoothRFCOMMChannel* channel,
159 void* refcon,
160 IOReturn status) {
161 // Note: We use "CHECK" below to ensure we never run into unforeseen
162 // occurrences of asynchronous callbacks, which could lead to data
163 // corruption.
164 CHECK_EQ(channel_, channel);
165 socket()->OnChannelWriteComplete(refcon, status);
166 }
167
168 } // namespace device
OLDNEW
« 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