summaryrefslogtreecommitdiffstats
path: root/src/bluetooth/qlowenergycontroller_winrt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/bluetooth/qlowenergycontroller_winrt.cpp')
-rw-r--r--src/bluetooth/qlowenergycontroller_winrt.cpp105
1 files changed, 74 insertions, 31 deletions
diff --git a/src/bluetooth/qlowenergycontroller_winrt.cpp b/src/bluetooth/qlowenergycontroller_winrt.cpp
index 62b8a9d3..917f3790 100644
--- a/src/bluetooth/qlowenergycontroller_winrt.cpp
+++ b/src/bluetooth/qlowenergycontroller_winrt.cpp
@@ -37,12 +37,16 @@
**
****************************************************************************/
-#include "qlowenergycontroller_p.h"
+#include "qlowenergycontroller_winrt_p.h"
+
+#include <QtBluetooth/QLowEnergyCharacteristicData>
+#include <QtBluetooth/QLowEnergyDescriptorData>
#ifdef CLASSIC_APP_BUILD
#define Q_OS_WINRT
#endif
#include <QtCore/qfunctions_winrt.h>
+#include <QtCore/QtEndian>
#include <QtCore/QLoggingCategory>
#include <private/qeventdispatcher_winrt_p.h>
@@ -274,18 +278,15 @@ signals:
QLowEnergyHandle startHandle, QLowEnergyHandle endHandle);
};
-QLowEnergyControllerPrivate::QLowEnergyControllerPrivate()
- : QObject(),
- state(QLowEnergyController::UnconnectedState),
- error(QLowEnergyController::NoError)
+QLowEnergyControllerPrivateWinRT::QLowEnergyControllerPrivateWinRT()
+ : QLowEnergyControllerPrivate()
{
qCDebug(QT_BT_WINRT) << __FUNCTION__;
- qRegisterMetaType<QLowEnergyCharacteristic>();
- qRegisterMetaType<QLowEnergyDescriptor>();
+ registerQLowEnergyControllerMetaType();
}
-QLowEnergyControllerPrivate::~QLowEnergyControllerPrivate()
+QLowEnergyControllerPrivateWinRT::~QLowEnergyControllerPrivateWinRT()
{
if (mDevice && mStatusChangedToken.value)
mDevice->remove_ConnectionStatusChanged(mStatusChangedToken);
@@ -295,11 +296,11 @@ QLowEnergyControllerPrivate::~QLowEnergyControllerPrivate()
entry.characteristic->remove_ValueChanged(entry.token);
}
-void QLowEnergyControllerPrivate::init()
+void QLowEnergyControllerPrivateWinRT::init()
{
}
-void QLowEnergyControllerPrivate::connectToDevice()
+void QLowEnergyControllerPrivateWinRT::connectToDevice()
{
qCDebug(QT_BT_WINRT) << __FUNCTION__;
Q_Q(QLowEnergyController);
@@ -403,7 +404,17 @@ void QLowEnergyControllerPrivate::connectToDevice()
Q_ASSERT_SUCCEEDED(hr);
ComPtr<IGattReadResult> result;
hr = QWinRTFunctions::await(op, result.GetAddressOf());
- Q_ASSERT_SUCCEEDED(hr);
+ if (hr == E_INVALIDARG) {
+ // E_INVALIDARG happens when user tries to connect to a device that was paired
+ // before but is not available.
+ qCDebug(QT_BT_WINRT) << "Could not obtain characteristic read result that triggers"
+ "device connection. Is the device reachable?";
+ setError(QLowEnergyController::ConnectionError);
+ setState(QLowEnergyController::UnconnectedState);
+ return;
+ } else {
+ Q_ASSERT_SUCCEEDED(hr);
+ }
ComPtr<ABI::Windows::Storage::Streams::IBuffer> buffer;
hr = result->get_Value(&buffer);
Q_ASSERT_SUCCEEDED(hr);
@@ -417,7 +428,7 @@ void QLowEnergyControllerPrivate::connectToDevice()
}
}
-void QLowEnergyControllerPrivate::disconnectFromDevice()
+void QLowEnergyControllerPrivateWinRT::disconnectFromDevice()
{
qCDebug(QT_BT_WINRT) << __FUNCTION__;
Q_Q(QLowEnergyController);
@@ -429,7 +440,7 @@ void QLowEnergyControllerPrivate::disconnectFromDevice()
}
}
-ComPtr<IGattDeviceService> QLowEnergyControllerPrivate::getNativeService(const QBluetoothUuid &serviceUuid)
+ComPtr<IGattDeviceService> QLowEnergyControllerPrivateWinRT::getNativeService(const QBluetoothUuid &serviceUuid)
{
ComPtr<IGattDeviceService> deviceService;
HRESULT hr;
@@ -439,7 +450,7 @@ ComPtr<IGattDeviceService> QLowEnergyControllerPrivate::getNativeService(const Q
return deviceService;
}
-ComPtr<IGattCharacteristic> QLowEnergyControllerPrivate::getNativeCharacteristic(const QBluetoothUuid &serviceUuid, const QBluetoothUuid &charUuid)
+ComPtr<IGattCharacteristic> QLowEnergyControllerPrivateWinRT::getNativeCharacteristic(const QBluetoothUuid &serviceUuid, const QBluetoothUuid &charUuid)
{
ComPtr<IGattDeviceService> service = getNativeService(serviceUuid);
if (!service)
@@ -454,7 +465,7 @@ ComPtr<IGattCharacteristic> QLowEnergyControllerPrivate::getNativeCharacteristic
return characteristic;
}
-void QLowEnergyControllerPrivate::registerForValueChanges(const QBluetoothUuid &serviceUuid, const QBluetoothUuid &charUuid)
+void QLowEnergyControllerPrivateWinRT::registerForValueChanges(const QBluetoothUuid &serviceUuid, const QBluetoothUuid &charUuid)
{
qCDebug(QT_BT_WINRT) << "Registering characteristic" << charUuid << "in service"
<< serviceUuid << "for value changes";
@@ -487,7 +498,7 @@ void QLowEnergyControllerPrivate::registerForValueChanges(const QBluetoothUuid &
<< serviceUuid << "registered for value changes";
}
-void QLowEnergyControllerPrivate::obtainIncludedServices(QSharedPointer<QLowEnergyServicePrivate> servicePointer,
+void QLowEnergyControllerPrivateWinRT::obtainIncludedServices(QSharedPointer<QLowEnergyServicePrivate> servicePointer,
ComPtr<IGattDeviceService> service)
{
Q_Q(QLowEnergyController);
@@ -496,7 +507,9 @@ void QLowEnergyControllerPrivate::obtainIncludedServices(QSharedPointer<QLowEner
Q_ASSERT_SUCCEEDED(hr);
ComPtr<IVectorView<GattDeviceService *>> includedServices;
hr = service2->GetAllIncludedServices(&includedServices);
- Q_ASSERT_SUCCEEDED(hr);
+ // Some devices return ERROR_ACCESS_DISABLED_BY_POLICY
+ if (FAILED(hr))
+ return;
uint count;
hr = includedServices->get_Size(&count);
@@ -529,7 +542,7 @@ void QLowEnergyControllerPrivate::obtainIncludedServices(QSharedPointer<QLowEner
}
}
-void QLowEnergyControllerPrivate::discoverServices()
+void QLowEnergyControllerPrivateWinRT::discoverServices()
{
Q_Q(QLowEnergyController);
@@ -571,7 +584,7 @@ void QLowEnergyControllerPrivate::discoverServices()
emit q->discoveryFinished();
}
-void QLowEnergyControllerPrivate::discoverServiceDetails(const QBluetoothUuid &service)
+void QLowEnergyControllerPrivateWinRT::discoverServiceDetails(const QBluetoothUuid &service)
{
qCDebug(QT_BT_WINRT) << __FUNCTION__ << service;
if (!serviceList.contains(service)) {
@@ -595,7 +608,12 @@ void QLowEnergyControllerPrivate::discoverServiceDetails(const QBluetoothUuid &s
Q_ASSERT_SUCCEEDED(hr);
ComPtr<IVectorView<GattDeviceService *>> deviceServices;
hr = deviceService2->GetAllIncludedServices(&deviceServices);
- Q_ASSERT_SUCCEEDED(hr);
+ if (FAILED(hr)) { // ERROR_ACCESS_DISABLED_BY_POLICY
+ qCDebug(QT_BT_WINRT) << "Could not obtain included services list for" << service;
+ pointer->setError(QLowEnergyService::UnknownError);
+ pointer->setState(QLowEnergyService::InvalidService);
+ return;
+ }
uint serviceCount;
hr = deviceServices->get_Size(&serviceCount);
Q_ASSERT_SUCCEEDED(hr);
@@ -656,26 +674,33 @@ void QLowEnergyControllerPrivate::discoverServiceDetails(const QBluetoothUuid &s
thread->start();
}
-void QLowEnergyControllerPrivate::startAdvertising(const QLowEnergyAdvertisingParameters &, const QLowEnergyAdvertisingData &, const QLowEnergyAdvertisingData &)
+void QLowEnergyControllerPrivateWinRT::startAdvertising(const QLowEnergyAdvertisingParameters &, const QLowEnergyAdvertisingData &, const QLowEnergyAdvertisingData &)
{
+ setError(QLowEnergyController::AdvertisingError);
Q_UNIMPLEMENTED();
}
-void QLowEnergyControllerPrivate::stopAdvertising()
+void QLowEnergyControllerPrivateWinRT::stopAdvertising()
{
Q_UNIMPLEMENTED();
}
-void QLowEnergyControllerPrivate::requestConnectionUpdate(const QLowEnergyConnectionParameters &)
+void QLowEnergyControllerPrivateWinRT::requestConnectionUpdate(const QLowEnergyConnectionParameters &)
{
Q_UNIMPLEMENTED();
}
-void QLowEnergyControllerPrivate::readCharacteristic(const QSharedPointer<QLowEnergyServicePrivate> service,
+void QLowEnergyControllerPrivateWinRT::readCharacteristic(const QSharedPointer<QLowEnergyServicePrivate> service,
const QLowEnergyHandle charHandle)
{
qCDebug(QT_BT_WINRT) << __FUNCTION__ << service << charHandle;
Q_ASSERT(!service.isNull());
+ if (role == QLowEnergyController::PeripheralRole) {
+ service->setError(QLowEnergyService::CharacteristicReadError);
+ Q_UNIMPLEMENTED();
+ return;
+ }
+
if (!service->characteristicList.contains(charHandle)) {
qCDebug(QT_BT_WINRT) << charHandle << "could not be found in service" << service->uuid;
service->setError(QLowEnergyService::CharacteristicReadError);
@@ -729,12 +754,18 @@ void QLowEnergyControllerPrivate::readCharacteristic(const QSharedPointer<QLowEn
Q_ASSERT_SUCCEEDED(hr);
}
-void QLowEnergyControllerPrivate::readDescriptor(const QSharedPointer<QLowEnergyServicePrivate> service,
+void QLowEnergyControllerPrivateWinRT::readDescriptor(const QSharedPointer<QLowEnergyServicePrivate> service,
const QLowEnergyHandle charHandle,
const QLowEnergyHandle descHandle)
{
qCDebug(QT_BT_WINRT) << __FUNCTION__ << service << charHandle << descHandle;
Q_ASSERT(!service.isNull());
+ if (role == QLowEnergyController::PeripheralRole) {
+ service->setError(QLowEnergyService::DescriptorReadError);
+ Q_UNIMPLEMENTED();
+ return;
+ }
+
if (!service->characteristicList.contains(charHandle)) {
qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle << "in characteristic" << charHandle
<< "cannot be found in service" << service->uuid;
@@ -854,13 +885,18 @@ void QLowEnergyControllerPrivate::readDescriptor(const QSharedPointer<QLowEnergy
Q_ASSERT_SUCCEEDED(hr);
}
-void QLowEnergyControllerPrivate::writeCharacteristic(const QSharedPointer<QLowEnergyServicePrivate> service,
+void QLowEnergyControllerPrivateWinRT::writeCharacteristic(const QSharedPointer<QLowEnergyServicePrivate> service,
const QLowEnergyHandle charHandle,
const QByteArray &newValue,
QLowEnergyService::WriteMode mode)
{
qCDebug(QT_BT_WINRT) << __FUNCTION__ << service << charHandle << newValue << mode;
Q_ASSERT(!service.isNull());
+ if (role == QLowEnergyController::PeripheralRole) {
+ service->setError(QLowEnergyService::CharacteristicWriteError);
+ Q_UNIMPLEMENTED();
+ return;
+ }
if (!service->characteristicList.contains(charHandle)) {
qCDebug(QT_BT_WINRT) << "Characteristic" << charHandle << "cannot be found in service" << service->uuid;
service->setError(QLowEnergyService::CharacteristicWriteError);
@@ -901,7 +937,7 @@ void QLowEnergyControllerPrivate::writeCharacteristic(const QSharedPointer<QLowE
GattWriteOption option = writeWithResponse ? GattWriteOption_WriteWithResponse : GattWriteOption_WriteWithoutResponse;
hr = characteristic->WriteValueWithOptionAsync(buffer.Get(), option, &writeOp);
Q_ASSERT_SUCCEEDED(hr);
- auto writeCompletedLambda =[charData, charHandle, newValue, service, this]
+ auto writeCompletedLambda =[charData, charHandle, newValue, service, writeWithResponse, this]
(IAsyncOperation<GattCommunicationStatus> *op, AsyncStatus status)
{
if (status == AsyncStatus::Canceled || status == AsyncStatus::Error) {
@@ -927,7 +963,8 @@ void QLowEnergyControllerPrivate::writeCharacteristic(const QSharedPointer<QLowE
// empty.
if (charData.properties & QLowEnergyCharacteristic::Read)
updateValueOfCharacteristic(charHandle, newValue, false);
- emit service->characteristicWritten(QLowEnergyCharacteristic(service, charHandle), newValue);
+ if (writeWithResponse)
+ emit service->characteristicWritten(QLowEnergyCharacteristic(service, charHandle), newValue);
return S_OK;
};
hr = writeOp->put_Completed(Callback<IAsyncOperationCompletedHandler<GattCommunicationStatus>>(writeCompletedLambda).Get());
@@ -937,7 +974,7 @@ void QLowEnergyControllerPrivate::writeCharacteristic(const QSharedPointer<QLowE
Q_ASSERT_SUCCEEDED(hr);
}
-void QLowEnergyControllerPrivate::writeDescriptor(
+void QLowEnergyControllerPrivateWinRT::writeDescriptor(
const QSharedPointer<QLowEnergyServicePrivate> service,
const QLowEnergyHandle charHandle,
const QLowEnergyHandle descHandle,
@@ -945,6 +982,12 @@ void QLowEnergyControllerPrivate::writeDescriptor(
{
qCDebug(QT_BT_WINRT) << __FUNCTION__ << service << charHandle << descHandle << newValue;
Q_ASSERT(!service.isNull());
+ if (role == QLowEnergyController::PeripheralRole) {
+ service->setError(QLowEnergyService::DescriptorWriteError);
+ Q_UNIMPLEMENTED();
+ return;
+ }
+
if (!service->characteristicList.contains(charHandle)) {
qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle << "in characteristic" << charHandle
<< "could not be found in service" << service->uuid;
@@ -1076,12 +1119,12 @@ void QLowEnergyControllerPrivate::writeDescriptor(
}
-void QLowEnergyControllerPrivate::addToGenericAttributeList(const QLowEnergyServiceData &, QLowEnergyHandle)
+void QLowEnergyControllerPrivateWinRT::addToGenericAttributeList(const QLowEnergyServiceData &, QLowEnergyHandle)
{
Q_UNIMPLEMENTED();
}
-void QLowEnergyControllerPrivate::characteristicChanged(
+void QLowEnergyControllerPrivateWinRT::characteristicChanged(
int charHandle, const QByteArray &data)
{
QSharedPointer<QLowEnergyServicePrivate> service =