Source code

Revision control

Copy as Markdown

// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2014 Denis Shienkov <denis.shienkov@gmail.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QBLUETOOTHDEVICEDISCOVERYAGENT_P_H
#define QBLUETOOTHDEVICEDISCOVERYAGENT_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "qbluetoothdevicediscoveryagent.h"
#ifdef QT_ANDROID_BLUETOOTH
#include <QtCore/QJniObject>
#include "android/devicediscoverybroadcastreceiver_p.h"
#include <QtCore/QTimer>
#endif
#ifdef Q_OS_DARWIN
#include "darwin/btdelegates_p.h"
#include "darwin/btraii_p.h"
#endif // Q_OS_DARWIN
#include <QtCore/QVariantMap>
#include <QtBluetooth/QBluetoothAddress>
#include <QtBluetooth/QBluetoothLocalDevice>
#if QT_CONFIG(bluez)
#include "bluez/bluez5_helper_p.h"
namespace QtBluetoothPrivate {
class OrgBluezManagerInterface;
class OrgBluezAdapterInterface;
class OrgFreedesktopDBusObjectManagerInterface;
class OrgFreedesktopDBusPropertiesInterface;
class OrgBluezAdapter1Interface;
class OrgBluezDevice1Interface;
} // namespace QtBluetoothPrivate
QT_BEGIN_NAMESPACE
class QDBusVariant;
QT_END_NAMESPACE
#endif
#ifdef QT_WINRT_BLUETOOTH
#include <QtCore/QPointer>
#include <QtCore/QTimer>
using ManufacturerData = QHash<quint16, QByteArray>;
using ServiceData = QHash<QBluetoothUuid, QByteArray>;
QT_DECL_METATYPE_EXTERN(ManufacturerData, Q_BLUETOOTH_EXPORT)
QT_DECL_METATYPE_EXTERN(ServiceData, Q_BLUETOOTH_EXPORT)
#endif
#ifdef QT_HARMONY_BLUETOOTH
#include <QtBluetooth/private/qohosbluetoothdevicediscovery_p.h>
#endif
QT_BEGIN_NAMESPACE
#ifdef QT_WINRT_BLUETOOTH
class QWinRTBluetoothDeviceDiscoveryWorker;
#endif
class QBluetoothDeviceDiscoveryAgentPrivate
#if defined(QT_ANDROID_BLUETOOTH) || defined(QT_WINRT_BLUETOOTH) \
|| defined(Q_OS_DARWIN) || defined(QT_HARMONY_BLUETOOTH)
: public QObject
#if defined(Q_OS_MACOS)
, public DarwinBluetooth::DeviceInquiryDelegate
#endif // Q_OS_MACOS
{
Q_OBJECT
#else // BlueZ
{
#endif
Q_DECLARE_PUBLIC(QBluetoothDeviceDiscoveryAgent)
public:
QBluetoothDeviceDiscoveryAgentPrivate(
const QBluetoothAddress &deviceAdapter,
QBluetoothDeviceDiscoveryAgent *parent);
~QBluetoothDeviceDiscoveryAgentPrivate();
void start(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods methods);
void stop();
bool isActive() const;
#if QT_CONFIG(bluez)
void _q_InterfacesAdded(const QDBusObjectPath &object_path,
InterfaceList interfaces_and_properties);
void _q_discoveryFinished();
void _q_discoveryInterrupted(const QString &path);
void _q_PropertiesChanged(const QString &interface,
const QString &path,
const QVariantMap &changed_properties,
const QStringList &invalidated_properties);
#endif
private:
QList<QBluetoothDeviceInfo> discoveredDevices;
QBluetoothDeviceDiscoveryAgent::Error lastError = QBluetoothDeviceDiscoveryAgent::NoError;
QString errorString;
QBluetoothAddress adapterAddress;
#ifdef QT_ANDROID_BLUETOOTH
private slots:
void processSdpDiscoveryFinished();
void processDiscoveredDevices(const QBluetoothDeviceInfo &info, bool isLeResult);
friend void QtBluetoothLE_leScanResult(JNIEnv *, jobject, jlong, jobject);
void stopLowEnergyScan();
private:
void startLowEnergyScan();
void processLeDiscoveryFinished(int epoch);
void classicDiscoveryStartFail();
bool setErrorIfPowerOff();
DeviceDiscoveryBroadcastReceiver *receiver = nullptr;
short m_active;
QJniObject adapter;
QJniObject leScanner;
QTimer *leScanTimeout = nullptr;
QTimer *deviceDiscoveryStartTimeout = nullptr;
short deviceDiscoveryStartAttemptsLeft;
int leScanEpoch = 0;
bool pendingCancel = false;
bool pendingStart = false;
#elif QT_CONFIG(bluez)
bool pendingCancel = false;
bool pendingStart = false;
QtBluetoothPrivate::OrgFreedesktopDBusObjectManagerInterface *manager = nullptr;
QtBluetoothPrivate::OrgBluezAdapter1Interface *adapter = nullptr;
QTimer *discoveryTimer = nullptr;
QList<QtBluetoothPrivate::OrgFreedesktopDBusPropertiesInterface *> propertyMonitors;
void deviceFound(const QString &devicePath, const QVariantMap &properties);
QMap<QString, QVariantMap> devicesProperties;
#endif
#ifdef QT_WINRT_BLUETOOTH
private slots:
void registerDevice(const QBluetoothDeviceInfo &info);
void updateDeviceData(const QBluetoothAddress &address, QBluetoothDeviceInfo::Fields fields,
qint16 rssi, ManufacturerData manufacturerData, ServiceData serviceData);
void onErrorOccured(QBluetoothDeviceDiscoveryAgent::Error e);
void onScanFinished();
private:
void disconnectAndClearWorker();
std::shared_ptr<QWinRTBluetoothDeviceDiscoveryWorker> worker = nullptr;
#endif
#ifdef Q_OS_DARWIN
void startLE();
#ifdef Q_OS_MACOS
void startClassic();
// Classic (IOBluetooth) inquiry delegate's methods:
void inquiryFinished() override;
void error(IOReturn error) override;
void classicDeviceFound(void *device) override;
// Classic (IOBluetooth) errors:
void setError(IOReturn error, const QString &text = QString());
#endif // Q_OS_MACOS
// LE scan delegates (CoreBluetooth, all Darwin OSes):
void LEinquiryFinished();
void LEinquiryError(QBluetoothDeviceDiscoveryAgent::Error error);
void LEnotSupported();
// LE errors:
void setError(QBluetoothDeviceDiscoveryAgent::Error,
const QString &text = QString());
// Both LE and Classic devices go there:
void deviceFound(const QBluetoothDeviceInfo &newDeviceInfo);
enum AgentState {
NonActive,
ClassicScan, // macOS (IOBluetooth) only
LEScan
} agentState;
bool startPending = false;
bool stopPending = false;
#ifdef Q_OS_MACOS
DarwinBluetooth::ScopedPointer controller;
DarwinBluetooth::ScopedPointer inquiry;
#endif // Q_OS_MACOS
DarwinBluetooth::ScopedPointer inquiryLE;
#endif // Q_OS_DARWIN
#ifdef QT_HARMONY_BLUETOOTH
enum class DiscoveryStopReason { Finished, BluetoothPoweredOff };
void reportDiscoveryStopped(DiscoveryStopReason reason);
void clearDiscoveryState();
void emitAsyncError();
void reportPairedDevicesAsync();
void reportDiscoveredDevices(const std::vector<QBluetoothDeviceInfo> &bluetoothDevicesInfos);
std::shared_ptr<QtOhosBluetooth::QOhosBluetoothDeviceDiscoveryAgentProxy> m_discoveryAgentProxy;
bool m_discoveryRequested = false;
bool m_pendingStart = false;
bool m_pendingCancel = false;
#endif
int lowEnergySearchTimeout = 40000;
QBluetoothDeviceDiscoveryAgent::DiscoveryMethods requestedMethods;
QBluetoothDeviceDiscoveryAgent *q_ptr;
};
QT_END_NAMESPACE
#endif