summaryrefslogtreecommitdiffstats
path: root/src/bluetooth/qbluetoothdevicediscoveryagent_win.cpp
diff options
context:
space:
mode:
authorDenis Shienkov <denis.shienkov@gmail.com>2015-10-13 17:18:15 +0300
committerTimur Pocheptsov <timur.pocheptsov@theqtcompany.com>2015-10-14 08:26:40 +0000
commitc18927e87e65eefccd8cda9e6671d234e95d387c (patch)
treeb10d59ca000e674257927a548a5e378c08f2f1de /src/bluetooth/qbluetoothdevicediscoveryagent_win.cpp
parent797624ac0c5f0a7ee3dd0a938454d55cb8786373 (diff)
Windows: Refactor code related to discovering of a remote devices
* There is no need to do parallel scan for LE and Classic devices. It is enough to do it one after another by using one QFutureWatcher instead of two QFutureWatchers. * Now the qwinclassicbluetooth(h).cpp files are deleted from the 'windows' directory, and its related code is moved into QBluetoothDeviceDiscoveryAgentPrivate. Change-Id: I2acf102c3a8d313d078b351e9a2ce54ebca79dee Reviewed-by: Timur Pocheptsov <timur.pocheptsov@theqtcompany.com>
Diffstat (limited to 'src/bluetooth/qbluetoothdevicediscoveryagent_win.cpp')
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_win.cpp556
1 files changed, 327 insertions, 229 deletions
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_win.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_win.cpp
index 937bc2a4..78626e85 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_win.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_win.cpp
@@ -33,253 +33,414 @@
****************************************************************************/
#include "qbluetoothdevicediscoveryagent.h"
-#include "qbluetoothdevicediscoveryagent_p.h"
-#include "qbluetoothaddress.h"
#include "qbluetoothuuid.h"
+#include "qbluetoothdevicediscoveryagent_p.h"
#include "qbluetoothlocaldevice_p.h"
+#include <QtCore/qmutex.h>
+
+#include <qt_windows.h>
+#include <setupapi.h>
+#include <bluetoothapis.h>
+
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(QT_BT_WINDOWS)
-QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
- const QBluetoothAddress &deviceAdapter,
- QBluetoothDeviceDiscoveryAgent *parent)
- : inquiryType(QBluetoothDeviceDiscoveryAgent::GeneralUnlimitedInquiry)
- , lastError(QBluetoothDeviceDiscoveryAgent::NoError)
- , classicDiscoveryWatcher(0)
- , lowEnergyDiscoveryWatcher(0)
- , pendingCancel(false)
- , pendingStart(false)
- , isClassicActive(false)
- , isClassicValid(false)
- , isLowEnergyActive(false)
- , isLowEnergyValid(false)
- , q_ptr(parent)
-{
- initialize(deviceAdapter);
-}
+struct LeDeviceEntry {
+ LeDeviceEntry(const QString &path, const QBluetoothAddress &address)
+ : devicePath(path), deviceAddress(address) {}
+ QString devicePath;
+ QBluetoothAddress deviceAddress;
+};
-QBluetoothDeviceDiscoveryAgentPrivate::~QBluetoothDeviceDiscoveryAgentPrivate()
+Q_GLOBAL_STATIC(QList<LeDeviceEntry>, cachedLeDeviceEntries)
+Q_GLOBAL_STATIC(QMutex, cachedLeDeviceEntriesGuard)
+
+static QString devicePropertyString(
+ HDEVINFO hDeviceInfo,
+ const PSP_DEVINFO_DATA deviceInfoData,
+ DWORD registryProperty)
{
- if (isClassicActive || isLowEnergyActive)
- stop();
+ DWORD propertyRegDataType = 0;
+ DWORD propertyBufferSize = 0;
+ QByteArray propertyBuffer;
+
+ while (!::SetupDiGetDeviceRegistryProperty(
+ hDeviceInfo,
+ deviceInfoData,
+ registryProperty,
+ &propertyRegDataType,
+ propertyBuffer.isEmpty() ? NULL : reinterpret_cast<PBYTE>(propertyBuffer.data()),
+ propertyBuffer.size(),
+ &propertyBufferSize)) {
+
+ const DWORD error = ::GetLastError();
+ if (error != ERROR_INSUFFICIENT_BUFFER
+ || (propertyRegDataType != REG_SZ
+ && propertyRegDataType != REG_EXPAND_SZ)) {
+ return QString();
+ }
- if (classicDiscoveryWatcher)
- classicDiscoveryWatcher->waitForFinished();
+ // add +2 byte to allow to successfully convert to qstring
+ propertyBuffer.fill(0, propertyBufferSize + sizeof(wchar_t));
+ }
- if (lowEnergyDiscoveryWatcher)
- lowEnergyDiscoveryWatcher->waitForFinished();
+ return QString::fromWCharArray(reinterpret_cast<const wchar_t *>(
+ propertyBuffer.constData()));
}
-bool QBluetoothDeviceDiscoveryAgentPrivate::isActive() const
+static QString deviceName(HDEVINFO hDeviceInfo, PSP_DEVINFO_DATA deviceInfoData)
{
- if (pendingStart)
- return true;
- if (pendingCancel)
- return false;
-
- return isClassicActive || isLowEnergyActive;
+ return devicePropertyString(hDeviceInfo, deviceInfoData, SPDRP_FRIENDLYNAME);
}
-void QBluetoothDeviceDiscoveryAgentPrivate::start()
+static QString deviceSystemPath(const PSP_INTERFACE_DEVICE_DETAIL_DATA detailData)
{
- if (!isClassicValid && !isLowEnergyValid) {
- setError(ERROR_INVALID_HANDLE,
- QBluetoothDeviceDiscoveryAgent::tr("Passed address is not a local device."));
- return;
- }
-
- if (pendingCancel == true) {
- pendingStart = true;
- return;
- }
-
- discoveredDevices.clear();
-
- if (isClassicValid)
- startDiscoveryForFirstClassicDevice();
-
- if (isLowEnergyValid)
- startDiscoveryForLowEnergyDevices();
+ return QString::fromWCharArray(detailData->DevicePath);
}
-void QBluetoothDeviceDiscoveryAgentPrivate::stop()
+static QBluetoothAddress deviceAddress(const QString &devicePath)
{
- if (!isClassicActive && !isLowEnergyActive)
- return;
-
- pendingCancel = true;
- pendingStart = false;
+ const int firstbound = devicePath.indexOf(QStringLiteral("dev_"));
+ const int lastbound = devicePath.indexOf(QLatin1Char('#'), firstbound);
+ const QString hex = devicePath.mid(firstbound + 4, lastbound - firstbound - 4);
+ bool ok = false;
+ return QBluetoothAddress(hex.toULongLong(&ok, 16));
}
-void QBluetoothDeviceDiscoveryAgentPrivate::classicDeviceDiscovered()
+static QBluetoothDeviceInfo createClassicDeviceInfo(const BLUETOOTH_DEVICE_INFO &foundDevice)
{
- const WinClassicBluetooth::RemoteDeviceDiscoveryResult result =
- classicDiscoveryWatcher->result();
-
- if (isDiscoveredSuccessfully(result.error)) {
+ QBluetoothDeviceInfo deviceInfo(
+ QBluetoothAddress(foundDevice.Address.ullLong),
+ QString::fromWCharArray(foundDevice.szName),
+ foundDevice.ulClassofDevice);
- if (canBeCanceled()) {
- cancel();
- } else if (canBePendingStarted()) {
- prepareToPendingStart();
- } else {
- if (result.error != ERROR_NO_MORE_ITEMS) {
- acceptDiscoveredClassicDevice(result.device);
- startDiscoveryForNextClassicDevice(result.hSearch);
- return;
- }
- }
+ if (foundDevice.fRemembered)
+ deviceInfo.setCached(true);
+ return deviceInfo;
+}
+static QBluetoothDeviceInfo findFirstClassicDevice(
+ int *systemErrorCode, HBLUETOOTH_DEVICE_FIND *searchHandle)
+{
+ BLUETOOTH_DEVICE_SEARCH_PARAMS searchParams;
+ ::ZeroMemory(&searchParams, sizeof(searchParams));
+ searchParams.dwSize = sizeof(searchParams);
+ searchParams.cTimeoutMultiplier = 10; // 12.8 sec
+ searchParams.fIssueInquiry = TRUE;
+ searchParams.fReturnAuthenticated = TRUE;
+ searchParams.fReturnConnected = TRUE;
+ searchParams.fReturnRemembered = TRUE;
+ searchParams.fReturnUnknown = TRUE;
+ searchParams.hRadio = NULL;
+
+ BLUETOOTH_DEVICE_INFO deviceInfo;
+ ::ZeroMemory(&deviceInfo, sizeof(deviceInfo));
+ deviceInfo.dwSize = sizeof(deviceInfo);
+
+ const HBLUETOOTH_DEVICE_FIND hFind = ::BluetoothFindFirstDevice(
+ &searchParams, &deviceInfo);
+
+ QBluetoothDeviceInfo foundDevice;
+ if (hFind) {
+ *searchHandle = hFind;
+ *systemErrorCode = NO_ERROR;
+ foundDevice = createClassicDeviceInfo(deviceInfo);
} else {
- drop(result.error);
+ *systemErrorCode = ::GetLastError();
}
- completeClassicDiscovery(result.hSearch);
+ return foundDevice;
}
-void QBluetoothDeviceDiscoveryAgentPrivate::lowEnergyDeviceDiscovered()
+static QBluetoothDeviceInfo findNextClassicDevice(
+ int *systemErrorCode, HBLUETOOTH_DEVICE_FIND searchHandle)
{
- const WinLowEnergyBluetooth::DeviceDiscoveryResult result =
- lowEnergyDiscoveryWatcher->result();
-
- if (isDiscoveredSuccessfully(result.error)) {
-
- if (canBeCanceled()) {
- cancel();
- } else if (canBePendingStarted()) {
- prepareToPendingStart();
- } else {
- foreach (const WinLowEnergyBluetooth::DeviceInfo &deviceInfo, result.devices)
- acceptDiscoveredLowEnergyDevice(deviceInfo);
- }
+ BLUETOOTH_DEVICE_INFO deviceInfo;
+ ::ZeroMemory(&deviceInfo, sizeof(deviceInfo));
+ deviceInfo.dwSize = sizeof(deviceInfo);
+ QBluetoothDeviceInfo foundDevice;
+ if (!::BluetoothFindNextDevice(searchHandle, &deviceInfo)) {
+ *systemErrorCode = ::GetLastError();
} else {
- drop(result.error);
+ *systemErrorCode = NO_ERROR;
+ foundDevice = createClassicDeviceInfo(deviceInfo);
}
- completeLowEnergyDiscovery();
+ return foundDevice;
}
-void QBluetoothDeviceDiscoveryAgentPrivate::initialize(
- const QBluetoothAddress &deviceAdapter)
+static void closeClassicSearch(HBLUETOOTH_DEVICE_FIND *searchHandle)
{
- isClassicValid = isClassicAdapterValid(deviceAdapter);
- isLowEnergyValid = isLowEnergyAdapterValid(deviceAdapter);
+ if (searchHandle && *searchHandle) {
+ ::BluetoothFindDeviceClose(*searchHandle);
+ *searchHandle = 0;
+ }
}
-bool QBluetoothDeviceDiscoveryAgentPrivate::isClassicAdapterValid(
- const QBluetoothAddress &deviceAdapter)
+static QList<QBluetoothDeviceInfo> enumerateLeDevices(
+ int *systemErrorCode)
{
- foreach (const QBluetoothHostInfo &adapterInfo, QBluetoothLocalDevicePrivate::localAdapters()) {
- if (deviceAdapter == QBluetoothAddress()
- || deviceAdapter == adapterInfo.address()) {
- return true;
- }
+ const QUuid deviceInterfaceGuid("781aee18-7733-4ce4-add0-91f41c67b592");
+ const HDEVINFO hDeviceInfo = ::SetupDiGetClassDevs(
+ reinterpret_cast<const GUID *>(&deviceInterfaceGuid),
+ NULL,
+ 0,
+ DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
+
+ if (hDeviceInfo == INVALID_HANDLE_VALUE) {
+ *systemErrorCode = ::GetLastError();
+ return QList<QBluetoothDeviceInfo>();
}
- qCWarning(QT_BT_WINDOWS) << "No matching for classic local radio:" << deviceAdapter;
- return false;
-}
+ QList<QBluetoothDeviceInfo> foundDevices;
+ DWORD index = 0;
-void QBluetoothDeviceDiscoveryAgentPrivate::startDiscoveryForFirstClassicDevice()
-{
- isClassicActive = true;
+ QList<LeDeviceEntry> cachedEntries;
- if (!classicDiscoveryWatcher) {
- classicDiscoveryWatcher = new QFutureWatcher<
- WinClassicBluetooth::RemoteDeviceDiscoveryResult>(this);
- connect(classicDiscoveryWatcher, &QFutureWatcher<WinClassicBluetooth::RemoteDeviceDiscoveryResult>::finished,
- this, &QBluetoothDeviceDiscoveryAgentPrivate::classicDeviceDiscovered);
+ forever {
+ SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
+ ::ZeroMemory(&deviceInterfaceData, sizeof(deviceInterfaceData));
+ deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
+
+ if (!::SetupDiEnumDeviceInterfaces(
+ hDeviceInfo,
+ NULL,
+ reinterpret_cast<const GUID *>(&deviceInterfaceGuid),
+ index++,
+ &deviceInterfaceData)) {
+ *systemErrorCode = ::GetLastError();
+ break;
+ }
+
+ DWORD deviceInterfaceDetailDataSize = 0;
+ if (!::SetupDiGetDeviceInterfaceDetail(
+ hDeviceInfo,
+ &deviceInterfaceData,
+ NULL,
+ deviceInterfaceDetailDataSize,
+ &deviceInterfaceDetailDataSize,
+ NULL)) {
+ if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+ *systemErrorCode = ::GetLastError();
+ break;
+ }
+ }
+
+ SP_DEVINFO_DATA deviceInfoData;
+ ::ZeroMemory(&deviceInfoData, sizeof(deviceInfoData));
+ deviceInfoData.cbSize = sizeof(deviceInfoData);
+
+ QByteArray deviceInterfaceDetailDataBuffer(
+ deviceInterfaceDetailDataSize, 0);
+
+ PSP_INTERFACE_DEVICE_DETAIL_DATA deviceInterfaceDetailData =
+ reinterpret_cast<PSP_INTERFACE_DEVICE_DETAIL_DATA>
+ (deviceInterfaceDetailDataBuffer.data());
+
+ deviceInterfaceDetailData->cbSize =
+ sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
+
+ if (!::SetupDiGetDeviceInterfaceDetail(
+ hDeviceInfo,
+ &deviceInterfaceData,
+ deviceInterfaceDetailData,
+ deviceInterfaceDetailDataBuffer.size(),
+ &deviceInterfaceDetailDataSize,
+ &deviceInfoData)) {
+ *systemErrorCode = ::GetLastError();
+ break;
+ }
+
+ const QString systemPath = deviceSystemPath(deviceInterfaceDetailData);
+ const QBluetoothAddress address = deviceAddress(systemPath);
+ if (address.isNull())
+ continue;
+ const QString name = deviceName(hDeviceInfo, &deviceInfoData);
+
+ QBluetoothDeviceInfo deviceInfo(address, name, QBluetoothDeviceInfo::MiscellaneousDevice);
+ deviceInfo.setCoreConfigurations(QBluetoothDeviceInfo::LowEnergyCoreConfiguration);
+ deviceInfo.setCached(true);
+
+ foundDevices << deviceInfo;
+ cachedEntries << LeDeviceEntry(systemPath, address);
}
- const QFuture<WinClassicBluetooth::RemoteDeviceDiscoveryResult> future =
- QtConcurrent::run(WinClassicBluetooth::startDiscoveryOfFirstRemoteDevice);
- classicDiscoveryWatcher->setFuture(future);
+ QMutexLocker locker(cachedLeDeviceEntriesGuard());
+ cachedLeDeviceEntries()->swap(cachedEntries);
+
+ ::SetupDiDestroyDeviceInfoList(hDeviceInfo);
+ return foundDevices;
}
-void QBluetoothDeviceDiscoveryAgentPrivate::startDiscoveryForNextClassicDevice(
- HBLUETOOTH_DEVICE_FIND hSearch)
+QString QBluetoothDeviceDiscoveryAgentPrivate::discoveredLeDeviceSystemPath(
+ const QBluetoothAddress &deviceAddress)
{
- Q_ASSERT(classicDiscoveryWatcher);
-
- const QFuture<WinClassicBluetooth::RemoteDeviceDiscoveryResult> future =
- QtConcurrent::run(WinClassicBluetooth::startDiscoveryOfNextRemoteDevice, hSearch);
- classicDiscoveryWatcher->setFuture(future);
+ // update LE devices cache
+ int dummyErrorCode;
+ enumerateLeDevices(&dummyErrorCode);
+
+ QMutexLocker locker(cachedLeDeviceEntriesGuard());
+ for (int i = 0; i < cachedLeDeviceEntries()->count(); ++i) {
+ if (cachedLeDeviceEntries()->at(i).deviceAddress == deviceAddress)
+ return cachedLeDeviceEntries()->at(i).devicePath;
+ }
+ return QString();
}
-void QBluetoothDeviceDiscoveryAgentPrivate::completeClassicDiscovery(
- HBLUETOOTH_DEVICE_FIND hSearch)
+QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
+ const QBluetoothAddress &deviceAdapter,
+ QBluetoothDeviceDiscoveryAgent *parent)
+ : inquiryType(QBluetoothDeviceDiscoveryAgent::GeneralUnlimitedInquiry)
+ , lastError(QBluetoothDeviceDiscoveryAgent::NoError)
+ , adapterAddress(deviceAdapter)
+ , pendingCancel(false)
+ , pendingStart(false)
+ , scanWatcher(Q_NULLPTR)
+ , active(false)
+ , systemErrorCode(NO_ERROR)
+ , searchHandle(0)
+ , q_ptr(parent)
{
- WinClassicBluetooth::cancelRemoteDevicesDiscovery(hSearch);
- isClassicActive = false;
- finalize();
+ scanWatcher = new QFutureWatcher<QBluetoothDeviceInfo>(this);
+ connect(scanWatcher, &QFutureWatcher<QBluetoothDeviceInfo>::finished,
+ this, &QBluetoothDeviceDiscoveryAgentPrivate::taskFinished);
}
-void QBluetoothDeviceDiscoveryAgentPrivate::acceptDiscoveredClassicDevice(
- const BLUETOOTH_DEVICE_INFO &device)
+QBluetoothDeviceDiscoveryAgentPrivate::~QBluetoothDeviceDiscoveryAgentPrivate()
{
- QBluetoothDeviceInfo deviceInfo(
- QBluetoothAddress(device.Address.ullLong),
- QString::fromWCharArray(device.szName),
- device.ulClassofDevice);
-
- if (device.fRemembered)
- deviceInfo.setCached(true);
+ if (active)
+ stop();
- processDuplicates(deviceInfo);
+ scanWatcher->waitForFinished();
}
-bool QBluetoothDeviceDiscoveryAgentPrivate::isLowEnergyAdapterValid(
- const QBluetoothAddress &deviceAdapter)
+bool QBluetoothDeviceDiscoveryAgentPrivate::isActive() const
{
- Q_UNUSED(deviceAdapter);
-
- // We can not detect an address of local BLE adapter,
- // but we can detect that some BLE adapter is present.
- return WinLowEnergyBluetooth::hasLocalRadio();
+ if (pendingStart)
+ return true;
+ if (pendingCancel)
+ return false;
+ return active;
}
-void QBluetoothDeviceDiscoveryAgentPrivate::startDiscoveryForLowEnergyDevices()
+void QBluetoothDeviceDiscoveryAgentPrivate::start()
{
- isLowEnergyActive = true;
+ if (pendingCancel == true) {
+ pendingStart = true;
+ return;
+ }
+
+ const QList<QBluetoothHostInfo> foundLocalAdapters =
+ QBluetoothLocalDevicePrivate::localAdapters();
- if (!lowEnergyDiscoveryWatcher) {
- lowEnergyDiscoveryWatcher = new QFutureWatcher<
- WinLowEnergyBluetooth::DeviceDiscoveryResult>(this);
- connect(lowEnergyDiscoveryWatcher, &QFutureWatcher<WinLowEnergyBluetooth::DeviceDiscoveryResult>::finished,
- this, &QBluetoothDeviceDiscoveryAgentPrivate::lowEnergyDeviceDiscovered);
+ Q_Q(QBluetoothDeviceDiscoveryAgent);
+
+ if (foundLocalAdapters.isEmpty()) {
+ qCWarning(QT_BT_WINDOWS) << "Device does not support Bluetooth";
+ lastError = QBluetoothDeviceDiscoveryAgent::InputOutputError;
+ errorString = QBluetoothDeviceDiscoveryAgent::tr("Device does not support Bluetooth");
+ emit q->error(lastError);
+ return;
+ }
+
+ // Check for the local adapter address.
+ bool foundLocalAdapter = false;
+ foreach (const QBluetoothHostInfo &adapterInfo, foundLocalAdapters) {
+ if (adapterAddress == QBluetoothAddress() || adapterAddress == adapterInfo.address()) {
+ foundLocalAdapter = true;
+ break;
+ }
}
- const QFuture<WinLowEnergyBluetooth::DeviceDiscoveryResult> future =
- QtConcurrent::run(WinLowEnergyBluetooth::startDiscoveryOfRemoteDevices);
- lowEnergyDiscoveryWatcher->setFuture(future);
+ if (!foundLocalAdapter) {
+ qCWarning(QT_BT_WINDOWS) << "Incorrect local adapter passed.";
+ lastError = QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError;
+ errorString = QBluetoothDeviceDiscoveryAgent::tr("Passed address is not a local device.");
+ emit q->error(lastError);
+ return;
+ }
+
+ discoveredDevices.clear();
+ active = true;
+
+ // Start scan for first classic device.
+ const QFuture<QBluetoothDeviceInfo> future = QtConcurrent::run(
+ findFirstClassicDevice, &systemErrorCode, &searchHandle);
+ scanWatcher->setFuture(future);
}
-void QBluetoothDeviceDiscoveryAgentPrivate::completeLowEnergyDiscovery()
+void QBluetoothDeviceDiscoveryAgentPrivate::stop()
{
- isLowEnergyActive = false;
- finalize();
+ if (!active)
+ return;
+
+ pendingCancel = true;
+ pendingStart = false;
}
-void QBluetoothDeviceDiscoveryAgentPrivate::acceptDiscoveredLowEnergyDevice(
- const WinLowEnergyBluetooth::DeviceInfo &device)
+void QBluetoothDeviceDiscoveryAgentPrivate::taskFinished()
{
- QBluetoothDeviceInfo deviceInfo(device.address, device.name, 0);
- deviceInfo.setCoreConfigurations(QBluetoothDeviceInfo::LowEnergyCoreConfiguration);
- deviceInfo.setCached(true);
+ Q_Q(QBluetoothDeviceDiscoveryAgent);
- processDuplicates(deviceInfo);
+ if (pendingCancel && !pendingStart) {
+ closeClassicSearch(&searchHandle);
+ active = false;
+ pendingCancel = false;
+ emit q->canceled();
+ } else if (pendingStart) {
+ closeClassicSearch(&searchHandle);
+ pendingStart = pendingCancel = false;
+ start();
+ } else {
+ if (systemErrorCode == ERROR_NO_MORE_ITEMS) {
+ closeClassicSearch(&searchHandle);
+ // Enumerate LE devices.
+ const QList<QBluetoothDeviceInfo> foundDevices =
+ enumerateLeDevices(&systemErrorCode);
+ if (systemErrorCode == ERROR_NO_MORE_ITEMS) {
+ foreach (const QBluetoothDeviceInfo &foundDevice, foundDevices)
+ processDiscoveredDevice(foundDevice);
+ active = false;
+ emit q->finished();
+ } else {
+ pendingStart = pendingCancel = false;
+ active = false;
+ lastError = (systemErrorCode == ERROR_INVALID_HANDLE) ?
+ QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError
+ : QBluetoothDeviceDiscoveryAgent::InputOutputError;
+ errorString = qt_error_string(systemErrorCode);
+ emit q->error(lastError);
+ }
+ } else if (systemErrorCode == NO_ERROR) {
+ processDiscoveredDevice(scanWatcher->result());
+ // Start scan for next classic device.
+ const QFuture<QBluetoothDeviceInfo> future = QtConcurrent::run(
+ findNextClassicDevice, &systemErrorCode, searchHandle);
+ scanWatcher->setFuture(future);
+ } else {
+ closeClassicSearch(&searchHandle);
+ pendingStart = pendingCancel = false;
+ active = false;
+ lastError = (systemErrorCode == ERROR_INVALID_HANDLE) ?
+ QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError
+ : QBluetoothDeviceDiscoveryAgent::InputOutputError;
+ errorString = qt_error_string(systemErrorCode);
+ emit q->error(lastError);
+ }
+ }
}
-void QBluetoothDeviceDiscoveryAgentPrivate::processDuplicates(
+void QBluetoothDeviceDiscoveryAgentPrivate::processDiscoveredDevice(
const QBluetoothDeviceInfo &foundDevice)
{
Q_Q(QBluetoothDeviceDiscoveryAgent);
for (int i = 0; i < discoveredDevices.size(); i++) {
QBluetoothDeviceInfo mergedDevice = discoveredDevices[i];
+
if (mergedDevice.address() == foundDevice.address()) {
if (mergedDevice == foundDevice
|| mergedDevice.coreConfigurations() == foundDevice.coreConfigurations()) {
@@ -313,67 +474,4 @@ void QBluetoothDeviceDiscoveryAgentPrivate::processDuplicates(
emit q->deviceDiscovered(foundDevice);
}
-void QBluetoothDeviceDiscoveryAgentPrivate::setError(DWORD error, const QString &str)
-{
- Q_Q(QBluetoothDeviceDiscoveryAgent);
-
- lastError = (error == ERROR_INVALID_HANDLE) ?
- QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError
- : QBluetoothDeviceDiscoveryAgent::InputOutputError;
- errorString = str.isEmpty() ? qt_error_string(error) : str;
- emit q->error(lastError);
-}
-
-bool QBluetoothDeviceDiscoveryAgentPrivate::isDiscoveredSuccessfully(
- int systemError) const
-{
- return systemError == NO_ERROR || systemError == ERROR_NO_MORE_ITEMS;
-}
-
-bool QBluetoothDeviceDiscoveryAgentPrivate::canBeCanceled() const
-{
- if (isClassicActive || isLowEnergyActive)
- return false;
- return pendingCancel && !pendingStart;
-}
-
-void QBluetoothDeviceDiscoveryAgentPrivate::cancel()
-{
- Q_Q(QBluetoothDeviceDiscoveryAgent);
-
- emit q->canceled();
- pendingCancel = false;
-}
-
-bool QBluetoothDeviceDiscoveryAgentPrivate::canBePendingStarted() const
-{
- if (isClassicActive || isLowEnergyActive)
- return false;
- return pendingStart;
-}
-
-void QBluetoothDeviceDiscoveryAgentPrivate::prepareToPendingStart()
-{
- pendingCancel = false;
- pendingStart = false;
- start();
-}
-
-void QBluetoothDeviceDiscoveryAgentPrivate::finalize()
-{
- Q_Q(QBluetoothDeviceDiscoveryAgent);
-
- if (isClassicActive || isLowEnergyActive)
- return;
-
- emit q->finished();
-}
-
-void QBluetoothDeviceDiscoveryAgentPrivate::drop(int systemError)
-{
- setError(systemError);
- pendingCancel = false;
- pendingStart = false;
-}
-
QT_END_NAMESPACE