summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Wolff <oliver.wolff@qt.io>2019-03-14 14:39:02 +0100
committerOliver Wolff <oliver.wolff@qt.io>2019-03-19 09:50:40 +0000
commit929d7446ead35b481fab8e5fef6cc889225f1143 (patch)
tree98eb110211bebf715a8812aa6fd3c9fa615149f8
parentca0841c0d5f32baf6bc13c80eb801f24aa74cef1 (diff)
winrt: Handle device disconnection properly
"ConnectedState" is not the only valid "connected" state for QLowEnergyController. "disconnected" also has to be emitted, if we were in DiscoveredState and co. Additionally every value change callback has to be removed and mDevice has to be closed in disconnectFromDevice to make Windows disconnect from the device as there is no specific API to do that manually. Task-number: QTBUG-74394 Change-Id: Ic025b2c668f887db6c4a631cd8fee26a457bc279 Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r--src/bluetooth/qlowenergycontroller_winrt.cpp27
-rw-r--r--src/bluetooth/qlowenergycontroller_winrt_new.cpp27
-rw-r--r--src/bluetooth/qlowenergycontroller_winrt_new_p.h1
-rw-r--r--src/bluetooth/qlowenergycontroller_winrt_p.h1
4 files changed, 42 insertions, 14 deletions
diff --git a/src/bluetooth/qlowenergycontroller_winrt.cpp b/src/bluetooth/qlowenergycontroller_winrt.cpp
index ed279ffa..5347902f 100644
--- a/src/bluetooth/qlowenergycontroller_winrt.cpp
+++ b/src/bluetooth/qlowenergycontroller_winrt.cpp
@@ -291,9 +291,7 @@ QLowEnergyControllerPrivateWinRT::~QLowEnergyControllerPrivateWinRT()
if (mDevice && mStatusChangedToken.value)
mDevice->remove_ConnectionStatusChanged(mStatusChangedToken);
- qCDebug(QT_BT_WINRT) << "Unregistering " << mValueChangedTokens.count() << " value change tokens";
- for (const ValueChangedEntry &entry : qAsConst(mValueChangedTokens))
- entry.characteristic->remove_ValueChanged(entry.token);
+ unregisterFromValueChanges();
}
void QLowEnergyControllerPrivateWinRT::init()
@@ -340,7 +338,7 @@ void QLowEnergyControllerPrivateWinRT::connectToDevice()
&& status == BluetoothConnectionStatus::BluetoothConnectionStatus_Connected) {
setState(QLowEnergyController::ConnectedState);
emit q->connected();
- } else if (state == QLowEnergyController::ConnectedState
+ } else if (state != QLowEnergyController::UnconnectedState
&& status == BluetoothConnectionStatus::BluetoothConnectionStatus_Disconnected) {
setError(QLowEnergyController::RemoteHostClosedError);
setState(QLowEnergyController::UnconnectedState);
@@ -438,9 +436,13 @@ void QLowEnergyControllerPrivateWinRT::disconnectFromDevice()
Q_Q(QLowEnergyController);
setState(QLowEnergyController::UnconnectedState);
emit q->disconnected();
- if (mDevice && mStatusChangedToken.value) {
- mDevice->remove_ConnectionStatusChanged(mStatusChangedToken);
- mStatusChangedToken.value = 0;
+ unregisterFromValueChanges();
+ if (mDevice) {
+ if (mStatusChangedToken.value) {
+ mDevice->remove_ConnectionStatusChanged(mStatusChangedToken);
+ mStatusChangedToken.value = 0;
+ }
+ mDevice = nullptr;
}
}
@@ -502,6 +504,17 @@ void QLowEnergyControllerPrivateWinRT::registerForValueChanges(const QBluetoothU
<< serviceUuid << "registered for value changes";
}
+void QLowEnergyControllerPrivateWinRT::unregisterFromValueChanges()
+{
+ qCDebug(QT_BT_WINRT) << "Unregistering " << mValueChangedTokens.count() << " value change tokens";
+ HRESULT hr;
+ for (const ValueChangedEntry &entry : qAsConst(mValueChangedTokens)) {
+ hr = entry.characteristic->remove_ValueChanged(entry.token);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+ mValueChangedTokens.clear();
+}
+
void QLowEnergyControllerPrivateWinRT::obtainIncludedServices(QSharedPointer<QLowEnergyServicePrivate> servicePointer,
ComPtr<IGattDeviceService> service)
{
diff --git a/src/bluetooth/qlowenergycontroller_winrt_new.cpp b/src/bluetooth/qlowenergycontroller_winrt_new.cpp
index 1f70807e..df00d4c8 100644
--- a/src/bluetooth/qlowenergycontroller_winrt_new.cpp
+++ b/src/bluetooth/qlowenergycontroller_winrt_new.cpp
@@ -345,9 +345,7 @@ QLowEnergyControllerPrivateWinRTNew::~QLowEnergyControllerPrivateWinRTNew()
if (mDevice && mStatusChangedToken.value)
mDevice->remove_ConnectionStatusChanged(mStatusChangedToken);
- qCDebug(QT_BT_WINRT) << "Unregistering " << mValueChangedTokens.count() << " value change tokens";
- for (const ValueChangedEntry &entry : qAsConst(mValueChangedTokens))
- entry.characteristic->remove_ValueChanged(entry.token);
+ unregisterFromValueChanges();
}
void QLowEnergyControllerPrivateWinRTNew::init()
@@ -397,7 +395,7 @@ void QLowEnergyControllerPrivateWinRTNew::connectToDevice()
&& status == BluetoothConnectionStatus::BluetoothConnectionStatus_Connected) {
setState(QLowEnergyController::ConnectedState);
emit q->connected();
- } else if (state == QLowEnergyController::ConnectedState
+ } else if (state != QLowEnergyController::UnconnectedState
&& status == BluetoothConnectionStatus::BluetoothConnectionStatus_Disconnected) {
setError(QLowEnergyController::RemoteHostClosedError);
setState(QLowEnergyController::UnconnectedState);
@@ -522,9 +520,13 @@ void QLowEnergyControllerPrivateWinRTNew::disconnectFromDevice()
Q_Q(QLowEnergyController);
setState(QLowEnergyController::UnconnectedState);
emit q->disconnected();
- if (mDevice && mStatusChangedToken.value) {
- mDevice->remove_ConnectionStatusChanged(mStatusChangedToken);
- mStatusChangedToken.value = 0;
+ unregisterFromValueChanges();
+ if (mDevice) {
+ if (mStatusChangedToken.value) {
+ mDevice->remove_ConnectionStatusChanged(mStatusChangedToken);
+ mStatusChangedToken.value = 0;
+ }
+ mDevice = nullptr;
}
}
@@ -591,6 +593,17 @@ void QLowEnergyControllerPrivateWinRTNew::registerForValueChanges(const QBluetoo
<< serviceUuid << "registered for value changes";
}
+void QLowEnergyControllerPrivateWinRTNew::unregisterFromValueChanges()
+{
+ qCDebug(QT_BT_WINRT) << "Unregistering " << mValueChangedTokens.count() << " value change tokens";
+ HRESULT hr;
+ for (const ValueChangedEntry &entry : qAsConst(mValueChangedTokens)) {
+ hr = entry.characteristic->remove_ValueChanged(entry.token);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+ mValueChangedTokens.clear();
+}
+
void QLowEnergyControllerPrivateWinRTNew::obtainIncludedServices(
QSharedPointer<QLowEnergyServicePrivate> servicePointer,
ComPtr<IGattDeviceService> service)
diff --git a/src/bluetooth/qlowenergycontroller_winrt_new_p.h b/src/bluetooth/qlowenergycontroller_winrt_new_p.h
index 716d2d07..b3990acd 100644
--- a/src/bluetooth/qlowenergycontroller_winrt_new_p.h
+++ b/src/bluetooth/qlowenergycontroller_winrt_new_p.h
@@ -140,6 +140,7 @@ private:
Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::IGattCharacteristic> getNativeCharacteristic(const QBluetoothUuid &serviceUuid, const QBluetoothUuid &charUuid);
void registerForValueChanges(const QBluetoothUuid &serviceUuid, const QBluetoothUuid &charUuid);
+ void unregisterFromValueChanges();
void obtainIncludedServices(QSharedPointer<QLowEnergyServicePrivate> servicePointer,
Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::IGattDeviceService> nativeService);
diff --git a/src/bluetooth/qlowenergycontroller_winrt_p.h b/src/bluetooth/qlowenergycontroller_winrt_p.h
index 783a71fa..da21353f 100644
--- a/src/bluetooth/qlowenergycontroller_winrt_p.h
+++ b/src/bluetooth/qlowenergycontroller_winrt_p.h
@@ -138,6 +138,7 @@ private:
Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::IGattCharacteristic> getNativeCharacteristic(const QBluetoothUuid &serviceUuid, const QBluetoothUuid &charUuid);
void registerForValueChanges(const QBluetoothUuid &serviceUuid, const QBluetoothUuid &charUuid);
+ void unregisterFromValueChanges();
void obtainIncludedServices(QSharedPointer<QLowEnergyServicePrivate> servicePointer,
Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::IGattDeviceService> nativeService);