Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qbluetoothsocket.cpp
Go to the documentation of this file.
1// Copyright (C) 2018 The Qt Company Ltd.
2// Copyright (C) 2016 BlackBerry Limited. All rights reserved.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
6#if QT_CONFIG(bluez)
7#include "qbluetoothsocket_bluez_p.h"
8#include "qbluetoothsocket_bluezdbus_p.h"
9#include "bluez/bluez5_helper_p.h"
10#elif defined(QT_ANDROID_BLUETOOTH)
11#include "qbluetoothsocket_android_p.h"
12#elif defined(QT_WINRT_BLUETOOTH)
13#include "qbluetoothsocket_winrt_p.h"
14#elif defined(QT_OSX_BLUETOOTH)
15#include "qbluetoothsocket_macos_p.h"
16#else
18#endif
19
21
22#include <QtCore/QLoggingCategory>
23#include <QSocketNotifier>
24
26
27Q_DECLARE_LOGGING_CATEGORY(QT_BT)
28
29/*!
30 \class QBluetoothSocket
31 \inmodule QtBluetooth
32 \brief The QBluetoothSocket class enables connection to a Bluetooth device
33 running a bluetooth server.
34
35 \since 5.2
36
37 QBluetoothSocket supports two socket types, \l {QBluetoothServiceInfo::L2capProtocol}{L2CAP} and
38 \l {QBluetoothServiceInfo::RfcommProtocol}{RFCOMM}.
39
40 \l {QBluetoothServiceInfo::L2capProtocol}{L2CAP} is a low level datagram-oriented Bluetooth socket.
41 Android does not support \l {QBluetoothServiceInfo::L2capProtocol}{L2CAP} for socket
42 connections.
43
44 \l {QBluetoothServiceInfo::RfcommProtocol}{RFCOMM} is a reliable, stream-oriented socket. RFCOMM
45 sockets emulate an RS-232 serial port.
46
47 To create a connection to a Bluetooth service, create a socket of the appropriate type and call
48 connectToService() passing the Bluetooth address and port number. QBluetoothSocket will emit
49 the connected() signal when the connection is established.
50
51 If the \l {QBluetoothServiceInfo::Protocol}{Protocol} is not supported on a platform, calling
52 \l connectToService() will emit a \l {QBluetoothSocket::SocketError::UnsupportedProtocolError}{UnsupportedProtocolError} error.
53
54 \note QBluetoothSocket does not support synchronous read and write operations. Functions such
55 as \l waitForReadyRead() and \l waitForBytesWritten() are not implemented. I/O operations should be
56 performed using \l readyRead(), \l read() and \l write().
57
58 On iOS, this class cannot be used because the platform does not expose
59 an API which may permit access to QBluetoothSocket related features.
60
61 \note On macOS Monterey (12) the socket data flow is paused when a
62 modal dialogue is executing, or an event tracking mode is entered (for
63 example by long-pressing a Window close button). This issue has been
64 fixed in macOS Sequoia (15).
65*/
66
67/*!
68 \enum QBluetoothSocket::SocketState
69
70 This enum describes the state of the Bluetooth socket.
71
72 \value UnconnectedState Socket is not connected.
73 \value ServiceLookupState Socket is querying connection parameters.
74 \value ConnectingState Socket is attempting to connect to a device.
75 \value ConnectedState Socket is connected to a device.
76 \value BoundState Socket is bound to a local address and port.
77 \value ClosingState Socket is connected and will be closed once all pending data is
78 written to the socket.
79 \value ListeningState Socket is listening for incoming connections.
80*/
81
82/*!
83 \enum QBluetoothSocket::SocketError
84
85 This enum describes Bluetooth socket error types.
86
87 \value UnknownSocketError An unknown error has occurred.
88 \value NoSocketError No error. Used for testing.
89 \value HostNotFoundError Could not find the remote host.
90 \value ServiceNotFoundError Could not find the service UUID on remote host.
91 \value NetworkError Attempt to read or write from socket returned an error
92 \value UnsupportedProtocolError The \l {QBluetoothServiceInfo::Protocol}{Protocol} is not
93 supported on this platform.
94 \value OperationError An operation was attempted while the socket was in a state
95 that did not permit it.
96 \value [since 5.10] RemoteHostClosedError The remote host closed the connection.
97 \value [since 6.4] MissingPermissionsError The operating system requests
98 permissions which were not
99 granted by the user.
100*/
101
102/*!
103 \fn void QBluetoothSocket::connected()
104
105 This signal is emitted when a connection is established.
106
107 \sa QBluetoothSocket::SocketState::ConnectedState, stateChanged()
108*/
109
110/*!
111 \fn void QBluetoothSocket::disconnected()
112
113 This signal is emitted when the socket is disconnected.
114
115 \sa QBluetoothSocket::SocketState::UnconnectedState, stateChanged()
116*/
117
118/*!
119 \fn void QBluetoothSocket::errorOccurred(QBluetoothSocket::SocketError error)
120
121 This signal is emitted when an \a error occurs.
122
123 \sa error()
124 \since 6.2
125*/
126
127/*!
128 \fn QBluetoothSocket::stateChanged(QBluetoothSocket::SocketState state)
129
130 This signal is emitted when the socket state changes to \a state.
131
132 \sa connected(), disconnected(), state(), QBluetoothSocket::SocketState
133*/
134
135/*!
136 \fn void QBluetoothSocket::abort()
137
138 Aborts the current connection and resets the socket. Unlike disconnectFromService(), this
139 function immediately closes the socket, discarding any pending data in the write buffer.
140
141 \note On Android, aborting the socket requires asynchronous interaction with Android threads.
142 Therefore the associated \l disconnected() and \l stateChanged() signals are delayed
143 until the threads have finished the closure.
144
145 \sa disconnectFromService(), close()
146*/
147
148/*!
149 \fn void QBluetoothSocket::close()
150
151 Disconnects the socket's connection with the device.
152
153 \note On Android, closing the socket requires asynchronous interaction with Android threads.
154 Therefore the associated \l disconnected() and \l stateChanged() signals are delayed
155 until the threads have finished the closure.
156
157*/
158
159/*!
160 \fn void QBluetoothSocket::disconnectFromService()
161
162 Attempts to close the socket. If there is pending data waiting to be written QBluetoothSocket
163 will enter ClosingState and wait until all data has been written. Eventually, it will enter
164 UnconnectedState and emit the disconnected() signal.
165
166 \sa connectToService()
167*/
168
169/*!
170 \fn QString QBluetoothSocket::localName() const
171
172 Returns the name of the local device.
173
174 Although some platforms may differ the socket must generally be connected to guarantee
175 the return of a valid name. In particular, this is true when dealing with platforms
176 that support multiple local Bluetooth adapters.
177*/
178
179/*!
180 \fn QBluetoothAddress QBluetoothSocket::localAddress() const
181
182 Returns the address of the local device.
183
184 Although some platforms may differ the socket must generally be connected to guarantee
185 the return of a valid address. In particular, this is true when dealing with platforms
186 that support multiple local Bluetooth adapters.
187*/
188
189/*!
190 \fn quint16 QBluetoothSocket::localPort() const
191
192 Returns the port number of the local socket if available, otherwise returns 0.
193 Although some platforms may differ the socket must generally be connected to guarantee
194 the return of a valid port number.
195
196 On Android and \macos, this feature is not supported and returns 0.
197*/
198
199/*!
200 \fn QString QBluetoothSocket::peerName() const
201
202 Returns the name of the peer device.
203*/
204
205/*!
206 \fn QBluetoothAddress QBluetoothSocket::peerAddress() const
207
208 Returns the address of the peer device.
209*/
210
211/*!
212 \fn quint16 QBluetoothSocket::peerPort() const
213
214 Return the port number of the peer socket if available, otherwise returns 0.
215 On Android, this feature is not supported.
216*/
217
218/*!
219 \fn qint64 QBluetoothSocket::readData(char *data, qint64 maxSize)
220
221 \reimp
222*/
223
224/*!
225 \fn qint64 QBluetoothSocket::writeData(const char *data, qint64 maxSize)
226
227 \reimp
228*/
229
230static QBluetoothSocketBasePrivate *createSocketPrivate()
231{
232#if QT_CONFIG(bluez)
233 if (bluetoothdVersion() >= QVersionNumber(5, 46)) {
234 qCDebug(QT_BT) << "Using Bluetooth dbus socket implementation";
235 return new QBluetoothSocketPrivateBluezDBus();
236 } else {
237 qCDebug(QT_BT) << "Using Bluetooth raw socket implementation";
238 return new QBluetoothSocketPrivateBluez();
239 }
240#elif defined(QT_ANDROID_BLUETOOTH)
241 return new QBluetoothSocketPrivateAndroid();
242#elif defined(QT_WINRT_BLUETOOTH)
243 return new QBluetoothSocketPrivateWinRT();
244#elif defined(QT_OSX_BLUETOOTH)
245 return new QBluetoothSocketPrivateDarwin();
246#else
247 return new QBluetoothSocketPrivateDummy();
248#endif
249}
250
251/*!
252 Constructs a Bluetooth socket of \a socketType type, with \a parent.
253*/
254QBluetoothSocket::QBluetoothSocket(QBluetoothServiceInfo::Protocol socketType, QObject *parent)
255: QIODevice(parent)
256{
257 d_ptr = createSocketPrivate();
258 d_ptr->q_ptr = this;
259
260 Q_D(QBluetoothSocketBase);
261 d->ensureNativeSocket(socketType);
262
263 setOpenMode(QIODevice::NotOpen);
264}
265
266/*!
267 Constructs a Bluetooth socket with \a parent.
268*/
269QBluetoothSocket::QBluetoothSocket(QObject *parent)
270 : QIODevice(parent)
271{
272 d_ptr = createSocketPrivate();
273 d_ptr->q_ptr = this;
274 setOpenMode(QIODevice::NotOpen);
275}
276
277#if QT_CONFIG(bluez)
278
279/*!
280 \internal
281*/
282QBluetoothSocket::QBluetoothSocket(QBluetoothSocketBasePrivate *dPrivate,
283 QBluetoothServiceInfo::Protocol socketType,
284 QObject *parent)
285 : QIODevice(parent)
286{
287 d_ptr = dPrivate;
288 d_ptr->q_ptr = this;
289
290 Q_D(QBluetoothSocketBase);
291 d->ensureNativeSocket(socketType);
292
293 setOpenMode(QIODevice::NotOpen);
294}
295
296#endif
297
298/*!
299 Destroys the Bluetooth socket.
300*/
301QBluetoothSocket::~QBluetoothSocket()
302{
303 delete d_ptr;
304 d_ptr = nullptr;
305}
306
307/*!
308 \reimp
309*/
310bool QBluetoothSocket::isSequential() const
311{
312 return true;
313}
314
315/*!
316 Returns the number of incoming bytes that are waiting to be read.
317
318 \sa bytesToWrite(), read()
319*/
320qint64 QBluetoothSocket::bytesAvailable() const
321{
322 Q_D(const QBluetoothSocketBase);
323 return QIODevice::bytesAvailable() + d->bytesAvailable();
324}
325
326/*!
327 Returns the number of bytes that are waiting to be written. The bytes are written when control
328 goes back to the event loop.
329*/
330qint64 QBluetoothSocket::bytesToWrite() const
331{
332 Q_D(const QBluetoothSocketBase);
333 return d->bytesToWrite();
334}
335
336/*!
337 Attempts to connect to the service described by \a service.
338
339 The socket is opened in the given \a openMode. The \l socketType() is ignored
340 if \a service specifies a differing \l QBluetoothServiceInfo::socketProtocol().
341
342 The socket first enters ConnectingState and attempts to connect to the device providing
343 \a service. If a connection is established, QBluetoothSocket enters ConnectedState and
344 emits connected().
345
346 At any point, the socket can emit errorOccurred() to signal that an error occurred.
347
348 Note that most platforms require a pairing prior to connecting to the remote device. Otherwise
349 the connection process may fail.
350
351 On Android, only RFCOMM connections are possible. This function ignores any socket protocol indicator
352 and assumes RFCOMM.
353
354 \sa state(), disconnectFromService()
355*/
356void QBluetoothSocket::connectToService(const QBluetoothServiceInfo &service, OpenMode openMode)
357{
358 Q_D(QBluetoothSocketBase);
359 d->connectToService(service, openMode);
360}
361
362/*!
363 \fn void QBluetoothSocket::connectToService(const QBluetoothAddress &address, QBluetoothUuid::ServiceClassUuid uuid, OpenMode mode = ReadWrite)
364
365 \internal
366
367 Exists to avoid QTBUG-65831.
368*/
369
370/*!
371 Attempts to make a connection to the service identified by \a uuid on the device with address
372 \a address.
373
374 The socket is opened in the given \a openMode.
375
376 For BlueZ, the socket first enters the \l ServiceLookupState and queries the connection parameters for
377 \a uuid. If the service parameters are successfully retrieved the socket enters
378 ConnectingState, and attempts to connect to \a address. If a connection is established,
379 QBluetoothSocket enters \l ConnectedState and emits connected().
380
381 On Android, the service connection can directly be established
382 using the UUID of the remote service. Therefore the platform does not require
383 the \l ServiceLookupState and \l socketType() is always set to
384 \l QBluetoothServiceInfo::RfcommProtocol.
385
386 At any point, the socket can emit errorOccurred() to signal that an error occurred.
387
388 Note that most platforms require a pairing prior to connecting to the remote device. Otherwise
389 the connection process may fail.
390
391 \sa state(), disconnectFromService()
392*/
393void QBluetoothSocket::connectToService(const QBluetoothAddress &address, const QBluetoothUuid &uuid, OpenMode openMode)
394{
395 Q_D(QBluetoothSocketBase);
396 d->connectToService(address, uuid, openMode);
397}
398
399/*!
400 Attempts to make a connection with \a address on the given \a port.
401
402 The socket is opened in the given \a openMode.
403
404 The socket first enters ConnectingState, and attempts to connect to \a address. If a
405 connection is established, QBluetoothSocket enters ConnectedState and emits connected().
406
407 At any point, the socket can emit errorOccurred() to signal that an error occurred.
408
409 On Android and BlueZ (version 5.46 or above), a connection to a service can not be established using a port.
410 Calling this function will emit a \l {QBluetoothSocket::SocketError::ServiceNotFoundError}{ServiceNotFoundError}.
411
412 Note that most platforms require a pairing prior to connecting to the remote device. Otherwise
413 the connection process may fail.
414
415 \sa state(), disconnectFromService()
416*/
417void QBluetoothSocket::connectToService(const QBluetoothAddress &address, quint16 port, OpenMode openMode)
418{
419 Q_D(QBluetoothSocketBase);
420 d->connectToService(address, port, openMode);
421}
422
423/*!
424 Returns the socket type. The socket automatically adjusts to the protocol
425 offered by the remote service.
426
427 Android only support \l{QBluetoothServiceInfo::RfcommProtocol}{RFCOMM}
428 based sockets.
429*/
430QBluetoothServiceInfo::Protocol QBluetoothSocket::socketType() const
431{
432 Q_D(const QBluetoothSocketBase);
433 return d->socketType;
434}
435
436/*!
437 Returns the current state of the socket.
438*/
439QBluetoothSocket::SocketState QBluetoothSocket::state() const
440{
441 Q_D(const QBluetoothSocketBase);
442 return d->state;
443}
444
445/*!
446 Returns the last error.
447*/
448QBluetoothSocket::SocketError QBluetoothSocket::error() const
449{
450 Q_D(const QBluetoothSocketBase);
451 return d->socketError;
452}
453
454/*!
455 Returns a user displayable text string for the error.
456 */
457QString QBluetoothSocket::errorString() const
458{
459 Q_D(const QBluetoothSocketBase);
460 return d->errorString;
461}
462
463/*!
464 Sets the preferred security parameter for the connection attempt to
465 \a flags. This value is incorporated when calling \l connectToService().
466 Therefore it is required to reconnect to change this parameter for an
467 existing connection.
468
469 \include qbluetoothserver.cpp bluetooth_security_bluez
470
471 On Linux with the BlueZ D-Bus backend and on Windows, this flag is not
472 supported and ignored.
473
474 On \macos, this value is ignored as the platform does not permit access
475 to the security parameter of the socket. By default the platform prefers
476 secure/encrypted connections though and therefore this function always
477 returns \l QBluetooth::Security::Secure.
478
479 Android only supports two levels of security (secure and non-secure).
480 If this flag is set to \l QBluetooth::Security::NoSecurity the socket
481 object will not employ any authentication or encryption. Any other
482 security flag combination will trigger a secure Bluetooth connection.
483 This flag is set to \l QBluetooth::Security::Secure by default.
484
485 \note A secure connection requires a pairing between the two devices. On
486 some platforms, the pairing is automatically initiated during the establishment
487 of the connection. Other platforms require the application to manually trigger
488 the pairing before attempting to connect.
489
490 \sa preferredSecurityFlags()
491
492 \since 5.6
493*/
494void QBluetoothSocket::setPreferredSecurityFlags(QBluetooth::SecurityFlags flags)
495{
496#ifdef QT_OSX_BLUETOOTH
497 return; // not supported on macOS.
498#endif
499 Q_D(QBluetoothSocketBase);
500 if (d->secFlags != flags)
501 d->secFlags = flags;
502}
503
504/*!
505 Returns the security parameters used for the initial connection
506 attempt.
507
508 The security parameters may be renegotiated between the two parties
509 during or after the connection has been established. If such a change happens
510 it is not reflected in the value of this flag.
511
512 On \macos, this flag is always set to \l QBluetooth::Security::Secure.
513
514 \sa setPreferredSecurityFlags()
515
516 \since 5.6
517*/
518QBluetooth::SecurityFlags QBluetoothSocket::preferredSecurityFlags() const
519{
520#if QT_OSX_BLUETOOTH
521 // not supported on macOS - platform always uses encryption
522 return QBluetooth::Security::Secure;
523#else
524 Q_D(const QBluetoothSocketBase);
525 return d->secFlags;
526#endif // QT_OSX_BLUETOOTH
527}
528
529/*!
530 Sets the socket state to \a state.
531*/
532void QBluetoothSocket::setSocketState(QBluetoothSocket::SocketState state)
533{
534 Q_D(QBluetoothSocketBase);
535 const SocketState old = d->state;
536 if (state == old)
537 return;
538
539 d->state = state;
540 if(old != d->state)
541 emit stateChanged(state);
542 if (state == QBluetoothSocket::SocketState::ConnectedState) {
543 emit connected();
544 } else if ((old == QBluetoothSocket::SocketState::ConnectedState
545 || old == QBluetoothSocket::SocketState::ClosingState)
546 && state == QBluetoothSocket::SocketState::UnconnectedState) {
547 emit disconnected();
548 }
549 if (state == SocketState::ListeningState){
550#ifdef QT_OSX_BLUETOOTH
551 qCWarning(QT_BT) << "listening socket is not supported by IOBluetooth";
552#endif
553 // TODO: look at this, is this really correct?
554 // if we're a listening socket we can't handle connects?
555 if (d->readNotifier) {
556 d->readNotifier->setEnabled(false);
557 }
558 }
559}
560
561/*!
562 Returns true if you can read at least one line from the device
563 */
564
565bool QBluetoothSocket::canReadLine() const
566{
567 Q_D(const QBluetoothSocketBase);
568 return d->canReadLine() || QIODevice::canReadLine();
569}
570
571/*!
572 Sets the type of error that last occurred to \a error_.
573*/
574void QBluetoothSocket::setSocketError(QBluetoothSocket::SocketError error_)
575{
576 Q_D(QBluetoothSocketBase);
577 d->socketError = error_;
578 emit errorOccurred(error_);
579}
580
581/*!
582 Start device discovery for \a service and open the socket with \a openMode. If the socket
583 is created with a service uuid device address, use service discovery to find the
584 port number to connect to.
585*/
586
587void QBluetoothSocket::doDeviceDiscovery(const QBluetoothServiceInfo &service, OpenMode openMode)
588{
589 Q_D(QBluetoothSocketBase);
590
591 setSocketState(QBluetoothSocket::SocketState::ServiceLookupState);
592 qCDebug(QT_BT) << "Starting Bluetooth service discovery";
593
594 if(d->discoveryAgent) {
595 d->discoveryAgent->stop();
596 delete d->discoveryAgent;
597 }
598
599 d->discoveryAgent = new QBluetoothServiceDiscoveryAgent(this);
600 d->discoveryAgent->setRemoteAddress(service.device().address());
601
602 //qDebug() << "Got agent";
603
604 connect(d->discoveryAgent, &QBluetoothServiceDiscoveryAgent::serviceDiscovered,
605 this, &QBluetoothSocket::serviceDiscovered);
606 connect(d->discoveryAgent, &QBluetoothServiceDiscoveryAgent::finished,
607 this, &QBluetoothSocket::discoveryFinished);
608
609 d->openMode = openMode;
610
611 QList<QBluetoothUuid> filterUuids = service.serviceClassUuids();
612 if(!service.serviceUuid().isNull())
613 filterUuids.append(service.serviceUuid());
614
615 if (!filterUuids.isEmpty())
616 d->discoveryAgent->setUuidFilter(filterUuids);
617
618 // we have to ID the service somehow
619 Q_ASSERT(!d->discoveryAgent->uuidFilter().isEmpty());
620
621 qCDebug(QT_BT) << "UUID filter" << d->discoveryAgent->uuidFilter();
622
623 d->discoveryAgent->start(QBluetoothServiceDiscoveryAgent::FullDiscovery);
624}
625
626void QBluetoothSocket::serviceDiscovered(const QBluetoothServiceInfo &service)
627{
628 Q_D(QBluetoothSocketBase);
629 qCDebug(QT_BT) << "FOUND SERVICE!" << service;
630 if (service.protocolServiceMultiplexer() > 0 || service.serverChannel() > 0) {
631 connectToService(service, d->openMode);
632 d->discoveryAgent->deleteLater();
633 d->discoveryAgent = nullptr;
634#ifdef QT_WINRT_BLUETOOTH
635 } else if (!service.attribute(0xBEEF).isNull()
636 && !service.attribute(0xBEF0).isNull()) {
637 connectToService(service, d->openMode);
638 d->discoveryAgent->deleteLater();
639 d->discoveryAgent = nullptr;
640#endif
641 } else {
642 qCDebug(QT_BT) << "Could not find port/psm for potential remote service";
643 }
644}
645
646void QBluetoothSocket::discoveryFinished()
647{
648 qCDebug(QT_BT) << "Socket discovery finished";
649 Q_D(QBluetoothSocketBase);
650 if (d->discoveryAgent){
651 qCDebug(QT_BT) << "Didn't find any";
652 d->errorString = tr("Service cannot be found");
653 setSocketError(SocketError::ServiceNotFoundError);
654 setSocketState(QBluetoothSocket::SocketState::UnconnectedState);
655 d->discoveryAgent->deleteLater();
656 d->discoveryAgent = nullptr;
657 }
658}
659
660void QBluetoothSocket::abort()
661{
662 if (state() == SocketState::UnconnectedState)
663 return;
664
665 Q_D(QBluetoothSocketBase);
666 setOpenMode(QIODevice::NotOpen);
667
668 if (state() == SocketState::ServiceLookupState && d->discoveryAgent) {
669 d->discoveryAgent->disconnect();
670 d->discoveryAgent->stop();
671 d->discoveryAgent = nullptr;
672 }
673
674 setSocketState(SocketState::ClosingState);
675 d->abort();
676}
677
678void QBluetoothSocket::disconnectFromService()
679{
680 close();
681}
682
683QString QBluetoothSocket::localName() const
684{
685 Q_D(const QBluetoothSocketBase);
686 return d->localName();
687}
688
689QBluetoothAddress QBluetoothSocket::localAddress() const
690{
691 Q_D(const QBluetoothSocketBase);
692 return d->localAddress();
693}
694
695quint16 QBluetoothSocket::localPort() const
696{
697 Q_D(const QBluetoothSocketBase);
698 return d->localPort();
699}
700
701QString QBluetoothSocket::peerName() const
702{
703 Q_D(const QBluetoothSocketBase);
704 return d->peerName();
705}
706
707QBluetoothAddress QBluetoothSocket::peerAddress() const
708{
709 Q_D(const QBluetoothSocketBase);
710 return d->peerAddress();
711}
712
713quint16 QBluetoothSocket::peerPort() const
714{
715 Q_D(const QBluetoothSocketBase);
716 return d->peerPort();
717}
718
719qint64 QBluetoothSocket::writeData(const char *data, qint64 maxSize)
720{
721 Q_D(QBluetoothSocketBase);
722
723 if (!data || maxSize <= 0) {
724 d_ptr->errorString = tr("Invalid data/data size");
725 setSocketError(QBluetoothSocket::SocketError::OperationError);
726 return -1;
727 }
728
729 return d->writeData(data, maxSize);
730}
731
732qint64 QBluetoothSocket::readData(char *data, qint64 maxSize)
733{
734 Q_D(QBluetoothSocketBase);
735 return d->readData(data, maxSize);
736}
737
738void QBluetoothSocket::close()
739{
740 if (state() == SocketState::UnconnectedState)
741 return;
742
743 Q_D(QBluetoothSocketBase);
744 setOpenMode(QIODevice::NotOpen);
745
746 if (state() == SocketState::ServiceLookupState && d->discoveryAgent) {
747 d->discoveryAgent->disconnect();
748 d->discoveryAgent->stop();
749 d->discoveryAgent = nullptr;
750 }
751
752 setSocketState(SocketState::ClosingState);
753
754 d->close();
755}
756
757/*!
758 \fn bool QBluetoothSocket::setSocketDescriptor(int socketDescriptor, QBluetoothServiceInfo::Protocol socketType, SocketState socketState, OpenMode openMode)
759
760 Sets the socket to use \a socketDescriptor with a type of \a socketType,
761 which is in state \a socketState, and mode \a openMode.
762
763 The socket descriptor is owned by the QBluetoothSocket instance and may
764 be closed once finished.
765
766 Returns \c true on success.
767*/
768
769// ### Qt 7 consider making this function private. The qbluetoothsocket_bluez backend is the
770// the only backend providing publicly accessible support for this. Other backends implement
771// similarly named, but private, overload
772bool QBluetoothSocket::setSocketDescriptor(int socketDescriptor, QBluetoothServiceInfo::Protocol socketType,
773 SocketState socketState, OpenMode openMode)
774{
775 Q_D(QBluetoothSocketBase);
776 return d->setSocketDescriptor(socketDescriptor, socketType, socketState, openMode);
777}
778
779/*!
780 Returns the platform-specific socket descriptor, if available.
781 This function returns -1 if the descriptor is not available or an error has occurred.
782*/
783
784int QBluetoothSocket::socketDescriptor() const
785{
786 Q_D(const QBluetoothSocketBase);
787 return d->socket;
788}
789
790QT_END_NAMESPACE
791
792#include "moc_qbluetoothsocket.cpp"
Combined button and popup list for selecting options.