diff options
author | Oliver Wolff <oliver.wolff@qt.io> | 2016-05-02 12:50:11 +0200 |
---|---|---|
committer | Oliver Wolff <oliver.wolff@qt.io> | 2016-06-16 08:26:42 +0000 |
commit | da0973e98ebd0d81523839ea255015c4a2e646a7 (patch) | |
tree | fb26e67ffd894dc9beafd1fce1808e4167e12a1b /src | |
parent | 63d3788d04badb32bb7ba27f8d8aeaf46b443ae1 (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.cpp | 94 |
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) |