Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
btrfcommchannel.mm
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "btrfcommchannel_p.h"
5#include "qbluetoothaddress.h"
6#include "btdelegates_p.h"
7#include "btutility_p.h"
8
10
11@implementation DarwinBTRFCOMMChannel
12{
13 QT_PREPEND_NAMESPACE(DarwinBluetooth)::ChannelDelegate *delegate;
14 IOBluetoothDevice *device;
15 IOBluetoothRFCOMMChannel *channel;
17}
18
19- (id)initWithDelegate:(DarwinBluetooth::ChannelDelegate *)aDelegate
20{
21 Q_ASSERT_X(aDelegate, Q_FUNC_INFO, "invalid delegate (null)");
22
23 if (self = [super init]) {
24 delegate = aDelegate;
25 device = nil;
26 channel = nil;
27 connected = false;
28 }
29
30 return self;
31}
32
33- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(DarwinBluetooth::ChannelDelegate) *)aDelegate
34 channel:(IOBluetoothRFCOMMChannel *)aChannel
35{
36 // This type of channel does not require connect, it's created with
37 // already open channel.
38 Q_ASSERT_X(aDelegate, Q_FUNC_INFO, "invalid delegate (null)");
39 Q_ASSERT_X(aChannel, Q_FUNC_INFO, "invalid channel (nil)");
40
41 if (self = [super init]) {
42 delegate = aDelegate;
43 channel = [aChannel retain];
44 [channel setDelegate:self];
45 device = [[channel getDevice] retain];
46 connected = true;
47 }
48
49 return self;
50}
51
52- (void)dealloc
53{
54 if (channel) {
55 [channel setDelegate:nil];
56 [channel closeChannel];
57 [channel release];
58 }
59
60 [device release];
61
62 [super dealloc];
63}
64
65// A single async connection (you can not reuse this object).
66- (IOReturn)connectAsyncToDevice:(const QBluetoothAddress &)address
67 withChannelID:(BluetoothRFCOMMChannelID)channelID
68{
69 if (address.isNull()) {
70 qCCritical(QT_BT_DARWIN) << "invalid peer address";
71 return kIOReturnNoDevice;
72 }
73
74 // Can never be called twice.
75 if (connected || device || channel) {
76 qCCritical(QT_BT_DARWIN) << "connection is already active";
77 return kIOReturnStillOpen;
78 }
79
81
82 const BluetoothDeviceAddress iobtAddress = DarwinBluetooth::iobluetooth_address(address);
83 device = [IOBluetoothDevice deviceWithAddress:&iobtAddress];
84 if (!device) { // TODO: do I always check this BTW??? Apple's docs say nothing about nil.
85 qCCritical(QT_BT_DARWIN) << "failed to create a device";
86 return kIOReturnNoDevice;
87 }
88
89 const IOReturn status = [device openRFCOMMChannelAsync:&channel
90 withChannelID:channelID delegate:self];
91 if (status != kIOReturnSuccess) {
92 qCCritical(QT_BT_DARWIN) << "failed to open L2CAP channel";
93 // device is still autoreleased.
94 device = nil;
95 return status;
96 }
97
98 [channel retain];// What if we're closed already?
99 [device retain];
100
101 return kIOReturnSuccess;
102}
103
104- (void)rfcommChannelData:(IOBluetoothRFCOMMChannel*)rfcommChannel
105 data:(void *)dataPointer length:(size_t)dataLength
106{
107 Q_UNUSED(rfcommChannel);
108
109 Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
110
111 // Not sure if it can ever happen and if
112 // assert is better.
113 if (!dataPointer || !dataLength)
114 return;
115
116 delegate->readChannelData(dataPointer, dataLength);
117}
118
119- (void)rfcommChannelOpenComplete:(IOBluetoothRFCOMMChannel*)rfcommChannel
120 status:(IOReturn)error
121{
122 Q_UNUSED(rfcommChannel);
123
124 Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
125
126 if (error != kIOReturnSuccess) {
127 delegate->setChannelError(error);
128 } else {
129 connected = true;
130 delegate->channelOpenComplete();
131 }
132}
133
134- (void)rfcommChannelClosed:(IOBluetoothRFCOMMChannel*)rfcommChannel
135{
136 Q_UNUSED(rfcommChannel);
137
138 Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
139 delegate->channelClosed();
140 connected = false;
141}
142
143- (void)rfcommChannelControlSignalsChanged:(IOBluetoothRFCOMMChannel*)rfcommChannel
144{
145 Q_UNUSED(rfcommChannel);
146}
147
148- (void)rfcommChannelFlowControlChanged:(IOBluetoothRFCOMMChannel*)rfcommChannel
149{
150 Q_UNUSED(rfcommChannel);
151}
152
153- (void)rfcommChannelWriteComplete:(IOBluetoothRFCOMMChannel*)rfcommChannel
154 refcon:(void*)refcon status:(IOReturn)error
155{
156 Q_UNUSED(rfcommChannel);
157 Q_UNUSED(refcon);
158
159 Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
160
161 if (error != kIOReturnSuccess)
162 delegate->setChannelError(error);
163 else
164 delegate->writeComplete();
165}
166
167- (void)rfcommChannelQueueSpaceAvailable:(IOBluetoothRFCOMMChannel*)rfcommChannel
168{
169 Q_UNUSED(rfcommChannel);
170}
171
172- (BluetoothRFCOMMChannelID)getChannelID
173{
174 if (channel)
175 return [channel getChannelID];
176
177 return 0;
178}
179
180- (BluetoothDeviceAddress)peerAddress
181{
182 const BluetoothDeviceAddress *const addr = device ? [device getAddress]
183 : nullptr;
184 if (addr)
185 return *addr;
186
187 return BluetoothDeviceAddress();
188}
189
190- (NSString *)peerName
191{
192 if (device)
193 return device.name;
194
195 return nil;
196}
197
198- (BluetoothRFCOMMMTU)getMTU
199{
200 if (channel)
201 return [channel getMTU];
202
203 return 0;
204}
205
206- (IOReturn) writeSync:(void*)data length:(UInt16)length
207{
208 Q_ASSERT_X(data, Q_FUNC_INFO, "invalid data (null)");
209 Q_ASSERT_X(length, Q_FUNC_INFO, "invalid data size");
210 Q_ASSERT_X(connected && channel, Q_FUNC_INFO, "invalid RFCOMM channel");
211
212 return [channel writeSync:data length:length];
213}
214
215- (IOReturn) writeAsync:(void*)data length:(UInt16)length
216{
217 Q_ASSERT_X(data, Q_FUNC_INFO, "invalid data (null)");
218 Q_ASSERT_X(length, Q_FUNC_INFO, "invalid data size");
219 Q_ASSERT_X(connected && channel, Q_FUNC_INFO, "invalid RFCOMM channel");
220
221 return [channel writeAsync:data length:length refcon:nullptr];
222}
223
224
225@end
IOBluetoothL2CAPChannel * channel
bool connected
IOBluetoothDevice * device
IOBluetoothRFCOMMChannel * channel
bool connected
IOBluetoothDevice * device
#define QT_BT_MAC_AUTORELEASEPOOL
Definition btutility_p.h:78
\inmodule QtBluetooth
BluetoothDeviceAddress iobluetooth_address(const QBluetoothAddress &qAddress)
Definition btutility.mm:65
QString self
Definition language.cpp:58
#define Q_FUNC_INFO
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
DBusConnection const char DBusError * error
#define qCCritical(category,...)
GLenum GLuint GLenum GLsizei length
GLenum GLuint id
[7]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum const void * addr
GLuint GLuint64EXT address
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
#define Q_UNUSED(x)