summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Wolff <oliver.wolff@qt.io>2016-08-03 12:45:27 +0200
committerOliver Wolff <oliver.wolff@qt.io>2016-08-04 10:01:52 +0000
commit1e31c7028208bd267dfd513b036b6a7a78118226 (patch)
tree88f7f1aadabdffaae83c440b8b2297102c21c6aa
parentcef1148c0e0852232b664afef1510e25aa9c1d55 (diff)
winrt: Implement LE device discovery timeout
Change-Id: If6ec32dc3105b3498eef8a20e8f464a85f1ee891 Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_p.h3
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp87
-rw-r--r--tests/auto/qbluetoothdevicediscoveryagent/tst_qbluetoothdevicediscoveryagent.cpp2
3 files changed, 87 insertions, 5 deletions
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_p.h b/src/bluetooth/qbluetoothdevicediscoveryagent_p.h
index 06cf29c2..44a067c5 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_p.h
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_p.h
@@ -162,10 +162,13 @@ private:
#ifdef QT_WINRT_BLUETOOTH
private slots:
void onListInitializationCompleted();
+ void onScanFinished();
+ void onScanCanceled();
private:
void disconnectAndClearWorker();
QPointer<QWinRTBluetoothDeviceDiscoveryWorker> worker;
+ QTimer *leScanTimer;
#endif
int lowEnergySearchTimeout;
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
index bfa39fc1..db1592b1 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
@@ -178,6 +178,8 @@ public:
~QWinRTBluetoothDeviceDiscoveryWorker()
{
+ if (leDeviceWatcher && leDeviceAddedToken.value)
+ leDeviceWatcher->remove_Added(leDeviceAddedToken);
}
private:
@@ -225,7 +227,7 @@ private:
if (initializedModes == BTAll) {
qCDebug(QT_BT_WINRT) << "All scans completed";
emit initializationCompleted();
- deleteLater();
+ setupLEDeviceWatcher();
}
}
@@ -271,14 +273,61 @@ private:
}
}
+ void setupLEDeviceWatcher()
+ {
+ HString deviceSelector;
+ ComPtr<IDeviceInformationStatics> deviceInformationStatics;
+ HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Devices_Enumeration_DeviceInformation).Get(), &deviceInformationStatics);
+ WARN_AND_RETURN_IF_FAILED("Could not obtain device information statics", return);
+ ComPtr<IBluetoothLEDeviceStatics> bluetoothLeDeviceStatics;
+ hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Devices_Bluetooth_BluetoothLEDevice).Get(), &bluetoothLeDeviceStatics);
+ WARN_AND_RETURN_IF_FAILED("Could not obtain bluetooth LE device statics", return);
+ hr = bluetoothLeDeviceStatics->GetDeviceSelector(deviceSelector.GetAddressOf());
+ WARN_AND_RETURN_IF_FAILED("Could not obtain device selector string", return);
+ hr = deviceInformationStatics->CreateWatcherAqsFilter(deviceSelector.Get(), &leDeviceWatcher);
+ WARN_AND_RETURN_IF_FAILED("Could not create le device watcher", return);
+ auto deviceAddedCallback =
+ Callback<ITypedEventHandler<DeviceWatcher*, DeviceInformation*>>([this](IDeviceWatcher *, IDeviceInformation *deviceInfo)
+ {
+ HString deviceId;
+ HRESULT hr;
+ hr = deviceInfo->get_Id(deviceId.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+ const QBluetoothDeviceInfo info = bluetoothInfoFromLeDeviceId(deviceId.Get());
+ if (!info.isValid())
+ return S_OK;
+
+ qCDebug(QT_BT_WINRT) << "Found device" << info.name() << info.address();
+ emit leDeviceFound(info);
+ return S_OK;
+ });
+ hr = leDeviceWatcher->add_Added(deviceAddedCallback.Get(), &leDeviceAddedToken);
+ WARN_AND_RETURN_IF_FAILED("Could not add \"device added\" callback", return);
+ }
+
+public slots:
+ void onLeTimeout()
+ {
+ if (initializedModes == BTAll)
+ emit scanFinished();
+ else
+ emit scanCanceled();
+ deleteLater();
+ }
+
Q_SIGNALS:
void initializationCompleted();
+ void leDeviceFound(const QBluetoothDeviceInfo &info);
+ void scanFinished();
+ void scanCanceled();
public:
QVector<QBluetoothDeviceInfo> deviceList;
private:
quint8 initializedModes;
+ ComPtr<IDeviceWatcher> leDeviceWatcher;
+ EventRegistrationToken leDeviceAddedToken;
};
QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
@@ -287,8 +336,9 @@ QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
: inquiryType(QBluetoothDeviceDiscoveryAgent::GeneralUnlimitedInquiry),
lastError(QBluetoothDeviceDiscoveryAgent::NoError),
- lowEnergySearchTimeout(-1), // TODO
- q_ptr(parent)
+ lowEnergySearchTimeout(25000),
+ q_ptr(parent),
+ leScanTimer(0)
{
Q_UNUSED(deviceAdapter);
}
@@ -310,6 +360,7 @@ QBluetoothDeviceDiscoveryAgent::DiscoveryMethods QBluetoothDeviceDiscoveryAgent:
void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods)
{
+ Q_Q(QBluetoothDeviceDiscoveryAgent);
if (worker)
return;
@@ -321,7 +372,24 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent
discoveredDevices.clear();
connect(worker, &QWinRTBluetoothDeviceDiscoveryWorker::initializationCompleted,
this, &QBluetoothDeviceDiscoveryAgentPrivate::onListInitializationCompleted);
+ connect(worker, &QWinRTBluetoothDeviceDiscoveryWorker::scanFinished,
+ this, &QBluetoothDeviceDiscoveryAgentPrivate::onScanFinished);
+ connect(worker, &QWinRTBluetoothDeviceDiscoveryWorker::scanCanceled,
+ this, &QBluetoothDeviceDiscoveryAgentPrivate::onScanCanceled);
+ connect(worker, &QWinRTBluetoothDeviceDiscoveryWorker::leDeviceFound,
+ q, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered);
worker->start();
+
+ if (lowEnergySearchTimeout > 0) { // otherwise no timeout and stop() required
+ if (!leScanTimer) {
+ leScanTimer = new QTimer(this);
+ leScanTimer->setSingleShot(true);
+ connect(leScanTimer, &QTimer::timeout,
+ worker, &QWinRTBluetoothDeviceDiscoveryWorker::onLeTimeout);
+ }
+ leScanTimer->setInterval(lowEnergySearchTimeout);
+ leScanTimer->start();
+ }
}
void QBluetoothDeviceDiscoveryAgentPrivate::stop()
@@ -339,11 +407,22 @@ void QBluetoothDeviceDiscoveryAgentPrivate::onListInitializationCompleted()
discoveredDevices = worker->deviceList.toList();
foreach (const QBluetoothDeviceInfo &info, worker->deviceList)
emit q->deviceDiscovered(info);
+}
+void QBluetoothDeviceDiscoveryAgentPrivate::onScanFinished()
+{
+ Q_Q(QBluetoothDeviceDiscoveryAgent);
disconnectAndClearWorker();
emit q->finished();
}
+void QBluetoothDeviceDiscoveryAgentPrivate::onScanCanceled()
+{
+ Q_Q(QBluetoothDeviceDiscoveryAgent);
+ disconnectAndClearWorker();
+ emit q->canceled();
+}
+
void QBluetoothDeviceDiscoveryAgentPrivate::disconnectAndClearWorker()
{
if (!worker)
@@ -351,7 +430,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::disconnectAndClearWorker()
disconnect(worker, &QWinRTBluetoothDeviceDiscoveryWorker::initializationCompleted,
this, &QBluetoothDeviceDiscoveryAgentPrivate::onListInitializationCompleted);
- // worker deletion is done by the worker itself (see comment in start())
+ worker->deleteLater();
worker.clear();
}
diff --git a/tests/auto/qbluetoothdevicediscoveryagent/tst_qbluetoothdevicediscoveryagent.cpp b/tests/auto/qbluetoothdevicediscoveryagent/tst_qbluetoothdevicediscoveryagent.cpp
index f8ab72f7..efc4d8a6 100644
--- a/tests/auto/qbluetoothdevicediscoveryagent/tst_qbluetoothdevicediscoveryagent.cpp
+++ b/tests/auto/qbluetoothdevicediscoveryagent/tst_qbluetoothdevicediscoveryagent.cpp
@@ -489,7 +489,7 @@ void tst_QBluetoothDeviceDiscoveryAgent::tst_discoveryTimeout()
QBluetoothDeviceDiscoveryAgent agent;
// check default values
-#if defined(Q_OS_OSX) || defined(Q_OS_IOS) || defined(Q_OS_ANDROID)
+#if defined(Q_OS_OSX) || defined(Q_OS_IOS) || defined(Q_OS_ANDROID) || defined(Q_OS_WINRT)
QCOMPARE(agent.lowEnergyDiscoveryTimeout(), 25000);
agent.setLowEnergyDiscoveryTimeout(-1); // negative ignored
QCOMPARE(agent.lowEnergyDiscoveryTimeout(), 25000);