Warning: That file was not part of the compilation database. It may have many parsing errors.
1 | /**************************************************************************** |
---|---|
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtBluetooth module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #include "qbluetoothservicediscoveryagent.h" |
41 | // The order is important (the first header contains |
42 | // the base class for a private socket) - workaround for |
43 | // dependencies problem. |
44 | #include "qbluetoothsocketbase_p.h" |
45 | #include "qbluetoothsocket_osx_p.h" |
46 | |
47 | #include "osx/osxbtrfcommchannel_p.h" |
48 | #include "osx/osxbtl2capchannel_p.h" |
49 | #include "qbluetoothlocaldevice.h" |
50 | #include "qbluetoothdeviceinfo.h" |
51 | #include "osx/osxbtutility_p.h" |
52 | #include "osx/uistrings_p.h" |
53 | #include "qbluetoothsocket.h" |
54 | |
55 | #include <QtCore/qloggingcategory.h> |
56 | #include <QtCore/qmetaobject.h> |
57 | |
58 | #include <algorithm> |
59 | #include <limits> |
60 | |
61 | QT_BEGIN_NAMESPACE |
62 | |
63 | namespace { |
64 | |
65 | using DarwinBluetooth::RetainPolicy; |
66 | using ObjCL2CAPChannel = QT_MANGLE_NAMESPACE(OSXBTL2CAPChannel); |
67 | using ObjCRFCOMMChannel = QT_MANGLE_NAMESPACE(OSXBTRFCOMMChannel); |
68 | |
69 | } // unnamed namespace |
70 | |
71 | QBluetoothSocketPrivate::QBluetoothSocketPrivate() |
72 | : writeChunk(std::numeric_limits<UInt16>::max()) |
73 | { |
74 | q_ptr = nullptr; |
75 | } |
76 | |
77 | QBluetoothSocketPrivate::~QBluetoothSocketPrivate() |
78 | { |
79 | } |
80 | |
81 | bool QBluetoothSocketPrivate::ensureNativeSocket(QBluetoothServiceInfo::Protocol type) |
82 | { |
83 | // For now - very simplistic, we don't call it in this file, public class |
84 | // only calls it in a ctor, setting the protocol RFCOMM (in case of Android) |
85 | // or, indeed, doing, socket-related initialization in BlueZ backend. |
86 | Q_ASSERT(socketType == QBluetoothServiceInfo::UnknownProtocol); |
87 | socketType = type; |
88 | return type != QBluetoothServiceInfo::UnknownProtocol; |
89 | } |
90 | |
91 | QString QBluetoothSocketPrivate::localName() const |
92 | { |
93 | const QBluetoothLocalDevice device; |
94 | return device.name(); |
95 | } |
96 | |
97 | QBluetoothAddress QBluetoothSocketPrivate::localAddress() const |
98 | { |
99 | const QBluetoothLocalDevice device; |
100 | return device.address(); |
101 | } |
102 | |
103 | quint16 QBluetoothSocketPrivate::localPort() const |
104 | { |
105 | return 0; |
106 | } |
107 | |
108 | QString QBluetoothSocketPrivate::peerName() const |
109 | { |
110 | QT_BT_MAC_AUTORELEASEPOOL; |
111 | |
112 | NSString *nsName = nil; |
113 | if (socketType == QBluetoothServiceInfo::RfcommProtocol) { |
114 | if (rfcommChannel) |
115 | nsName = [rfcommChannel.getAs<ObjCRFCOMMChannel>() peerName]; |
116 | } else if (socketType == QBluetoothServiceInfo::L2capProtocol) { |
117 | if (l2capChannel) |
118 | nsName = [l2capChannel.getAs<ObjCL2CAPChannel>() peerName]; |
119 | } |
120 | |
121 | if (nsName) |
122 | return QString::fromNSString(nsName); |
123 | |
124 | return QString(); |
125 | } |
126 | |
127 | QBluetoothAddress QBluetoothSocketPrivate::peerAddress() const |
128 | { |
129 | BluetoothDeviceAddress addr = {}; |
130 | if (socketType == QBluetoothServiceInfo::RfcommProtocol) { |
131 | if (rfcommChannel) |
132 | addr = [rfcommChannel.getAs<ObjCRFCOMMChannel>() peerAddress]; |
133 | } else if (socketType == QBluetoothServiceInfo::L2capProtocol) { |
134 | if (l2capChannel) |
135 | addr = [l2capChannel.getAs<ObjCL2CAPChannel>() peerAddress]; |
136 | } |
137 | |
138 | return OSXBluetooth::qt_address(&addr); |
139 | } |
140 | |
141 | quint16 QBluetoothSocketPrivate::peerPort() const |
142 | { |
143 | if (socketType == QBluetoothServiceInfo::RfcommProtocol) { |
144 | if (rfcommChannel) |
145 | return [rfcommChannel.getAs<ObjCRFCOMMChannel>() getChannelID]; |
146 | } else if (socketType == QBluetoothServiceInfo::L2capProtocol) { |
147 | if (l2capChannel) |
148 | return [l2capChannel.getAs<ObjCL2CAPChannel>() getPSM]; |
149 | } |
150 | |
151 | return 0; |
152 | } |
153 | |
154 | void QBluetoothSocketPrivate::abort() |
155 | { |
156 | // Can never be called while we're in connectToService: |
157 | Q_ASSERT_X(!isConnecting, Q_FUNC_INFO, "internal inconsistency - " |
158 | "still in connectToService()"); |
159 | |
160 | if (socketType == QBluetoothServiceInfo::RfcommProtocol) |
161 | rfcommChannel.reset(); |
162 | else if (socketType == QBluetoothServiceInfo::L2capProtocol) |
163 | l2capChannel.reset(); |
164 | |
165 | Q_ASSERT(q_ptr); |
166 | |
167 | q_ptr->setSocketState(QBluetoothSocket::UnconnectedState); |
168 | emit q_ptr->readChannelFinished(); |
169 | emit q_ptr->disconnected(); |
170 | |
171 | } |
172 | |
173 | void QBluetoothSocketPrivate::close() |
174 | { |
175 | // Can never be called while we're in connectToService: |
176 | Q_ASSERT_X(!isConnecting, Q_FUNC_INFO, "internal inconsistency - " |
177 | "still in connectToService()"); |
178 | |
179 | if (!txBuffer.size()) |
180 | abort(); |
181 | } |
182 | |
183 | |
184 | qint64 QBluetoothSocketPrivate::writeData(const char *data, qint64 maxSize) |
185 | { |
186 | Q_ASSERT_X(data, Q_FUNC_INFO, "invalid data (null)"); |
187 | Q_ASSERT_X(maxSize > 0, Q_FUNC_INFO, "invalid data size"); |
188 | |
189 | if (state != QBluetoothSocket::ConnectedState) { |
190 | errorString = QCoreApplication::translate(SOCKET, SOC_NOWRITE); |
191 | q_ptr->setSocketError(QBluetoothSocket::OperationError); |
192 | return -1; |
193 | } |
194 | |
195 | // We do not have a real socket API under the hood, |
196 | // IOBluetoothL2CAPChannel is buffered (writeAsync). |
197 | |
198 | if (!txBuffer.size()) |
199 | QMetaObject::invokeMethod(this, "_q_writeNotify", Qt::QueuedConnection); |
200 | |
201 | char *dst = txBuffer.reserve(int(maxSize)); |
202 | std::copy(data, data + maxSize, dst); |
203 | |
204 | return maxSize; |
205 | } |
206 | |
207 | qint64 QBluetoothSocketPrivate::readData(char *data, qint64 maxSize) |
208 | { |
209 | if (!data) |
210 | return 0; |
211 | |
212 | if (state != QBluetoothSocket::ConnectedState) { |
213 | errorString = QCoreApplication::translate(SOCKET, SOC_NOREAD); |
214 | q_ptr->setSocketError(QBluetoothSocket::OperationError); |
215 | return -1; |
216 | } |
217 | |
218 | if (!buffer.isEmpty()) |
219 | return buffer.read(data, int(maxSize)); |
220 | |
221 | return 0; |
222 | } |
223 | |
224 | qint64 QBluetoothSocketPrivate::bytesAvailable() const |
225 | { |
226 | return buffer.size(); |
227 | } |
228 | |
229 | bool QBluetoothSocketPrivate::canReadLine() const |
230 | { |
231 | return buffer.canReadLine(); |
232 | } |
233 | |
234 | qint64 QBluetoothSocketPrivate::bytesToWrite() const |
235 | { |
236 | return txBuffer.size(); |
237 | } |
238 | |
239 | bool QBluetoothSocketPrivate::setSocketDescriptor(int socketDescriptor, QBluetoothServiceInfo::Protocol socketType, |
240 | QBluetoothSocket::SocketState socketState, QIODevice::OpenMode openMode) |
241 | { |
242 | Q_UNUSED(socketDescriptor) |
243 | Q_UNUSED(socketType) |
244 | Q_UNUSED(socketState) |
245 | Q_UNUSED(openMode) |
246 | |
247 | qCWarning(QT_BT_OSX) << "setting a socket descriptor is not supported by IOBluetooth"; |
248 | // Noop on macOS. |
249 | return true; |
250 | } |
251 | |
252 | void QBluetoothSocketPrivate::connectToServiceHelper(const QBluetoothAddress &address, quint16 port, |
253 | QIODevice::OpenMode openMode) |
254 | { |
255 | Q_UNUSED(address) |
256 | Q_UNUSED(port) |
257 | Q_UNUSED(openMode) |
258 | } |
259 | |
260 | void QBluetoothSocketPrivate::connectToService(const QBluetoothServiceInfo &service, QIODevice::OpenMode openMode) |
261 | { |
262 | Q_ASSERT(q_ptr); |
263 | |
264 | OSXBluetooth::qt_test_iobluetooth_runloop(); |
265 | |
266 | if (state!= QBluetoothSocket::UnconnectedState && state != QBluetoothSocket::ServiceLookupState) { |
267 | qCWarning(QT_BT_OSX) << "called on a busy socket"; |
268 | errorString = QCoreApplication::translate(SOCKET, SOC_CONNECT_IN_PROGRESS); |
269 | q_ptr->setSocketError(QBluetoothSocket::OperationError); |
270 | return; |
271 | } |
272 | |
273 | // Report this problem early, potentially avoid device discovery: |
274 | if (service.socketProtocol() == QBluetoothServiceInfo::UnknownProtocol) { |
275 | qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "cannot connect with 'UnknownProtocol' type"; |
276 | errorString = QCoreApplication::translate(SOCKET, SOC_NETWORK_ERROR); |
277 | q_ptr->setSocketError(QBluetoothSocket::UnsupportedProtocolError); |
278 | return; |
279 | } |
280 | |
281 | socketType = service.socketProtocol(); |
282 | |
283 | if (service.protocolServiceMultiplexer() > 0) { |
284 | connectToService(service.device().address(), |
285 | quint16(service.protocolServiceMultiplexer()), |
286 | openMode); |
287 | } else if (service.serverChannel() > 0) { |
288 | connectToService(service.device().address(), |
289 | quint16(service.serverChannel()), |
290 | openMode); |
291 | } else { |
292 | // Try service discovery. |
293 | if (service.serviceUuid().isNull()) { |
294 | qCWarning(QT_BT_OSX) << "No port, no PSM, and no " |
295 | "UUID provided, unable to connect"; |
296 | return; |
297 | } |
298 | |
299 | q_ptr->doDeviceDiscovery(service, openMode); |
300 | } |
301 | } |
302 | |
303 | void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address, const QBluetoothUuid &uuid, |
304 | QIODevice::OpenMode openMode) |
305 | { |
306 | Q_ASSERT(q_ptr); |
307 | |
308 | OSXBluetooth::qt_test_iobluetooth_runloop(); |
309 | |
310 | // Report this problem early, avoid device discovery: |
311 | if (socketType == QBluetoothServiceInfo::UnknownProtocol) { |
312 | qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "cannot connect with 'UnknownProtocol' type"; |
313 | errorString = QCoreApplication::translate(SOCKET, SOC_NETWORK_ERROR); |
314 | q_ptr->setSocketError(QBluetoothSocket::UnsupportedProtocolError); |
315 | return; |
316 | } |
317 | |
318 | if (state != QBluetoothSocket::UnconnectedState) { |
319 | qCWarning(QT_BT_OSX) << "called on a busy socket"; |
320 | errorString = QCoreApplication::translate(SOCKET, SOC_CONNECT_IN_PROGRESS); |
321 | q_ptr->setSocketError(QBluetoothSocket::OperationError); |
322 | return; |
323 | } |
324 | |
325 | QBluetoothDeviceInfo device(address, QString(), QBluetoothDeviceInfo::MiscellaneousDevice); |
326 | QBluetoothServiceInfo service; |
327 | service.setDevice(device); |
328 | service.setServiceUuid(uuid); |
329 | q_ptr->doDeviceDiscovery(service, openMode); |
330 | } |
331 | |
332 | void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address, quint16 port, |
333 | QIODevice::OpenMode mode) |
334 | { |
335 | Q_ASSERT(q_ptr); |
336 | |
337 | OSXBluetooth::qt_test_iobluetooth_runloop(); |
338 | |
339 | if (socketType == QBluetoothServiceInfo::UnknownProtocol) { |
340 | qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "cannot connect with 'UnknownProtocol' type"; |
341 | errorString = QCoreApplication::translate(SOCKET, SOC_NETWORK_ERROR); |
342 | q_ptr->setSocketError(QBluetoothSocket::UnsupportedProtocolError); |
343 | return; |
344 | } |
345 | |
346 | Q_ASSERT_X(state == QBluetoothSocket::ServiceLookupState || state == QBluetoothSocket::UnconnectedState, |
347 | Q_FUNC_INFO, "invalid state"); |
348 | |
349 | q_ptr->setOpenMode(mode); |
350 | |
351 | socketError = QBluetoothSocket::NoSocketError; |
352 | errorString.clear(); |
353 | buffer.clear(); |
354 | txBuffer.clear(); |
355 | |
356 | IOReturn status = kIOReturnError; |
357 | // Setting socket state on q_ptr will emit a signal, |
358 | // we'd like to avoid any signal until this function completes. |
359 | const QBluetoothSocket::SocketState oldState = state; |
360 | // To prevent other connectToService calls (from QBluetoothSocket): |
361 | // and also avoid signals in delegate callbacks. |
362 | state = QBluetoothSocket::ConnectingState; |
363 | // We're still inside this function: |
364 | isConnecting = true; |
365 | |
366 | // We'll later (or now) have to set an open mode on QBluetoothSocket. |
367 | openMode = mode; |
368 | |
369 | if (socketType == QBluetoothServiceInfo::RfcommProtocol) { |
370 | rfcommChannel.reset([[ObjCRFCOMMChannel alloc] initWithDelegate:this], RetainPolicy::noInitialRetain); |
371 | if (rfcommChannel) |
372 | status = [rfcommChannel.getAs<ObjCRFCOMMChannel>() connectAsyncToDevice:address withChannelID:port]; |
373 | else |
374 | status = kIOReturnNoMemory; |
375 | } else if (socketType == QBluetoothServiceInfo::L2capProtocol) { |
376 | l2capChannel.reset([[ObjCL2CAPChannel alloc] initWithDelegate:this], RetainPolicy::noInitialRetain); |
377 | if (l2capChannel) |
378 | status = [l2capChannel.getAs<ObjCL2CAPChannel>() connectAsyncToDevice:address withPSM:port]; |
379 | else |
380 | status = kIOReturnNoMemory; |
381 | } |
382 | |
383 | // We're probably still connecting, but at least are leaving this function: |
384 | isConnecting = false; |
385 | |
386 | // QBluetoothSocket will change the state and also emit |
387 | // a signal later if required. |
388 | if (status == kIOReturnSuccess && socketError == QBluetoothSocket::NoSocketError) { |
389 | if (state == QBluetoothSocket::ConnectedState) { |
390 | // Callback 'channelOpenComplete' fired before |
391 | // connectToService finished: |
392 | state = oldState; |
393 | // Connected, setOpenMode on a QBluetoothSocket. |
394 | q_ptr->setOpenMode(openMode); |
395 | q_ptr->setSocketState(QBluetoothSocket::ConnectedState); |
396 | emit q_ptr->connected(); |
397 | if (buffer.size()) // We also have some data already ... |
398 | emit q_ptr->readyRead(); |
399 | } else if (state == QBluetoothSocket::UnconnectedState) { |
400 | // Even if we have some data, we can not read it if |
401 | // state != ConnectedState. |
402 | buffer.clear(); |
403 | state = oldState; |
404 | q_ptr->setSocketError(QBluetoothSocket::UnknownSocketError); |
405 | } else { |
406 | // No error and we're connecting ... |
407 | state = oldState; |
408 | q_ptr->setSocketState(QBluetoothSocket::ConnectingState); |
409 | } |
410 | } else { |
411 | state = oldState; |
412 | if (status != kIOReturnSuccess) |
413 | errorString = OSXBluetooth::qt_error_string(status); |
414 | q_ptr->setSocketError(QBluetoothSocket::UnknownSocketError); |
415 | } |
416 | } |
417 | |
418 | void QBluetoothSocketPrivate::_q_writeNotify() |
419 | { |
420 | Q_ASSERT_X(socketType == QBluetoothServiceInfo::L2capProtocol |
421 | || socketType == QBluetoothServiceInfo::RfcommProtocol, |
422 | Q_FUNC_INFO, "invalid socket type"); |
423 | Q_ASSERT_X(l2capChannel || rfcommChannel, Q_FUNC_INFO, |
424 | "invalid socket (no open channel)"); |
425 | Q_ASSERT_X(q_ptr, Q_FUNC_INFO, "invalid q_ptr (null)"); |
426 | |
427 | if (txBuffer.size()) { |
428 | const bool isL2CAP = socketType == QBluetoothServiceInfo::L2capProtocol; |
429 | writeChunk.resize(isL2CAP ? std::numeric_limits<UInt16>::max() : |
430 | [rfcommChannel.getAs<ObjCRFCOMMChannel>() getMTU]); |
431 | |
432 | const int size = txBuffer.read(writeChunk.data(), writeChunk.size()); |
433 | IOReturn status = kIOReturnError; |
434 | if (!isL2CAP) |
435 | status = [rfcommChannel.getAs<ObjCRFCOMMChannel>() writeAsync:writeChunk.data() length:UInt16(size)]; |
436 | else |
437 | status = [l2capChannel.getAs<ObjCL2CAPChannel>() writeAsync:writeChunk.data() length:UInt16(size)]; |
438 | |
439 | if (status != kIOReturnSuccess) { |
440 | errorString = QCoreApplication::translate(SOCKET, SOC_NETWORK_ERROR); |
441 | q_ptr->setSocketError(QBluetoothSocket::NetworkError); |
442 | return; |
443 | } else { |
444 | emit q_ptr->bytesWritten(size); |
445 | } |
446 | } |
447 | |
448 | if (!txBuffer.size() && state == QBluetoothSocket::ClosingState) |
449 | close(); |
450 | } |
451 | |
452 | bool QBluetoothSocketPrivate::setRFCOMChannel(void *generic) |
453 | { |
454 | // A special case "constructor": on OS X we do not have a real listening socket, |
455 | // instead a bluetooth server "listens" for channel open notifications and |
456 | // creates (if asked by a user later) a "socket" object |
457 | // for this connection. This function initializes |
458 | // a "socket" from such an external channel (reported by a notification). |
459 | auto channel = static_cast<IOBluetoothRFCOMMChannel *>(generic); |
460 | // It must be a newborn socket! |
461 | Q_ASSERT_X(socketError == QBluetoothSocket::NoSocketError |
462 | && state == QBluetoothSocket::UnconnectedState && !rfcommChannel && !l2capChannel, |
463 | Q_FUNC_INFO, "unexpected socket state"); |
464 | |
465 | openMode = QIODevice::ReadWrite; |
466 | rfcommChannel.reset([[ObjCRFCOMMChannel alloc] initWithDelegate:this channel:channel], |
467 | RetainPolicy::noInitialRetain); |
468 | if (rfcommChannel) {// We do not handle errors, up to an external user. |
469 | q_ptr->setOpenMode(QIODevice::ReadWrite); |
470 | state = QBluetoothSocket::ConnectedState; |
471 | socketType = QBluetoothServiceInfo::RfcommProtocol; |
472 | } |
473 | |
474 | return rfcommChannel; |
475 | } |
476 | |
477 | bool QBluetoothSocketPrivate::setL2CAPChannel(void *generic) |
478 | { |
479 | // A special case "constructor": on OS X we do not have a real listening socket, |
480 | // instead a bluetooth server "listens" for channel open notifications and |
481 | // creates (if asked by a user later) a "socket" object |
482 | // for this connection. This function initializes |
483 | // a "socket" from such an external channel (reported by a notification). |
484 | auto channel = static_cast<IOBluetoothL2CAPChannel *>(generic); |
485 | |
486 | // It must be a newborn socket! |
487 | Q_ASSERT_X(socketError == QBluetoothSocket::NoSocketError |
488 | && state == QBluetoothSocket::UnconnectedState && !l2capChannel && !rfcommChannel, |
489 | Q_FUNC_INFO, "unexpected socket state"); |
490 | |
491 | openMode = QIODevice::ReadWrite; |
492 | l2capChannel.reset([[ObjCL2CAPChannel alloc] initWithDelegate:this channel:channel], RetainPolicy::noInitialRetain); |
493 | if (l2capChannel) {// We do not handle errors, up to an external user. |
494 | q_ptr->setOpenMode(QIODevice::ReadWrite); |
495 | state = QBluetoothSocket::ConnectedState; |
496 | socketType = QBluetoothServiceInfo::L2capProtocol; |
497 | } |
498 | |
499 | return l2capChannel; |
500 | } |
501 | |
502 | void QBluetoothSocketPrivate::setChannelError(IOReturn errorCode) |
503 | { |
504 | Q_UNUSED(errorCode) |
505 | |
506 | Q_ASSERT_X(q_ptr, Q_FUNC_INFO, "invalid q_ptr (null)"); |
507 | |
508 | if (isConnecting) { |
509 | // The delegate's method was called while we are still in |
510 | // connectToService ... will emit a moment later. |
511 | socketError = QBluetoothSocket::UnknownSocketError; |
512 | } else { |
513 | q_ptr->setSocketError(QBluetoothSocket::UnknownSocketError); |
514 | } |
515 | } |
516 | |
517 | void QBluetoothSocketPrivate::channelOpenComplete() |
518 | { |
519 | Q_ASSERT_X(q_ptr, Q_FUNC_INFO, "invalid q_ptr (null)"); |
520 | |
521 | if (!isConnecting) { |
522 | q_ptr->setSocketState(QBluetoothSocket::ConnectedState); |
523 | q_ptr->setOpenMode(openMode); |
524 | emit q_ptr->connected(); |
525 | } else { |
526 | state = QBluetoothSocket::ConnectedState; |
527 | // We are still in connectToService, it'll care |
528 | // about signals! |
529 | } |
530 | } |
531 | |
532 | void QBluetoothSocketPrivate::channelClosed() |
533 | { |
534 | Q_ASSERT_X(q_ptr, Q_FUNC_INFO, "invalid q_ptr (null)"); |
535 | |
536 | // Channel was closed by IOBluetooth and we can not write any data |
537 | // (thus close/abort probably will not work). |
538 | |
539 | if (!isConnecting) { |
540 | q_ptr->setSocketState(QBluetoothSocket::UnconnectedState); |
541 | q_ptr->setOpenMode(QIODevice::NotOpen); |
542 | emit q_ptr->readChannelFinished(); |
543 | emit q_ptr->disconnected(); |
544 | } else { |
545 | state = QBluetoothSocket::UnconnectedState; |
546 | // We are still in connectToService and do not want |
547 | // to emit any signals yet. |
548 | } |
549 | } |
550 | |
551 | void QBluetoothSocketPrivate::readChannelData(void *data, std::size_t size) |
552 | { |
553 | Q_ASSERT_X(data, Q_FUNC_INFO, "invalid data (null)"); |
554 | Q_ASSERT_X(size, Q_FUNC_INFO, "invalid data size (0)"); |
555 | Q_ASSERT_X(q_ptr, Q_FUNC_INFO, "invalid q_ptr (null)"); |
556 | |
557 | const char *src = static_cast<char *>(data); |
558 | char *dst = buffer.reserve(int(size)); |
559 | std::copy(src, src + size, dst); |
560 | |
561 | if (!isConnecting) { |
562 | // If we're still in connectToService, do not emit. |
563 | emit q_ptr->readyRead(); |
564 | } // else connectToService must check and emit readyRead! |
565 | } |
566 | |
567 | void QBluetoothSocketPrivate::writeComplete() |
568 | { |
569 | _q_writeNotify(); |
570 | } |
571 | |
572 | QT_END_NAMESPACE |
573 |
Warning: That file was not part of the compilation database. It may have many parsing errors.