summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorOliver Wolff <oliver.wolff@qt.io>2016-05-02 12:50:11 +0200
committerOliver Wolff <oliver.wolff@qt.io>2016-06-16 08:26:42 +0000
commitda0973e98ebd0d81523839ea255015c4a2e646a7 (patch)
treefb26e67ffd894dc9beafd1fce1808e4167e12a1b /src
parent63d3788d04badb32bb7ba27f8d8aeaf46b443ae1 (diff)
WinRT: BTLE: Write descriptors
Task-number: QTBUG-37779 Change-Id: Ib3ef0723b069275f4dd96dfba8316cc2b4ecb4f3 Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com> Reviewed-by: Maurice Kalinowski <maurice.kalinowski@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/bluetooth/qlowenergycontroller_winrt.cpp94
1 files changed, 89 insertions, 5 deletions
diff --git a/src/bluetooth/qlowenergycontroller_winrt.cpp b/src/bluetooth/qlowenergycontroller_winrt.cpp
index 08e47d5b..d7a90881 100644
--- a/src/bluetooth/qlowenergycontroller_winrt.cpp
+++ b/src/bluetooth/qlowenergycontroller_winrt.cpp
@@ -750,12 +750,96 @@ void QLowEnergyControllerPrivate::writeCharacteristic(const QSharedPointer<QLowE
}
void QLowEnergyControllerPrivate::writeDescriptor(
- const QSharedPointer<QLowEnergyServicePrivate>,
- const QLowEnergyHandle,
- const QLowEnergyHandle,
- const QByteArray &)
+ const QSharedPointer<QLowEnergyServicePrivate> service,
+ const QLowEnergyHandle charHandle,
+ const QLowEnergyHandle descHandle,
+ const QByteArray &newValue)
{
- Q_UNIMPLEMENTED();
+ qCDebug(QT_BT_WINRT) << __FUNCTION__ << service << charHandle << descHandle << newValue;
+ Q_ASSERT(!service.isNull());
+ if (!service->characteristicList.contains(charHandle)) {
+ qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle << "in characteristic" << charHandle
+ << "could not be found in service" << service->uuid;
+ service->setError(QLowEnergyService::DescriptorWriteError);
+ return;
+ }
+
+ HRESULT hr;
+ hr = QEventDispatcherWinRT::runOnXamlThread([charHandle, descHandle, this, service, newValue]() {
+ // Get native service
+ ComPtr<IGattDeviceService> deviceService;
+ HRESULT hr = mDevice->GetGattService(service->uuid, &deviceService);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ // Get native characteristic
+ QLowEnergyServicePrivate::CharData charData = service->characteristicList.value(charHandle);
+ ComPtr<IVectorView<GattCharacteristic *>> characteristics;
+ hr = deviceService->GetCharacteristics(charData.uuid, &characteristics);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IGattCharacteristic> characteristic;
+ hr = characteristics->GetAt(0, &characteristic);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ // Get native descriptor
+ if (!charData.descriptorList.contains(descHandle))
+ qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle << "could not be found in Characteristic" << charHandle;
+
+ QLowEnergyServicePrivate::DescData descData = charData.descriptorList.value(descHandle);
+ ComPtr<IVectorView<GattDescriptor *>> descriptors;
+ hr = characteristic->GetDescriptors(descData.uuid, &descriptors);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IGattDescriptor> descriptor;
+ hr = descriptors->GetAt(0, &descriptor);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<ABI::Windows::Storage::Streams::IBufferFactory> bufferFactory;
+ hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(), &bufferFactory);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<ABI::Windows::Storage::Streams::IBuffer> buffer;
+ const int length = newValue.length();
+ hr = bufferFactory->Create(length, &buffer);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = buffer->put_Length(length);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteAccess;
+ hr = buffer.As(&byteAccess);
+ Q_ASSERT_SUCCEEDED(hr);
+ byte *bytes;
+ hr = byteAccess->Buffer(&bytes);
+ Q_ASSERT_SUCCEEDED(hr);
+ memcpy(bytes, newValue, length);
+ ComPtr<IAsyncOperation<GattCommunicationStatus>> writeOp;
+ hr = descriptor->WriteValueAsync(buffer.Get(), &writeOp);
+ Q_ASSERT_SUCCEEDED(hr);
+ auto writeCompletedLambda = [charHandle, descHandle, newValue, service, this]
+ (IAsyncOperation<GattCommunicationStatus> *op, AsyncStatus status)
+ {
+ if (status == AsyncStatus::Canceled || status == AsyncStatus::Error) {
+ qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle << "write operation failed";
+ service->setError(QLowEnergyService::DescriptorWriteError);
+ return S_OK;
+ }
+ GattCommunicationStatus result;
+ HRESULT hr;
+ hr = op->GetResults(&result);
+ if (FAILED(hr)) {
+ qCDebug(QT_BT_WINRT) << "Could not obtain result for descriptor" << descHandle;
+ service->setError(QLowEnergyService::DescriptorWriteError);
+ return S_OK;
+ }
+ if (result != GattCommunicationStatus_Success) {
+ qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle << "write operation failed";
+ service->setError(QLowEnergyService::DescriptorWriteError);
+ return S_OK;
+ }
+ updateValueOfDescriptor(charHandle, descHandle, newValue, false);
+ emit service->descriptorWritten(QLowEnergyDescriptor(service, charHandle, descHandle), newValue);
+ return S_OK;
+ };
+ hr = writeOp->put_Completed(Callback<IAsyncOperationCompletedHandler<GattCommunicationStatus>>(writeCompletedLambda).Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ return S_OK;
+ });
+ Q_ASSERT_SUCCEEDED(hr);
}
void QLowEnergyControllerPrivate::addToGenericAttributeList(const QLowEnergyServiceData &, QLowEnergyHandle)