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) |
27 | class OrgBluezManagerInterface; |
28 | class OrgBluezAdapterInterface; |
29 | class OrgBluezDeviceInterface; |
30 | class OrgFreedesktopDBusObjectManagerInterface; |
31 | #include <QtCore/qprocess.h> |
32 | |
33 | QT_BEGIN_NAMESPACE |
34 | class QDBusPendingCallWatcher; |
35 | class QXmlStreamReader; |
36 | QT_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 | |
53 | QT_BEGIN_NAMESPACE |
54 | |
55 | class QBluetoothDeviceDiscoveryAgent; |
56 | #ifdef QT_ANDROID_BLUETOOTH |
57 | class ServiceDiscoveryBroadcastReceiver; |
58 | class LocalDeviceBroadcastReceiver; |
59 | #endif |
60 | |
61 | #ifdef QT_WINRT_BLUETOOTH |
62 | class QWinRTBluetoothServiceDiscoveryWorker; |
63 | #endif |
64 | |
65 | class 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 | |
78 | public: |
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 | |
119 | private: |
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 | |
134 | public: |
135 | QBluetoothServiceDiscoveryAgent::Error error; |
136 | QString errorString; |
137 | QBluetoothAddress deviceAddress; |
138 | QList<QBluetoothServiceInfo> discoveredServices; |
139 | QList<QBluetoothDeviceInfo> discoveredDevices; |
140 | QBluetoothAddress m_deviceAdapterAddress; |
141 | |
142 | private: |
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 |
172 | private slots: |
173 | void processFoundService(quint64 deviceAddress, const QBluetoothServiceInfo &info); |
174 | void onScanFinished(quint64 deviceAddress); |
175 | void onError(); |
176 | |
177 | private: |
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 | |
195 | protected: |
196 | QBluetoothServiceDiscoveryAgent *q_ptr; |
197 | }; |
198 | |
199 | QT_END_NAMESPACE |
200 | |
201 | #endif |
202 | |