1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QBLUETOOTHSERVICEDISCOVERYAGENT_P_H
5#define QBLUETOOTHSERVICEDISCOVERYAGENT_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "qbluetoothaddress.h"
19#include "qbluetoothdeviceinfo.h"
20#include "qbluetoothserviceinfo.h"
21#include "qbluetoothservicediscoveryagent.h"
22
23#include <QStack>
24#include <QStringList>
25
26#if QT_CONFIG(bluez)
27class OrgBluezManagerInterface;
28class OrgBluezAdapterInterface;
29class OrgBluezDeviceInterface;
30class OrgFreedesktopDBusObjectManagerInterface;
31#include <QtCore/qprocess.h>
32
33QT_BEGIN_NAMESPACE
34class QDBusPendingCallWatcher;
35class QXmlStreamReader;
36QT_END_NAMESPACE
37#endif
38
39#ifdef QT_WINRT_BLUETOOTH
40#include <QtCore/QPointer>
41#endif
42
43#ifdef QT_OSX_BLUETOOTH
44#include "darwin/btdelegates_p.h"
45#include "darwin/btraii_p.h"
46#endif
47
48#ifdef QT_ANDROID_BLUETOOTH
49#include <QtCore/QJniObject>
50#include <QtBluetooth/QBluetoothLocalDevice>
51#endif
52
53QT_BEGIN_NAMESPACE
54
55class QBluetoothDeviceDiscoveryAgent;
56#ifdef QT_ANDROID_BLUETOOTH
57class ServiceDiscoveryBroadcastReceiver;
58class LocalDeviceBroadcastReceiver;
59#endif
60
61#ifdef QT_WINRT_BLUETOOTH
62class QWinRTBluetoothServiceDiscoveryWorker;
63#endif
64
65class QBluetoothServiceDiscoveryAgentPrivate
66#if defined(QT_WINRT_BLUETOOTH)
67 : public QObject
68{
69 Q_OBJECT
70#elif defined(QT_OSX_BLUETOOTH)
71 : public QObject, public DarwinBluetooth::SDPInquiryDelegate
72{
73#else
74{
75#endif
76 Q_DECLARE_PUBLIC(QBluetoothServiceDiscoveryAgent)
77
78public:
79 enum DiscoveryState {
80 Inactive,
81 DeviceDiscovery,
82 ServiceDiscovery,
83 };
84
85 QBluetoothServiceDiscoveryAgentPrivate(QBluetoothServiceDiscoveryAgent *qp,
86 const QBluetoothAddress &deviceAdapter);
87 ~QBluetoothServiceDiscoveryAgentPrivate();
88
89 void startDeviceDiscovery();
90 void stopDeviceDiscovery();
91 void startServiceDiscovery();
92 void stopServiceDiscovery();
93
94 void setDiscoveryState(DiscoveryState s) { state = s; }
95 inline DiscoveryState discoveryState() { return state; }
96
97 void setDiscoveryMode(QBluetoothServiceDiscoveryAgent::DiscoveryMode m) { mode = m; }
98 QBluetoothServiceDiscoveryAgent::DiscoveryMode DiscoveryMode() { return mode; }
99
100 void _q_deviceDiscoveryFinished();
101 void _q_deviceDiscovered(const QBluetoothDeviceInfo &info);
102 void _q_serviceDiscoveryFinished();
103 void _q_deviceDiscoveryError(QBluetoothDeviceDiscoveryAgent::Error);
104#if QT_CONFIG(bluez)
105 void _q_sdpScannerDone(int exitCode, QProcess::ExitStatus status);
106 void _q_finishSdpScan(QBluetoothServiceDiscoveryAgent::Error errorCode,
107 const QString &errorDescription,
108 const QStringList &xmlRecords);
109#endif
110#ifdef QT_ANDROID_BLUETOOTH
111 void _q_processFetchedUuids(const QBluetoothAddress &address, const QList<QBluetoothUuid> &uuids);
112
113 void populateDiscoveredServices(const QBluetoothDeviceInfo &remoteDevice,
114 const QList<QBluetoothUuid> &uuids);
115 void _q_fetchUuidsTimeout();
116 void _q_hostModeStateChanged(QBluetoothLocalDevice::HostMode state);
117#endif
118
119private:
120 void start(const QBluetoothAddress &address);
121 void stop();
122 bool isDuplicatedService(const QBluetoothServiceInfo &serviceInfo) const;
123
124#if QT_CONFIG(bluez)
125 void startBluez5(const QBluetoothAddress &address);
126 void runExternalSdpScan(const QBluetoothAddress &remoteAddress,
127 const QBluetoothAddress &localAddress);
128 void sdpScannerDone(int exitCode, QProcess::ExitStatus exitStatus);
129 QVariant readAttributeValue(QXmlStreamReader &xml);
130 QBluetoothServiceInfo parseServiceXml(const QString& xml);
131 void performMinimalServiceDiscovery(const QBluetoothAddress &deviceAddress);
132#endif
133
134public:
135 QBluetoothServiceDiscoveryAgent::Error error;
136 QString errorString;
137 QBluetoothAddress deviceAddress;
138 QList<QBluetoothServiceInfo> discoveredServices;
139 QList<QBluetoothDeviceInfo> discoveredDevices;
140 QBluetoothAddress m_deviceAdapterAddress;
141
142private:
143 DiscoveryState state;
144 QList<QBluetoothUuid> uuidFilter;
145
146 QBluetoothDeviceDiscoveryAgent *deviceDiscoveryAgent = nullptr;
147
148 QBluetoothServiceDiscoveryAgent::DiscoveryMode mode;
149
150 bool singleDevice;
151#if QT_CONFIG(bluez)
152 QString foundHostAdapterPath;
153 OrgFreedesktopDBusObjectManagerInterface *manager = nullptr;
154 QProcess *sdpScannerProcess = nullptr;
155#endif
156
157#ifdef QT_ANDROID_BLUETOOTH
158 ServiceDiscoveryBroadcastReceiver *receiver = nullptr;
159 LocalDeviceBroadcastReceiver *localDeviceReceiver = nullptr;
160
161 QJniObject btAdapter;
162 // The sdpCache caches service discovery results while it is running, and is
163 // cleared once finished. The cache is used as we may (or may not) get more accurate
164 // results after the first result. This temporary caching allows to send the
165 // serviceDiscovered() signal once per service and with the most accurate information.
166 // Partial cache clearing may occur already during the scan if the second (more accurate)
167 // scan result is received.
168 QMap<QBluetoothAddress,QPair<QBluetoothDeviceInfo,QList<QBluetoothUuid> > > sdpCache;
169#endif
170
171#ifdef QT_WINRT_BLUETOOTH
172private slots:
173 void processFoundService(quint64 deviceAddress, const QBluetoothServiceInfo &info);
174 void onScanFinished(quint64 deviceAddress);
175 void onError();
176
177private:
178 void releaseWorker();
179 QPointer<QWinRTBluetoothServiceDiscoveryWorker> worker;
180#endif
181
182#ifdef QT_OSX_BLUETOOTH
183 // SDPInquiryDelegate:
184 void SDPInquiryFinished(void *device) override;
185 void SDPInquiryError(void *device, IOReturn errorCode) override;
186
187 void performMinimalServiceDiscovery(const QBluetoothAddress &deviceAddress);
188 //void serviceDiscoveryFinished();
189
190 bool serviceHasMatchingUuid(const QBluetoothServiceInfo &serviceInfo) const;
191
192 DarwinBluetooth::ScopedPointer serviceInquiry;
193#endif // QT_OSX_BLUETOOTH
194
195protected:
196 QBluetoothServiceDiscoveryAgent *q_ptr;
197};
198
199QT_END_NAMESPACE
200
201#endif
202

source code of qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_p.h