summaryrefslogtreecommitdiffstats
path: root/src/bluetooth/qbluetoothservicediscoveryagent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/bluetooth/qbluetoothservicediscoveryagent.cpp')
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent.cpp412
1 files changed, 412 insertions, 0 deletions
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent.cpp b/src/bluetooth/qbluetoothservicediscoveryagent.cpp
new file mode 100644
index 00000000..754e07e0
--- /dev/null
+++ b/src/bluetooth/qbluetoothservicediscoveryagent.cpp
@@ -0,0 +1,412 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbluetoothservicediscoveryagent.h"
+#include "qbluetoothservicediscoveryagent_p.h"
+
+#include "qbluetoothdevicediscoveryagent.h"
+
+/*!
+ \class QBluetoothServiceDiscoveryAgent
+ \brief The QBluetoothServiceDiscoveryAgent class provides an API for querying the services
+ provided by a Bluetooth device.
+
+ \ingroup connectivity-bluetooth
+ \inmodule QtConnectivity
+ \since 5.0
+
+ To query the services provided by all contactable Bluetooth devices create an instance of
+ QBluetoothServiceDiscoveryAgent, connect to either the serviceDiscovered() or finished()
+ signals and call start().
+
+ \snippet snippets/connectivity/servicediscovery.cpp Service discovery
+
+ By default a minimal service discovery is performed. In this mode the QBluetotohServiceInfo
+ objects returned are guaranteed to contain only device and service UUID information. Depending
+ on platform and device capabilities other service information may also be available. For most
+ use cases this is adequate as QBluetoothSocket::connectToService() will perform additional
+ discovery if required. If full service information is required pass \l FullDiscovery as the
+ discoveryMode parameter to start().
+*/
+
+/*!
+ \enum QBluetoothServiceDiscoveryAgent::Error
+
+ This enum describes errors that can occur during service discovery.
+
+ \value NoError No error.
+ \value DeviceDiscoveryError Error occurred during device discovery.
+ \value UnknownError An unidentified error occurred.
+*/
+
+/*!
+ \enum QBluetoothServiceDiscoveryAgent::DiscoveryMode
+
+ This enum describes the service discovery mode.
+
+ \value MinimalDiscovery Performs a minimal service discovery. The QBluetoothServiceInfo
+ objects returned may be incomplete and are only guaranteed to
+ contain device and service UUID information.
+ \value FullDiscovery Performs a full service discovery.
+*/
+
+/*!
+ \fn QBluetoothServiceDiscoveryAgent::serviceDiscovered(const QBluetoothServiceInfo &info)
+
+ This signal is emitted when the Bluetooth service described by \a info is discovered.
+*/
+
+/*!
+ \fn QBluetoothServiceDiscoveryAgent::finished()
+
+ This signal is emitted when Bluetooth service discovery completes.
+*/
+
+/*!
+ \fn void QBluetoothServiceDiscoveryAgent::error(QBluetoothServiceDiscoveryAgent::Error error)
+
+ This signal is emitted when an error occurs. The \a error parameter describes the error that
+ occurred.
+*/
+
+/*!
+ Constructs a new QBluetoothServiceDiscoveryAgent with \a parent. Services will be discovered on all
+ contactable devices.
+*/
+QBluetoothServiceDiscoveryAgent::QBluetoothServiceDiscoveryAgent(QObject *parent)
+: QObject(parent), d_ptr(new QBluetoothServiceDiscoveryAgentPrivate(QBluetoothAddress()))
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Constructs a new QBluetoothServiceDiscoveryAgent for \a remoteAddress and with \a parent.
+
+ If \a remoteAddress is null services will be discovred on all contactable Bluetooth
+ devices.
+*/
+QBluetoothServiceDiscoveryAgent::QBluetoothServiceDiscoveryAgent(const QBluetoothAddress &remoteAddress, QObject *parent)
+: QObject(parent), d_ptr(new QBluetoothServiceDiscoveryAgentPrivate(remoteAddress))
+{
+ d_ptr->q_ptr = this;
+ if (!remoteAddress.isNull()) {
+ d_ptr->singleDevice = true;
+ }
+}
+
+/*!
+
+ Destructor for QBluetoothServiceDiscoveryAgent
+
+*/
+
+QBluetoothServiceDiscoveryAgent::~QBluetoothServiceDiscoveryAgent()
+{
+ delete d_ptr;
+}
+
+/*!
+ Returns the list of all discovered services.
+*/
+QList<QBluetoothServiceInfo> QBluetoothServiceDiscoveryAgent::discoveredServices() const
+{
+ Q_D(const QBluetoothServiceDiscoveryAgent);
+
+ return d->discoveredServices;
+}
+/*!
+ Sets the UUID filter to \a uuids. Only services matching the UUIDs in \a uuids will be
+ returned.
+
+ An empty UUID list is equivalent to a list containing only QBluetoothUuid::PublicBrowseGroup.
+
+ \sa uuidFilter()
+*/
+void QBluetoothServiceDiscoveryAgent::setUuidFilter(const QList<QBluetoothUuid> &uuids)
+{
+ Q_D(QBluetoothServiceDiscoveryAgent);
+
+ d->uuidFilter = uuids;
+}
+
+/*!
+ This is an overloaded member function, provided for convenience.
+
+ Sets the UUID filter to a list containing the single element \a uuid.
+
+ \sa uuidFilter()
+*/
+void QBluetoothServiceDiscoveryAgent::setUuidFilter(const QBluetoothUuid &uuid)
+{
+ Q_D(QBluetoothServiceDiscoveryAgent);
+
+ d->uuidFilter.clear();
+ d->uuidFilter.append(uuid);
+}
+
+/*!
+ Returns the UUID filter.
+
+ \sa setUuidFilter()
+*/
+QList<QBluetoothUuid> QBluetoothServiceDiscoveryAgent::uuidFilter() const
+{
+ Q_D(const QBluetoothServiceDiscoveryAgent);
+
+ return d->uuidFilter;
+}
+
+/*!
+ Starts service discovery. \a mode specifies the type of service discovery to perform.
+
+ \sa DiscoveryMode
+*/
+void QBluetoothServiceDiscoveryAgent::start(DiscoveryMode mode)
+{
+ Q_D(QBluetoothServiceDiscoveryAgent);
+
+ if (d->discoveryState() == QBluetoothServiceDiscoveryAgentPrivate::Inactive) {
+ d->setDiscoveryMode(mode);
+ if (d->deviceAddress.isNull()) {
+ d->startDeviceDiscovery();
+ } else {
+ d->discoveredDevices << QBluetoothDeviceInfo(d->deviceAddress, QString(), 0);
+ d->startServiceDiscovery();
+ }
+ }
+}
+
+/*!
+ Stops service discovery.
+*/
+void QBluetoothServiceDiscoveryAgent::stop()
+{
+ Q_D(QBluetoothServiceDiscoveryAgent);
+
+ switch (d->discoveryState()) {
+ case QBluetoothServiceDiscoveryAgentPrivate::DeviceDiscovery:
+ d->stopDeviceDiscovery();
+ break;
+ case QBluetoothServiceDiscoveryAgentPrivate::ServiceDiscovery:
+ d->stopServiceDiscovery();
+ default:
+ ;
+ }
+
+ d->discoveredDevices.clear();
+}
+
+/*!
+ Clears the results of a previous service discovery.
+*/
+void QBluetoothServiceDiscoveryAgent::clear()
+{
+ Q_D(QBluetoothServiceDiscoveryAgent);
+
+ d->discoveredDevices.clear();
+ d->discoveredServices.clear();
+ d->uuidFilter.clear();
+}
+
+/*!
+ Returns true if service discovery is currently active, otherwise returns false.
+*/
+bool QBluetoothServiceDiscoveryAgent::isActive() const
+{
+ Q_D(const QBluetoothServiceDiscoveryAgent);
+
+ return d->state != QBluetoothServiceDiscoveryAgentPrivate::Inactive;
+}
+
+/*!
+ Returns the type of error that last occurred. If service discovery is done
+ on a signle address it will returns errors when trying to discover services
+ on that device. If the alternate constructor is used and devices are
+ discovered by a scan, then errors doing service discovery on individual
+ devices are not saved and no signals are emitted. In this case errors are
+ fairly normal since some devices may not respond to discovery or
+ may no longer be in range. As such errors are surpressed. If no services
+ are returned, it can be assumed no services could be discovered.
+
+*/
+QBluetoothServiceDiscoveryAgent::Error QBluetoothServiceDiscoveryAgent::error() const
+{
+ Q_D(const QBluetoothServiceDiscoveryAgent);
+
+ return d->error;
+}
+
+/*!
+ Returns a human-readable description of the last error that occurred when
+ doing service discovery on a single device.
+*/
+QString QBluetoothServiceDiscoveryAgent::errorString() const
+{
+ Q_D(const QBluetoothServiceDiscoveryAgent);
+ return d->errorString;
+}
+
+
+/*!
+ \fn QBluetoothServiceDiscoveryAgent::canceled()
+ Signals the cancellation of the service discovery.
+ */
+
+
+/*!
+ Starts device discovery.
+*/
+void QBluetoothServiceDiscoveryAgentPrivate::startDeviceDiscovery()
+{
+ Q_Q(QBluetoothServiceDiscoveryAgent);
+
+ if (!deviceDiscoveryAgent) {
+ deviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent;
+ QObject::connect(deviceDiscoveryAgent, SIGNAL(finished()),
+ q, SLOT(_q_deviceDiscoveryFinished()));
+ QObject::connect(deviceDiscoveryAgent, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),
+ q, SLOT(_q_deviceDiscovered(QBluetoothDeviceInfo)));
+
+ }
+
+ setDiscoveryState(DeviceDiscovery);
+
+ deviceDiscoveryAgent->start();
+}
+
+/*!
+ Stops device discovery.
+*/
+void QBluetoothServiceDiscoveryAgentPrivate::stopDeviceDiscovery()
+{
+ deviceDiscoveryAgent->stop();
+ delete deviceDiscoveryAgent;
+ deviceDiscoveryAgent = 0;
+
+ setDiscoveryState(Inactive);
+
+ Q_Q(QBluetoothServiceDiscoveryAgent);
+ emit q->canceled();
+}
+
+/*!
+ Called when device discovery finishes.
+*/
+void QBluetoothServiceDiscoveryAgentPrivate::_q_deviceDiscoveryFinished()
+{
+ if (deviceDiscoveryAgent->error() != QBluetoothDeviceDiscoveryAgent::NoError) {
+ error = QBluetoothServiceDiscoveryAgent::DeviceDiscoveryError;
+
+ setDiscoveryState(Inactive);
+ Q_Q(QBluetoothServiceDiscoveryAgent);
+ emit q->finished();
+ return;
+ }
+
+// discoveredDevices = deviceDiscoveryAgent->discoveredDevices();
+
+ delete deviceDiscoveryAgent;
+ deviceDiscoveryAgent = 0;
+
+ startServiceDiscovery();
+}
+
+void QBluetoothServiceDiscoveryAgentPrivate::_q_deviceDiscovered(const QBluetoothDeviceInfo &info)
+{
+ if(mode == QBluetoothServiceDiscoveryAgent::FullDiscovery) {
+ // look for duplicates, and cached entries
+ for(int i = 0; i < discoveredDevices.count(); i++){
+ if(discoveredDevices.at(i).address() == info.address()){
+ discoveredDevices.removeAt(i);
+ }
+ }
+ discoveredDevices.prepend(info);
+ }
+ else {
+ for(int i = 0; i < discoveredDevices.count(); i++){
+ if(discoveredDevices.at(i).address() == info.address()){
+ discoveredDevices.removeAt(i);
+ }
+ }
+ discoveredDevices.prepend(info);
+ }
+}
+
+/*!
+ Starts service discovery for the next device.
+*/
+void QBluetoothServiceDiscoveryAgentPrivate::startServiceDiscovery()
+{
+ Q_Q(QBluetoothServiceDiscoveryAgent);
+
+ setDiscoveryState(ServiceDiscovery);
+
+ if (discoveredDevices.isEmpty()) {
+ setDiscoveryState(Inactive);
+ emit q->finished();
+ return;
+ }
+
+ setDiscoveryState(ServiceDiscovery);
+ start(discoveredDevices.at(0).address());
+}
+
+/*!
+ Stops service discovery.
+*/
+void QBluetoothServiceDiscoveryAgentPrivate::stopServiceDiscovery()
+{
+ stop();
+
+ setDiscoveryState(Inactive);
+}
+
+void QBluetoothServiceDiscoveryAgentPrivate::_q_serviceDiscoveryFinished()
+{
+ if(!discoveredDevices.isEmpty()) {
+ discoveredDevices.removeFirst();
+ }
+
+ startServiceDiscovery();
+}
+
+
+#include "moc_qbluetoothservicediscoveryagent.cpp"