1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2014 Denis Shienkov <denis.shienkov@gmail.com>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QBLUETOOTHDEVICEDISCOVERYAGENT_P_H
6#define QBLUETOOTHDEVICEDISCOVERYAGENT_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include "qbluetoothdevicediscoveryagent.h"
20#ifdef QT_ANDROID_BLUETOOTH
21#include <QtCore/QJniObject>
22#include "android/devicediscoverybroadcastreceiver_p.h"
23#include <QtCore/QTimer>
24#endif
25
26#ifdef Q_OS_DARWIN
27#include "darwin/btdelegates_p.h"
28#include "darwin/btraii_p.h"
29#endif // Q_OS_DARWIN
30
31#include <QtCore/QVariantMap>
32
33#include <QtBluetooth/QBluetoothAddress>
34#include <QtBluetooth/QBluetoothLocalDevice>
35
36#if QT_CONFIG(bluez)
37#include "bluez/bluez5_helper_p.h"
38
39class OrgBluezManagerInterface;
40class OrgBluezAdapterInterface;
41class OrgFreedesktopDBusObjectManagerInterface;
42class OrgFreedesktopDBusPropertiesInterface;
43class OrgBluezAdapter1Interface;
44class OrgBluezDevice1Interface;
45
46QT_BEGIN_NAMESPACE
47class QDBusVariant;
48QT_END_NAMESPACE
49#endif
50
51#ifdef QT_WINRT_BLUETOOTH
52#include <QtCore/QPointer>
53#include <QtCore/QTimer>
54
55using ManufacturerData = QHash<quint16, QByteArray>;
56using ServiceData = QHash<QBluetoothUuid, QByteArray>;
57QT_DECL_METATYPE_EXTERN(ManufacturerData, Q_BLUETOOTH_EXPORT)
58QT_DECL_METATYPE_EXTERN(ServiceData, Q_BLUETOOTH_EXPORT)
59#endif
60
61QT_BEGIN_NAMESPACE
62
63#ifdef QT_WINRT_BLUETOOTH
64class QWinRTBluetoothDeviceDiscoveryWorker;
65#endif
66
67class QBluetoothDeviceDiscoveryAgentPrivate
68#if defined(QT_ANDROID_BLUETOOTH) || defined(QT_WINRT_BLUETOOTH) \
69 || defined(Q_OS_DARWIN)
70 : public QObject
71#if defined(Q_OS_MACOS)
72 , public DarwinBluetooth::DeviceInquiryDelegate
73#endif // Q_OS_MACOS
74{
75 Q_OBJECT
76#else // BlueZ
77{
78#endif
79 Q_DECLARE_PUBLIC(QBluetoothDeviceDiscoveryAgent)
80public:
81 QBluetoothDeviceDiscoveryAgentPrivate(
82 const QBluetoothAddress &deviceAdapter,
83 QBluetoothDeviceDiscoveryAgent *parent);
84 ~QBluetoothDeviceDiscoveryAgentPrivate();
85
86 void start(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods methods);
87 void stop();
88 bool isActive() const;
89
90#if QT_CONFIG(bluez)
91 void _q_InterfacesAdded(const QDBusObjectPath &object_path,
92 InterfaceList interfaces_and_properties);
93 void _q_discoveryFinished();
94 void _q_discoveryInterrupted(const QString &path);
95 void _q_PropertiesChanged(const QString &interface,
96 const QString &path,
97 const QVariantMap &changed_properties,
98 const QStringList &invalidated_properties);
99#endif
100
101private:
102 QList<QBluetoothDeviceInfo> discoveredDevices;
103
104 QBluetoothDeviceDiscoveryAgent::Error lastError = QBluetoothDeviceDiscoveryAgent::NoError;
105 QString errorString;
106 QBluetoothAddress adapterAddress;
107
108#ifdef QT_ANDROID_BLUETOOTH
109private slots:
110 void processSdpDiscoveryFinished();
111 void processDiscoveredDevices(const QBluetoothDeviceInfo &info, bool isLeResult);
112 friend void QtBluetoothLE_leScanResult(JNIEnv *, jobject, jlong, jobject);
113 void stopLowEnergyScan();
114
115private:
116 void startLowEnergyScan();
117 void classicDiscoveryStartFail();
118 bool setErrorIfPowerOff();
119
120 DeviceDiscoveryBroadcastReceiver *receiver = nullptr;
121 short m_active;
122 QJniObject adapter;
123 QJniObject leScanner;
124 QTimer *leScanTimeout = nullptr;
125 QTimer *deviceDiscoveryStartTimeout = nullptr;
126 short deviceDiscoveryStartAttemptsLeft;
127
128 bool pendingCancel = false;
129 bool pendingStart = false;
130#elif QT_CONFIG(bluez)
131 bool pendingCancel = false;
132 bool pendingStart = false;
133 OrgFreedesktopDBusObjectManagerInterface *manager = nullptr;
134 OrgBluezAdapter1Interface *adapter = nullptr;
135 QTimer *discoveryTimer = nullptr;
136 QList<OrgFreedesktopDBusPropertiesInterface *> propertyMonitors;
137
138 void deviceFound(const QString &devicePath, const QVariantMap &properties);
139
140 QMap<QString, QVariantMap> devicesProperties;
141#endif
142
143#ifdef QT_WINRT_BLUETOOTH
144private slots:
145 void registerDevice(const QBluetoothDeviceInfo &info);
146 void updateDeviceData(const QBluetoothAddress &address, QBluetoothDeviceInfo::Fields fields,
147 qint16 rssi, ManufacturerData manufacturerData, ServiceData serviceData);
148 void onErrorOccured(QBluetoothDeviceDiscoveryAgent::Error e);
149 void onScanFinished();
150
151private:
152 void disconnectAndClearWorker();
153 std::shared_ptr<QWinRTBluetoothDeviceDiscoveryWorker> worker = nullptr;
154#endif
155
156#ifdef Q_OS_DARWIN
157
158 void startLE();
159
160#ifdef Q_OS_MACOS
161
162 void startClassic();
163
164 // Classic (IOBluetooth) inquiry delegate's methods:
165 void inquiryFinished() override;
166 void error(IOReturn error) override;
167 void classicDeviceFound(void *device) override;
168 // Classic (IOBluetooth) errors:
169 void setError(IOReturn error, const QString &text = QString());
170
171#endif // Q_OS_MACOS
172
173 // LE scan delegates (CoreBluetooth, all Darwin OSes):
174 void LEinquiryFinished();
175 void LEinquiryError(QBluetoothDeviceDiscoveryAgent::Error error);
176 void LEnotSupported();
177
178 // LE errors:
179 void setError(QBluetoothDeviceDiscoveryAgent::Error,
180 const QString &text = QString());
181
182 // Both LE and Classic devices go there:
183 void deviceFound(const QBluetoothDeviceInfo &newDeviceInfo);
184
185 enum AgentState {
186 NonActive,
187 ClassicScan, // macOS (IOBluetooth) only
188 LEScan
189 } agentState;
190
191 bool startPending = false;
192 bool stopPending = false;
193
194#ifdef Q_OS_MACOS
195
196 DarwinBluetooth::ScopedPointer controller;
197 DarwinBluetooth::ScopedPointer inquiry;
198
199#endif // Q_OS_MACOS
200
201 DarwinBluetooth::ScopedPointer inquiryLE;
202
203#endif // Q_OS_DARWIN
204
205 int lowEnergySearchTimeout = 40000;
206 QBluetoothDeviceDiscoveryAgent::DiscoveryMethods requestedMethods;
207 QBluetoothDeviceDiscoveryAgent *q_ptr;
208};
209
210QT_END_NAMESPACE
211
212#endif
213

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