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