| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the QtBluetooth module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Lesser General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Lesser |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
| ** packaging of this file. Please review the following information to |
| ** ensure the GNU Lesser General Public License version 3 requirements |
| ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 2.0 or (at your option) the GNU General |
| ** Public license version 3 or any later version approved by the KDE Free |
| ** Qt Foundation. The licenses are as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
| ** https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include "qbluetoothserviceinfo.h" |
| #include "qbluetoothserviceinfo_p.h" |
| |
| #include <QUrl> |
| |
| QT_BEGIN_NAMESPACE |
| |
| /*! |
| \class QBluetoothServiceInfo::Sequence |
| \inmodule QtBluetooth |
| \brief The Sequence class stores attributes of a Bluetooth Data Element |
| Sequence. |
| |
| \since 5.2 |
| |
| */ |
| |
| /*! |
| \fn QBluetoothServiceInfo::Sequence::Sequence() |
| |
| Constructs a new empty sequence. |
| */ |
| |
| /*! |
| \fn QBluetoothServiceInfo::Sequence::Sequence(const QList<QVariant> &list) |
| |
| Constructs a new sequence that is a copy of \a list. |
| */ |
| |
| /*! |
| \class QBluetoothServiceInfo::Alternative |
| \inmodule QtBluetooth |
| \brief The Alternative class stores attributes of a Bluetooth Data Element |
| Alternative. |
| |
| \since 5.2 |
| */ |
| |
| /*! |
| \fn QBluetoothServiceInfo::Alternative::Alternative() |
| |
| Constructs a new empty alternative. |
| */ |
| |
| /*! |
| \fn QBluetoothServiceInfo::Alternative::Alternative(const QList<QVariant> &list) |
| |
| Constructs a new alternative that is a copy of \a list. |
| */ |
| |
| /*! |
| \class QBluetoothServiceInfo |
| \inmodule QtBluetooth |
| \brief The QBluetoothServiceInfo class enables access to the attributes of a |
| Bluetooth service. |
| |
| \since 5.2 |
| |
| QBluetoothServiceInfo provides information about a service offered by a Bluetooth device. |
| In addition it can be used to register new services on the local device. Note that such |
| a registration only affects the Bluetooth SDP entries. Any server listening |
| for incoming connections (e.g an RFCOMM server) must be started before registerService() |
| is called. Deregistration must happen in the reverse order. |
| |
| QBluetoothServiceInfo is not a value type in the traditional sense. All copies of the same |
| service info object share the same data as they do not detach upon changing them. This |
| ensures that two copies can (de)register the same Bluetooth service. |
| |
| On iOS, this class cannot be used because the platform does not expose |
| an API which may permit access to QBluetoothServiceInfo related features. |
| */ |
| |
| /*! |
| \enum QBluetoothServiceInfo::AttributeId |
| |
| Bluetooth service attributes. Please check the Bluetooth Core Specification for a more detailed description of these attributes. |
| |
| \value ServiceRecordHandle Specifies a service record from which attributes can be retrieved. |
| \value ServiceClassIds UUIDs of service classes that the service conforms to. The |
| most common service classes are defined in (\l QBluetoothUuid::ServiceClassUuid) |
| \value ServiceRecordState Attibute changes when any other service attribute is added, deleted or modified. |
| \value ServiceId UUID that uniquely identifies the service. |
| \value ProtocolDescriptorList List of protocols used by the service. The most common protocol Uuids are defined |
| in \l QBluetoothUuid::ProtocolUuid |
| \value BrowseGroupList List of browse groups the service is in. |
| \value LanguageBaseAttributeIdList List of language base attribute IDs to support human-readable attributes. |
| \value ServiceInfoTimeToLive Number of seconds for which the service record is expected to remain valid and unchanged. |
| \value ServiceAvailability Value indicating the availability of the service. |
| \value BluetoothProfileDescriptorList List of profiles to which the service conforms. |
| \value DocumentationUrl URL that points to the documentation on the service.. |
| \value ClientExecutableUrl URL that refers to the location of an application that can be used to utilize the service. |
| \value IconUrl URL to the location of the icon representing the service. |
| \value AdditionalProtocolDescriptorList Additional protocols used by the service. This attribute extends \c ProtocolDescriptorList. |
| \value PrimaryLanguageBase Base index for primary language text descriptors. |
| \value ServiceName Name of the Bluetooth service in the primary language. |
| \value ServiceDescription Description of the Bluetooth service in the primary language. |
| \value ServiceProvider Name of the company / entity that provides the Bluetooth service primary language. |
| |
| \note On Windows ServiceClassIds and ProtocolDescriptorList are automatically set to default |
| values when a service is created. Manually setting values for these attributes will not work and |
| might lead to unexpected results on this platform. |
| */ |
| |
| /*! |
| \enum QBluetoothServiceInfo::Protocol |
| |
| This enum describes the socket protocol used by the service. |
| |
| \value UnknownProtocol The service uses an unknown socket protocol. |
| \value L2capProtocol The service uses the L2CAP socket protocol. This protocol is not supported |
| for direct socket connections on Android. |
| \value RfcommProtocol The service uses the RFCOMM socket protocol. |
| */ |
| |
| /*! |
| \fn bool QBluetoothServiceInfo::isRegistered() const |
| |
| Returns true if the service information is registered with the platform's Service Discovery Protocol |
| (SDP) implementation, otherwise returns false. |
| */ |
| |
| bool QBluetoothServiceInfo::isRegistered() const |
| { |
| return d_ptr->isRegistered(); |
| } |
| |
| /*! |
| \fn bool QBluetoothServiceInfo::registerService(const QBluetoothAddress &localAdapter) |
| |
| Registers this service with the platform's Service Discovery Protocol (SDP) implementation, |
| making it findable by other devices when they perform service discovery. Returns true if the |
| service is successfully registered, otherwise returns false. Once registered changes to the record |
| cannot be made. The service must be unregistered and registered again with the changes. |
| |
| The \a localAdapter parameter determines the local Bluetooth adapter under which |
| the service should be registered. If \a localAdapter is \c null the default Bluetooth adapter |
| will be used. If this service info object is already registered via a local adapter |
| and this is function is called using a different local adapter, the previous registration |
| is removed and the service reregistered using the new adapter. |
| */ |
| |
| bool QBluetoothServiceInfo::registerService(const QBluetoothAddress &localAdapter) |
| { |
| #ifdef QT_OSX_BLUETOOTH |
| Q_UNUSED(localAdapter) |
| return d_ptr->registerService(*this); |
| #else |
| return d_ptr->registerService(localAdapter); |
| #endif |
| } |
| |
| /*! |
| \fn bool QBluetoothServiceInfo::unregisterService() |
| |
| Unregisters this service with the platform's Service Discovery Protocol (SDP) implementation. |
| After this, the service will no longer be findable by other devices through service discovery. |
| |
| Returns true if the service is successfully unregistered, otherwise returns false. |
| */ |
| |
| bool QBluetoothServiceInfo::unregisterService() |
| { |
| return d_ptr->unregisterService(); |
| } |
| |
| |
| /*! |
| \fn void QBluetoothServiceInfo::setAttribute(quint16 attributeId, const QBluetoothUuid &value) |
| |
| This is a convenience function. |
| |
| Sets the attribute identified by \a attributeId to \a value. |
| |
| If the service information is already registered with the platform's SDP database, |
| the database entry will not be updated until \l registerService() was called again. |
| */ |
| |
| /*! |
| \fn void QBluetoothServiceInfo::setAttribute(quint16 attributeId, const QBluetoothServiceInfo::Sequence &value) |
| |
| This is a convenience function. |
| |
| Sets the attribute identified by \a attributeId to \a value. |
| |
| If the service information is already registered with the platform's SDP database, |
| the database entry will not be updated until \l registerService() was called again. |
| */ |
| |
| /*! |
| \fn void QBluetoothServiceInfo::setAttribute(quint16 attributeId, const QBluetoothServiceInfo::Alternative &value) |
| |
| This is a convenience function. |
| |
| Sets the attribute identified by \a attributeId to \a value. |
| |
| If the service information is already registered with the platform's SDP database, |
| the database entry will not be updated until \l registerService() was called again. |
| */ |
| |
| /*! |
| \fn void QBluetoothServiceInfo::setServiceName(const QString &name) |
| |
| This is a convenience function. It is equivalent to calling |
| setAttribute(QBluetoothServiceInfo::ServiceName, name). |
| |
| Sets the service name in the primary language to \a name. |
| |
| \sa serviceName(), setAttribute() |
| */ |
| |
| /*! |
| \fn QString QBluetoothServiceInfo::serviceName() const |
| |
| This is a convenience function. It is equivalent to calling |
| attribute(QBluetoothServiceInfo::ServiceName).toString(). |
| |
| Returns the service name in the primary language. |
| |
| \sa setServiceName(), attribute() |
| */ |
| |
| /*! |
| \fn void QBluetoothServiceInfo::setServiceDescription(const QString &description) |
| |
| This is a convenience function. It is equivalent to calling |
| setAttribute(QBluetoothServiceInfo::ServiceDescription, description). |
| |
| Sets the service description in the primary language to \a description. |
| |
| \sa serviceDescription(), setAttribute() |
| */ |
| |
| /*! |
| \fn QString QBluetoothServiceInfo::serviceDescription() const |
| |
| This is a convenience function. It is equivalent to calling |
| attribute(QBluetoothServiceInfo::ServiceDescription).toString(). |
| |
| Returns the service description in the primary language. |
| |
| \sa setServiceDescription(), attribute() |
| */ |
| |
| /*! |
| \fn void QBluetoothServiceInfo::setServiceProvider(const QString &provider) |
| |
| This is a convenience function. It is equivalent to calling |
| setAttribute(QBluetoothServiceInfo::ServiceProvider, provider). |
| |
| Sets the service provider in the primary language to \a provider. |
| |
| \sa serviceProvider(), setAttribute() |
| */ |
| |
| /*! |
| \fn QString QBluetoothServiceInfo::serviceProvider() const |
| |
| This is a convenience function. It is equivalent to calling |
| attribute(QBluetoothServiceInfo::ServiceProvider).toString(). |
| |
| Returns the service provider in the primary language. |
| |
| \sa setServiceProvider(), attribute() |
| */ |
| |
| /*! |
| \fn void QBluetoothServiceInfo::setServiceAvailability(quint8 availability) |
| |
| This is a convenience function. It is equivalent to calling |
| setAttribute(QBluetoothServiceInfo::ServiceAvailability, availability). |
| |
| Sets the availabiltiy of the service to \a availability. |
| |
| \sa serviceAvailability(), setAttribute() |
| */ |
| |
| /*! |
| \fn quint8 QBluetoothServiceInfo::serviceAvailability() const |
| |
| This is a convenience function. It is equivalent to calling |
| attribute(QBluetoothServiceInfo::ServiceAvailability).toUInt(). |
| |
| Returns the availability of the service. |
| |
| \sa setServiceAvailability(), attribute() |
| */ |
| |
| /*! |
| \fn void QBluetoothServiceInfo::setServiceUuid(const QBluetoothUuid &uuid) |
| |
| This is a convenience function. It is equivalent to calling |
| setAttribute(QBluetoothServiceInfo::ServiceId, uuid). |
| |
| Sets the custom service UUID to \a uuid. This function should not be used |
| to set a standardized service UUID. |
| |
| \sa serviceUuid(), setAttribute() |
| */ |
| |
| /*! |
| \fn QBluetoothUuid QBluetoothServiceInfo::serviceUuid() const |
| |
| This is a convenience function. It is equivalent to calling |
| attribute(QBluetoothServiceInfo::ServiceId).value<QBluetoothUuid>(). |
| |
| Returns the custom UUID of the service. This UUID may be null. |
| UUIDs based on \l{https://bluetooth.org}{Bluetooth SIG standards} |
| should be retrieved via \l serviceClassUuids(). |
| |
| \sa setServiceUuid(), attribute() |
| */ |
| |
| /*! |
| Construct a new invalid QBluetoothServiceInfo; |
| */ |
| QBluetoothServiceInfo::QBluetoothServiceInfo() |
| : d_ptr(QSharedPointer<QBluetoothServiceInfoPrivate>::create()) |
| { |
| qRegisterMetaType<QBluetoothServiceInfo>(); |
| } |
| |
| /*! |
| Construct a new QBluetoothServiceInfo that is a copy of \a other. |
| |
| The two copies continue to share the same underlying data which does not detach |
| upon write. |
| */ |
| QBluetoothServiceInfo::QBluetoothServiceInfo(const QBluetoothServiceInfo &other) |
| : d_ptr(other.d_ptr) |
| { |
| } |
| |
| /*! |
| Destroys the QBluetoothServiceInfo object. |
| */ |
| QBluetoothServiceInfo::~QBluetoothServiceInfo() |
| { |
| } |
| |
| /*! |
| Returns true if the QBluetoothServiceInfo object is valid, otherwise returns false. |
| |
| An invalid QBluetoothServiceInfo object will have no attributes. |
| */ |
| bool QBluetoothServiceInfo::isValid() const |
| { |
| return !d_ptr->attributes.isEmpty(); |
| } |
| |
| /*! |
| Returns true if the QBluetoothServiceInfo object is considered complete, otherwise returns false. |
| |
| A complete QBluetoothServiceInfo object contains a ProtocolDescriptorList attribute. |
| */ |
| bool QBluetoothServiceInfo::isComplete() const |
| { |
| return d_ptr->attributes.contains(ProtocolDescriptorList); |
| } |
| |
| /*! |
| Returns the address of the Bluetooth device that provides this service. |
| */ |
| QBluetoothDeviceInfo QBluetoothServiceInfo::device() const |
| { |
| return d_ptr->deviceInfo; |
| } |
| |
| /*! |
| Sets the Bluetooth device that provides this service to \a device. |
| */ |
| void QBluetoothServiceInfo::setDevice(const QBluetoothDeviceInfo &device) |
| { |
| d_ptr->deviceInfo = device; |
| } |
| |
| /*! |
| Sets the attribute identified by \a attributeId to \a value. |
| |
| If the service information is already registered with the platform's SDP database, |
| the database entry will not be updated until \l registerService() was called again. |
| |
| \note If an attribute expectes a byte-encoded value (e.g. Bluetooth HID services), |
| it should be set as QByteArray. |
| |
| \sa isRegistered(), registerService() |
| */ |
| void QBluetoothServiceInfo::setAttribute(quint16 attributeId, const QVariant &value) |
| { |
| d_ptr->attributes[attributeId] = value; |
| } |
| |
| /*! |
| Returns the value of the attribute \a attributeId. |
| */ |
| QVariant QBluetoothServiceInfo::attribute(quint16 attributeId) const |
| { |
| return d_ptr->attributes.value(attributeId); |
| } |
| |
| /*! |
| Returns a list of all attribute ids that the QBluetoothServiceInfo object has. |
| */ |
| QList<quint16> QBluetoothServiceInfo::attributes() const |
| { |
| return d_ptr->attributes.keys(); |
| } |
| |
| /*! |
| Returns true if the QBluetoothServiceInfo object contains the attribute \a attributeId, otherwise returns |
| false. |
| */ |
| bool QBluetoothServiceInfo::contains(quint16 attributeId) const |
| { |
| return d_ptr->attributes.contains(attributeId); |
| } |
| |
| /*! |
| Removes the attribute \a attributeId from the QBluetoothServiceInfo object. |
| |
| If the service information is already registered with the platforms SDP database, |
| the database entry will not be updated until \l registerService() was called again. |
| */ |
| void QBluetoothServiceInfo::removeAttribute(quint16 attributeId) |
| { |
| d_ptr->attributes.remove(attributeId); |
| } |
| |
| /*! |
| Returns the protocol that the QBluetoothServiceInfo object uses. |
| */ |
| QBluetoothServiceInfo::Protocol QBluetoothServiceInfo::socketProtocol() const |
| { |
| QBluetoothServiceInfo::Sequence parameters = protocolDescriptor(QBluetoothUuid::Rfcomm); |
| if (!parameters.isEmpty()) |
| return RfcommProtocol; |
| |
| parameters = protocolDescriptor(QBluetoothUuid::L2cap); |
| if (!parameters.isEmpty()) |
| return L2capProtocol; |
| |
| return UnknownProtocol; |
| } |
| |
| /*! |
| This is a convenience function. Returns the protocol/service multiplexer for services which |
| support the L2CAP protocol, otherwise returns -1. |
| |
| This function is equivalent to extracting the information from |
| QBluetoothServiceInfo::Sequence returned by |
| QBluetoothServiceInfo::attribute(QBluetoothServiceInfo::ProtocolDescriptorList). |
| */ |
| int QBluetoothServiceInfo::protocolServiceMultiplexer() const |
| { |
| QBluetoothServiceInfo::Sequence parameters = protocolDescriptor(QBluetoothUuid::L2cap); |
| |
| if (parameters.isEmpty()) |
| return -1; |
| else if (parameters.count() == 1) |
| return 0; |
| else |
| return parameters.at(1).toUInt(); |
| } |
| |
| /*! |
| This is a convenience function. Returns the server channel for services which support the |
| RFCOMM protocol, otherwise returns -1. |
| |
| This function is equivalent to extracting the information from |
| QBluetoothServiceInfo::Sequence returned by |
| QBluetoothServiceInfo::attribute(QBluetootherServiceInfo::ProtocolDescriptorList). |
| */ |
| int QBluetoothServiceInfo::serverChannel() const |
| { |
| return d_ptr->serverChannel(); |
| } |
| |
| /*! |
| Returns the protocol parameters as a QBluetoothServiceInfo::Sequence for protocol \a protocol. |
| |
| An empty QBluetoothServiceInfo::Sequence is returned if \a protocol is not supported. |
| */ |
| QBluetoothServiceInfo::Sequence QBluetoothServiceInfo::protocolDescriptor(QBluetoothUuid::ProtocolUuid protocol) const |
| { |
| return d_ptr->protocolDescriptor(protocol); |
| } |
| |
| /*! |
| Returns a list of UUIDs describing the service classes that this service conforms to. |
| |
| This is a convenience function. It is equivalent to calling |
| attribute(QBluetoothServiceInfo::ServiceClassIds).value<QBluetoothServiceInfo::Sequence>() |
| and subsequently iterating over its QBluetoothUuid entries. |
| |
| \sa attribute() |
| */ |
| QList<QBluetoothUuid> QBluetoothServiceInfo::serviceClassUuids() const |
| { |
| QList<QBluetoothUuid> results; |
| |
| const QVariant var = attribute(QBluetoothServiceInfo::ServiceClassIds); |
| if (!var.isValid()) |
| return results; |
| |
| const QBluetoothServiceInfo::Sequence seq = var.value<QBluetoothServiceInfo::Sequence>(); |
| for (int i = 0; i < seq.count(); i++) |
| results.append(seq.at(i).value<QBluetoothUuid>()); |
| |
| return results; |
| } |
| |
| /*! |
| Makes a copy of the \a other and assigns it to this QBluetoothServiceInfo object. |
| The two copies continue to share the same service and registration details. |
| */ |
| QBluetoothServiceInfo &QBluetoothServiceInfo::operator=(const QBluetoothServiceInfo &other) |
| { |
| d_ptr = other.d_ptr; |
| |
| return *this; |
| } |
| |
| static void dumpAttributeVariant(QDebug dbg, const QVariant &var, const QString& indent) |
| { |
| switch (int(var.type())) { |
| case QMetaType::Void: |
| dbg << QString::asprintf("%sEmpty\n", indent.toUtf8().constData()); |
| break; |
| case QMetaType::UChar: |
| dbg << QString::asprintf("%suchar %u\n", indent.toUtf8().constData(), var.toUInt()); |
| break; |
| case QMetaType::UShort: |
| dbg << QString::asprintf("%sushort %u\n", indent.toUtf8().constData(), var.toUInt()); |
| break; |
| case QMetaType::UInt: |
| dbg << QString::asprintf("%suint %u\n", indent.toUtf8().constData(), var.toUInt()); |
| break; |
| case QMetaType::Char: |
| dbg << QString::asprintf("%schar %d\n", indent.toUtf8().constData(), var.toInt()); |
| break; |
| case QMetaType::Short: |
| dbg << QString::asprintf("%sshort %d\n", indent.toUtf8().constData(), var.toInt()); |
| break; |
| case QMetaType::Int: |
| dbg << QString::asprintf("%sint %d\n", indent.toUtf8().constData(), var.toInt()); |
| break; |
| case QMetaType::QString: |
| dbg << QString::asprintf("%sstring %s\n", indent.toUtf8().constData(), |
| var.toString().toUtf8().constData()); |
| break; |
| case QMetaType::QByteArray: |
| dbg << QString::asprintf("%sbytearray %s\n", indent.toUtf8().constData(), |
| var.toByteArray().toHex().constData()); |
| break; |
| case QMetaType::Bool: |
| dbg << QString::asprintf("%sbool %d\n", indent.toUtf8().constData(), var.toBool()); |
| break; |
| case QMetaType::QUrl: |
| dbg << QString::asprintf("%surl %s\n", indent.toUtf8().constData(), |
| var.toUrl().toString().toUtf8().constData()); |
| break; |
| case QVariant::UserType: |
| if (var.userType() == qMetaTypeId<QBluetoothUuid>()) { |
| QBluetoothUuid uuid = var.value<QBluetoothUuid>(); |
| switch (uuid.minimumSize()) { |
| case 0: |
| dbg << QString::asprintf("%suuid NULL\n", indent.toUtf8().constData()); |
| break; |
| case 2: |
| dbg << QString::asprintf("%suuid2 %04x\n", indent.toUtf8().constData(), |
| uuid.toUInt16()); |
| break; |
| case 4: |
| dbg << QString::asprintf("%suuid %08x\n", indent.toUtf8().constData(), |
| uuid.toUInt32()); |
| break; |
| case 16: |
| dbg << QString::asprintf("%suuid %s\n", |
| indent.toUtf8().constData(), |
| QByteArray(reinterpret_cast<const char *>(uuid.toUInt128().data), 16).toHex().constData()); |
| break; |
| default: |
| dbg << QString::asprintf("%suuid ???\n", indent.toUtf8().constData()); |
| } |
| } else if (var.userType() == qMetaTypeId<QBluetoothServiceInfo::Sequence>()) { |
| dbg << QString::asprintf("%sSequence\n", indent.toUtf8().constData()); |
| const QBluetoothServiceInfo::Sequence *sequence = static_cast<const QBluetoothServiceInfo::Sequence *>(var.data()); |
| for (const QVariant &v : *sequence) |
| dumpAttributeVariant(dbg, v, indent + QLatin1Char('\t')); |
| } else if (var.userType() == qMetaTypeId<QBluetoothServiceInfo::Alternative>()) { |
| dbg << QString::asprintf("%sAlternative\n", indent.toUtf8().constData()); |
| const QBluetoothServiceInfo::Alternative *alternative = static_cast<const QBluetoothServiceInfo::Alternative *>(var.data()); |
| for (const QVariant &v : *alternative) |
| dumpAttributeVariant(dbg, v, indent + QLatin1Char('\t')); |
| } |
| break; |
| default: |
| dbg << QString::asprintf("%sunknown variant type %d\n", indent.toUtf8().constData(), |
| var.userType()); |
| } |
| } |
| |
| |
| QDebug operator<<(QDebug dbg, const QBluetoothServiceInfo &info) |
| { |
| QDebugStateSaver saver(dbg); |
| dbg.noquote() << "\n"; |
| const QList<quint16> attributes = info.attributes(); |
| for (quint16 id : attributes) { |
| dumpAttributeVariant(dbg, info.attribute(id), QStringLiteral("(%1)\t").arg(id)); |
| } |
| return dbg; |
| } |
| |
| QBluetoothServiceInfo::Sequence QBluetoothServiceInfoPrivate::protocolDescriptor(QBluetoothUuid::ProtocolUuid protocol) const |
| { |
| if (!attributes.contains(QBluetoothServiceInfo::ProtocolDescriptorList)) |
| return QBluetoothServiceInfo::Sequence(); |
| |
| const QBluetoothServiceInfo::Sequence sequence |
| = attributes.value(QBluetoothServiceInfo::ProtocolDescriptorList).value<QBluetoothServiceInfo::Sequence>(); |
| for (const QVariant &v : sequence) { |
| QBluetoothServiceInfo::Sequence parameters = v.value<QBluetoothServiceInfo::Sequence>(); |
| if (parameters.empty()) |
| continue; |
| if (parameters.at(0).userType() == qMetaTypeId<QBluetoothUuid>()) { |
| if (parameters.at(0).value<QBluetoothUuid>() == protocol) |
| return parameters; |
| } |
| } |
| |
| return QBluetoothServiceInfo::Sequence(); |
| } |
| |
| int QBluetoothServiceInfoPrivate::serverChannel() const |
| { |
| QBluetoothServiceInfo::Sequence parameters = protocolDescriptor(QBluetoothUuid::Rfcomm); |
| |
| if (parameters.isEmpty()) |
| return -1; |
| else if (parameters.count() == 1) |
| return 0; |
| else |
| return parameters.at(1).toUInt(); |
| } |
| |
| QT_END_NAMESPACE |