diff options
author | Oliver Wolff <oliver.wolff@qt.io> | 2019-03-14 14:39:02 +0100 |
---|---|---|
committer | Oliver Wolff <oliver.wolff@qt.io> | 2019-03-19 09:50:40 +0000 |
commit | 929d7446ead35b481fab8e5fef6cc889225f1143 (patch) | |
tree | 98eb110211bebf715a8812aa6fd3c9fa615149f8 /src | |
parent | ca0841c0d5f32baf6bc13c80eb801f24aa74cef1 (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>
Diffstat (limited to 'src')
-rw-r--r-- | src/bluetooth/qlowenergycontroller_winrt.cpp | 27 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_winrt_new.cpp | 27 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_winrt_new_p.h | 1 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_winrt_p.h | 1 |
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); |