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
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
5#include "qbluetoothsocket.h"
6#if QT_CONFIG(bluez)
10#elif defined(QT_ANDROID_BLUETOOTH)
12#elif defined(QT_WINRT_BLUETOOTH)
14#elif defined(QT_OSX_BLUETOOTH)
16#else
18#endif
19
21
22#include <QtCore/QLoggingCategory>
23#include <QSocketNotifier>
24
26
28
29
231{
232#if QT_CONFIG(bluez)
233 if (bluetoothdVersion() >= QVersionNumber(5, 46)) {
234 qCDebug(QT_BT) << "Using Bluetooth dbus socket implementation";
236 } else {
237 qCDebug(QT_BT) << "Using Bluetooth raw socket implementation";
238 return new QBluetoothSocketPrivateBluez();
239 }
240#elif defined(QT_ANDROID_BLUETOOTH)
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
255: QIODevice(parent)
256{
258 d_ptr->q_ptr = this;
259
260 Q_D(QBluetoothSocketBase);
261 d->ensureNativeSocket(socketType);
262
264}
265
276
277#if QT_CONFIG(bluez)
278
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
294}
295
296#endif
297
302{
303 delete d_ptr;
304 d_ptr = nullptr;
305}
306
311{
312 return true;
313}
314
321{
322 Q_D(const QBluetoothSocketBase);
323 return QIODevice::bytesAvailable() + d->bytesAvailable();
324}
325
331{
332 Q_D(const QBluetoothSocketBase);
333 return d->bytesToWrite();
334}
335
356void QBluetoothSocket::connectToService(const QBluetoothServiceInfo &service, OpenMode openMode)
357{
358 Q_D(QBluetoothSocketBase);
359 d->connectToService(service, openMode);
360}
361
394{
395 Q_D(QBluetoothSocketBase);
396 d->connectToService(address, uuid, openMode);
397}
398
418{
419 Q_D(QBluetoothSocketBase);
420 d->connectToService(address, port, openMode);
421}
422
431{
432 Q_D(const QBluetoothSocketBase);
433 return d->socketType;
434}
435
440{
441 Q_D(const QBluetoothSocketBase);
442 return d->state;
443}
444
449{
450 Q_D(const QBluetoothSocketBase);
451 return d->socketError;
452}
453
458{
459 Q_D(const QBluetoothSocketBase);
460 return d->errorString;
461}
462
492{
493#ifdef QT_OSX_BLUETOOTH
494 return; // not supported on macOS.
495#endif
496 Q_D(QBluetoothSocketBase);
497 if (d->secFlags != flags)
498 d->secFlags = flags;
499}
500
515QBluetooth::SecurityFlags QBluetoothSocket::preferredSecurityFlags() const
516{
517#if QT_OSX_BLUETOOTH
518 // not supported on macOS - platform always uses encryption
520#else
521 Q_D(const QBluetoothSocketBase);
522 return d->secFlags;
523#endif // QT_OSX_BLUETOOTH
524}
525
530{
531 Q_D(QBluetoothSocketBase);
532 const SocketState old = d->state;
533 if (state == old)
534 return;
535
536 d->state = state;
537 if(old != d->state)
540 emit connected();
545 }
547#ifdef QT_OSX_BLUETOOTH
548 qCWarning(QT_BT) << "listening socket is not supported by IOBluetooth";
549#endif
550 // TODO: look at this, is this really correct?
551 // if we're a listening socket we can't handle connects?
552 if (d->readNotifier) {
553 d->readNotifier->setEnabled(false);
554 }
555 }
556}
557
563{
564 Q_D(const QBluetoothSocketBase);
565 return d->canReadLine() || QIODevice::canReadLine();
566}
567
572{
573 Q_D(QBluetoothSocketBase);
574 d->socketError = error_;
575 emit errorOccurred(error_);
576}
577
584void QBluetoothSocket::doDeviceDiscovery(const QBluetoothServiceInfo &service, OpenMode openMode)
585{
586 Q_D(QBluetoothSocketBase);
587
589 qCDebug(QT_BT) << "Starting Bluetooth service discovery";
590
591 if(d->discoveryAgent) {
592 d->discoveryAgent->stop();
593 delete d->discoveryAgent;
594 }
595
596 d->discoveryAgent = new QBluetoothServiceDiscoveryAgent(this);
597 d->discoveryAgent->setRemoteAddress(service.device().address());
598
599 //qDebug() << "Got agent";
600
602 this, &QBluetoothSocket::serviceDiscovered);
604 this, &QBluetoothSocket::discoveryFinished);
605
606 d->openMode = openMode;
607
608 QList<QBluetoothUuid> filterUuids = service.serviceClassUuids();
609 if(!service.serviceUuid().isNull())
610 filterUuids.append(service.serviceUuid());
611
612 if (!filterUuids.isEmpty())
613 d->discoveryAgent->setUuidFilter(filterUuids);
614
615 // we have to ID the service somehow
616 Q_ASSERT(!d->discoveryAgent->uuidFilter().isEmpty());
617
618 qCDebug(QT_BT) << "UUID filter" << d->discoveryAgent->uuidFilter();
619
621}
622
623void QBluetoothSocket::serviceDiscovered(const QBluetoothServiceInfo &service)
624{
625 Q_D(QBluetoothSocketBase);
626 qCDebug(QT_BT) << "FOUND SERVICE!" << service;
627 if (service.protocolServiceMultiplexer() > 0 || service.serverChannel() > 0) {
628 connectToService(service, d->openMode);
629 d->discoveryAgent->deleteLater();
630 d->discoveryAgent = nullptr;
631#ifdef QT_WINRT_BLUETOOTH
632 } else if (!service.attribute(0xBEEF).isNull()
633 && !service.attribute(0xBEF0).isNull()) {
634 connectToService(service, d->openMode);
635 d->discoveryAgent->deleteLater();
636 d->discoveryAgent = nullptr;
637#endif
638 } else {
639 qCDebug(QT_BT) << "Could not find port/psm for potential remote service";
640 }
641}
642
643void QBluetoothSocket::discoveryFinished()
644{
645 qCDebug(QT_BT) << "Socket discovery finished";
646 Q_D(QBluetoothSocketBase);
647 if (d->discoveryAgent){
648 qCDebug(QT_BT) << "Didn't find any";
649 d->errorString = tr("Service cannot be found");
652 d->discoveryAgent->deleteLater();
653 d->discoveryAgent = nullptr;
654 }
655}
656
658{
660 return;
661
662 Q_D(QBluetoothSocketBase);
664
665 if (state() == SocketState::ServiceLookupState && d->discoveryAgent) {
666 d->discoveryAgent->disconnect();
667 d->discoveryAgent->stop();
668 d->discoveryAgent = nullptr;
669 }
670
672 d->abort();
673}
674
679
681{
682 Q_D(const QBluetoothSocketBase);
683 return d->localName();
684}
685
687{
688 Q_D(const QBluetoothSocketBase);
689 return d->localAddress();
690}
691
693{
694 Q_D(const QBluetoothSocketBase);
695 return d->localPort();
696}
697
699{
700 Q_D(const QBluetoothSocketBase);
701 return d->peerName();
702}
703
705{
706 Q_D(const QBluetoothSocketBase);
707 return d->peerAddress();
708}
709
711{
712 Q_D(const QBluetoothSocketBase);
713 return d->peerPort();
714}
715
717{
718 Q_D(QBluetoothSocketBase);
719
720 if (!data || maxSize <= 0) {
721 d_ptr->errorString = tr("Invalid data/data size");
723 return -1;
724 }
725
726 return d->writeData(data, maxSize);
727}
728
730{
731 Q_D(QBluetoothSocketBase);
732 return d->readData(data, maxSize);
733}
734
736{
738 return;
739
740 Q_D(QBluetoothSocketBase);
742
743 if (state() == SocketState::ServiceLookupState && d->discoveryAgent) {
744 d->discoveryAgent->disconnect();
745 d->discoveryAgent->stop();
746 d->discoveryAgent = nullptr;
747 }
748
750
751 d->close();
752}
753
766// ### Qt 7 consider making this function private. The qbluetoothsocket_bluez backend is the
767// the only backend providing publicly accessible support for this. Other backends implement
768// similarly named, but private, overload
770 SocketState socketState, OpenMode openMode)
771{
772 Q_D(QBluetoothSocketBase);
773 return d->setSocketDescriptor(socketDescriptor, socketType, socketState, openMode);
774}
775
782{
783 Q_D(const QBluetoothSocketBase);
784 return d->socket;
785}
786
788
789#include "moc_qbluetoothsocket.cpp"
QVersionNumber bluetoothdVersion()
\inmodule QtBluetooth
void finished()
This signal is emitted when the Bluetooth service discovery completes.
void serviceDiscovered(const QBluetoothServiceInfo &info)
This signal is emitted when the Bluetooth service described by info is discovered.
\inmodule QtBluetooth
Protocol
This enum describes the socket protocol used by the service.
bool canReadLine() const override
Returns true if you can read at least one line from the device.
void connectToService(const QBluetoothServiceInfo &service, OpenMode openMode=ReadWrite)
Attempts to connect to the service described by service.
quint16 peerPort() const
Return the port number of the peer socket if available, otherwise returns 0.
void connected()
This signal is emitted when a connection is established.
QBluetooth::SecurityFlags preferredSecurityFlags() const
Returns the security parameters used for the initial connection attempt.
QString peerName() const
Returns the name of the peer device.
SocketError error() const
Returns the last error.
QString errorString() const
Returns a user displayable text string for the error.
virtual ~QBluetoothSocket()
Destroys the Bluetooth socket.
quint16 localPort() const
Returns the port number of the local socket if available, otherwise returns 0.
void doDeviceDiscovery(const QBluetoothServiceInfo &service, OpenMode openMode)
Start device discovery for service and open the socket with openMode.
void stateChanged(QBluetoothSocket::SocketState state)
This signal is emitted when the socket state changes to state.
void abort()
Aborts the current connection and resets the socket.
void setSocketState(SocketState state)
Sets the socket state to state.
qint64 bytesToWrite() const override
Returns the number of bytes that are waiting to be written.
void setPreferredSecurityFlags(QBluetooth::SecurityFlags flags)
Sets the preferred security parameter for the connection attempt to flags.
void disconnectFromService()
Attempts to close the socket.
QString localName() const
Returns the name of the local device.
bool setSocketDescriptor(int socketDescriptor, QBluetoothServiceInfo::Protocol socketType, SocketState socketState=SocketState::ConnectedState, OpenMode openMode=ReadWrite)
Sets the socket to use socketDescriptor with a type of socketType, which is in state socketState,...
void errorOccurred(QBluetoothSocket::SocketError error)
This signal is emitted when an error occurs.
qint64 writeData(const char *data, qint64 maxSize) override
\reimp
QBluetoothSocketBasePrivate * d_ptr
void close() override
Disconnects the socket's connection with the device.
SocketState
This enum describes the state of the Bluetooth socket.
qint64 bytesAvailable() const override
Returns the number of incoming bytes that are waiting to be read.
QBluetoothAddress localAddress() const
Returns the address of the local device.
int socketDescriptor() const
Returns the platform-specific socket descriptor, if available.
QBluetoothAddress peerAddress() const
Returns the address of the peer device.
void setSocketError(SocketError error)
Sets the type of error that last occurred to error_.
QBluetoothServiceInfo::Protocol socketType() const
Returns the socket type.
bool isSequential() const override
\reimp
QBluetoothSocket(QBluetoothServiceInfo::Protocol socketType, QObject *parent=nullptr)
Constructs a Bluetooth socket of socketType type, with parent.
SocketState state() const
Returns the current state of the socket.
qint64 readData(char *data, qint64 maxSize) override
\reimp
SocketError
This enum describes Bluetooth socket error types.
void disconnected()
This signal is emitted when the socket is disconnected.
\inmodule QtBluetooth
\inmodule QtCore \reentrant
Definition qiodevice.h:34
void setOpenMode(QIODeviceBase::OpenMode openMode)
Sets the OpenMode of the device to openMode.
QIODeviceBase::OpenMode openMode() const
Returns the mode in which the device has been opened; i.e.
virtual qint64 bytesAvailable() const
Returns the number of bytes that are available for reading.
virtual bool canReadLine() const
Returns true if a complete line of data can be read from the device; otherwise returns false.
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\inmodule QtCore
else opt state
[0]
Combined button and popup list for selecting options.
Q_CORE_EXPORT QtJniTypes::Service service()
static QBluetoothSocketBasePrivate * createSocketPrivate()
EGLOutputPortEXT port
static QT_BEGIN_NAMESPACE const char * socketType(QSocketNotifier::Type type)
#define qCWarning(category,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLbitfield flags
GLuint GLuint64EXT address
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define tr(X)
#define emit
unsigned short quint16
Definition qtypes.h:48
long long qint64
Definition qtypes.h:60