From 6dc89e93f887e3ef9c7e85655a1818b096ce81ad Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 2 May 2016 12:39:52 +0200 Subject: WinRT: BTLE: Discover list of available services Task-number: QTBUG-37779 Change-Id: Ia92facf9f3f1c6aae8fac7a205d3f9ad4921787e Reviewed-by: Alex Blasche --- src/bluetooth/qlowenergycontroller_p.h | 6 +++ src/bluetooth/qlowenergycontroller_winrt.cpp | 81 +++++++++++++++++++++++++++- 2 files changed, 86 insertions(+), 1 deletion(-) (limited to 'src/bluetooth') diff --git a/src/bluetooth/qlowenergycontroller_p.h b/src/bluetooth/qlowenergycontroller_p.h index 4ecdc7c9..38dfb714 100644 --- a/src/bluetooth/qlowenergycontroller_p.h +++ b/src/bluetooth/qlowenergycontroller_p.h @@ -90,6 +90,9 @@ namespace ABI { namespace Devices { namespace Bluetooth { struct IBluetoothLEDevice; + namespace GenericAttributeProfile { + struct IGattDeviceService; + } } } } @@ -432,6 +435,9 @@ private slots: private: Microsoft::WRL::ComPtr mDevice; EventRegistrationToken mStatusChangedToken; + + void obtainIncludedServices(QSharedPointer servicePointer, + Microsoft::WRL::ComPtr nativeService); #endif private: QLowEnergyController *q_ptr; diff --git a/src/bluetooth/qlowenergycontroller_winrt.cpp b/src/bluetooth/qlowenergycontroller_winrt.cpp index 1a9a3697..ffdd0d84 100644 --- a/src/bluetooth/qlowenergycontroller_winrt.cpp +++ b/src/bluetooth/qlowenergycontroller_winrt.cpp @@ -65,6 +65,7 @@ QT_BEGIN_NAMESPACE typedef ITypedEventHandler StatusHandler; Q_DECLARE_LOGGING_CATEGORY(QT_BT_WINRT) + QLowEnergyControllerPrivate::QLowEnergyControllerPrivate() : QObject(), state(QLowEnergyController::UnconnectedState), @@ -194,9 +195,87 @@ void QLowEnergyControllerPrivate::disconnectFromDevice() emit q->disconnected(); } +void QLowEnergyControllerPrivate::obtainIncludedServices(QSharedPointer servicePointer, + ComPtr service) +{ + Q_Q(QLowEnergyController); + ComPtr service2; + HRESULT hr = service.As(&service2); + Q_ASSERT_SUCCEEDED(hr); + ComPtr> includedServices; + hr = service2->GetAllIncludedServices(&includedServices); + Q_ASSERT_SUCCEEDED(hr); + + uint count; + includedServices->get_Size(&count); + for (uint i = 0; i < count; ++i) { + ComPtr includedService; + hr = includedServices->GetAt(i, &includedService); + Q_ASSERT_SUCCEEDED(hr); + GUID guuid; + hr = includedService->get_Uuid(&guuid); + Q_ASSERT_SUCCEEDED(hr); + const QBluetoothUuid includedUuid(guuid); + QSharedPointer includedPointer; + if (serviceList.contains(includedUuid)) { + includedPointer = serviceList.value(includedUuid); + } else { + QLowEnergyServicePrivate *priv = new QLowEnergyServicePrivate(); + priv->uuid = includedUuid; + priv->setController(this); + + includedPointer = QSharedPointer(priv); + serviceList.insert(includedUuid, includedPointer); + } + includedPointer->type |= QLowEnergyService::IncludedService; + servicePointer->includedServices.append(includedUuid); + + obtainIncludedServices(includedPointer, includedService); + + emit q->serviceDiscovered(includedUuid); + } +} + void QLowEnergyControllerPrivate::discoverServices() { - Q_UNIMPLEMENTED(); + Q_Q(QLowEnergyController); + + qCDebug(QT_BT_WINRT) << "Service discovery initiated"; + ComPtr> deviceServices; + HRESULT hr = mDevice->get_GattServices(&deviceServices); + Q_ASSERT_SUCCEEDED(hr); + uint serviceCount; + hr = deviceServices->get_Size(&serviceCount); + Q_ASSERT_SUCCEEDED(hr); + for (uint i = 0; i < serviceCount; ++i) { + ComPtr deviceService; + hr = deviceServices->GetAt(i, &deviceService); + Q_ASSERT_SUCCEEDED(hr); + GUID guuid; + hr = deviceService->get_Uuid(&guuid); + Q_ASSERT_SUCCEEDED(hr); + const QBluetoothUuid service(guuid); + + QSharedPointer pointer; + if (serviceList.contains(service)) { + pointer = serviceList.value(service); + } else { + QLowEnergyServicePrivate *priv = new QLowEnergyServicePrivate(); + priv->uuid = service; + priv->setController(this); + + pointer = QSharedPointer(priv); + serviceList.insert(service, pointer); + } + pointer->type |= QLowEnergyService::PrimaryService; + + obtainIncludedServices(pointer, deviceService); + + emit q->serviceDiscovered(service); + } + + setState(QLowEnergyController::DiscoveredState); + emit q->discoveryFinished(); } void QLowEnergyControllerPrivate::discoverServiceDetails(const QBluetoothUuid &) -- cgit v1.2.3