diff options
author | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2023-04-24 10:13:37 +0300 |
---|---|---|
committer | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2023-04-24 10:13:37 +0300 |
commit | da6113cb52beb5731d8c95ecbfc375936f59def2 (patch) | |
tree | 81a617b98e6e04d660fb2e75aae942a49ed7c2a1 /src/bluetooth/qlowenergycontroller_bluezdbus.cpp | |
parent | 3dcb548bd6fe4aa488ca0bac95e65a7a366c3eca (diff) | |
parent | ca96a42035255b4355e4d8ddba7f5da7b9006577 (diff) |
Merge remote-tracking branch 'origin/tqtc/lts-5.15.10' into tqtc/lts-5.15-opensource
Change-Id: I19a002f2b52eb02d4bfdf32c336811a71d42e9f2
Diffstat (limited to 'src/bluetooth/qlowenergycontroller_bluezdbus.cpp')
-rw-r--r-- | src/bluetooth/qlowenergycontroller_bluezdbus.cpp | 64 |
1 files changed, 53 insertions, 11 deletions
diff --git a/src/bluetooth/qlowenergycontroller_bluezdbus.cpp b/src/bluetooth/qlowenergycontroller_bluezdbus.cpp index c159e97e..2dbb28ae 100644 --- a/src/bluetooth/qlowenergycontroller_bluezdbus.cpp +++ b/src/bluetooth/qlowenergycontroller_bluezdbus.cpp @@ -415,7 +415,8 @@ void QLowEnergyControllerPrivateBluezDBus::discoverServices() Q_Q(QLowEnergyController); auto setupServicePrivate = [&, q]( - QLowEnergyService::ServiceType type, const QBluetoothUuid &uuid, const QString &path){ + QLowEnergyService::ServiceType type, const QBluetoothUuid &uuid, + const QString &path, const bool battery1Interface = false){ QSharedPointer<QLowEnergyServicePrivate> priv = QSharedPointer<QLowEnergyServicePrivate>::create(); priv->uuid = uuid; priv->type = type; // we make a guess we cannot validate @@ -423,8 +424,11 @@ void QLowEnergyControllerPrivateBluezDBus::discoverServices() GattService serviceContainer; serviceContainer.servicePath = path; - if (uuid == QBluetoothUuid::BatteryService) + + if (battery1Interface) { + qCDebug(QT_BT_BLUEZ) << "Using Battery1 interface to emulate generic interface"; serviceContainer.hasBatteryService = true; + } serviceList.insert(priv->uuid, priv); dbusServices.insert(priv->uuid, serviceContainer); @@ -434,25 +438,50 @@ void QLowEnergyControllerPrivateBluezDBus::discoverServices() const ManagedObjectList managedObjectList = reply.value(); const QString servicePathPrefix = device->path().append(QStringLiteral("/service")); + + // The Bluez battery service (0x180f) support has evolved over time and needs additional logic: + // + // * Until 5.47 Bluez exposes battery services via generic interface (GattService1) only + // * Between 5.48..5.54 Bluez exposes battery service as a dedicated 'Battery1' interface only + // * From 5.55 Bluez exposes both the generic service as well as the dedicated 'Battery1' + // + // To hide the difference from users the 'Battery1' interface will be used to emulate the + // generic interface. Importantly also the GattService1 interface, if available, is available + // early whereas the Battery1 interface may be available only later (generated too late for + // this service discovery's purposes) + // + // The precedence for battery service here is as follows: + // * If available via GattService1, use that and ignore possible Battery1 interface + // * If Battery1 interface is available or the 'org.bluez.Device1' lists battery service + // amongst list of available services, mark the service such that the code will later + // look up the Battery1 service details + bool gattBatteryService{false}; + QString batteryServicePath; + for (ManagedObjectList::const_iterator it = managedObjectList.constBegin(); it != managedObjectList.constEnd(); ++it) { const InterfaceList &ifaceList = it.value(); if (!it.key().path().startsWith(device->path())) continue; - // Since Bluez 5.48 battery services (0x180f) are no longer exposed - // as generic services under servicePathPrefix. - // A dedicated org.bluez.Battery1 interface is exposed. Here we are going to revert - // Bettery1 to the generic pattern. if (it.key().path() == device->path()) { - // find Battery1 service + // See if the battery service is available or is assumed to be available later for (InterfaceList::const_iterator battIter = ifaceList.constBegin(); battIter != ifaceList.constEnd(); ++battIter) { const QString &iface = battIter.key(); if (iface == QStringLiteral("org.bluez.Battery1")) { - qCDebug(QT_BT_BLUEZ) << "Found dedicated Battery service -> emulating generic btle access"; - setupServicePrivate(QLowEnergyService::PrimaryService, - QBluetoothUuid::BatteryService, - it.key().path()); + qCDebug(QT_BT_BLUEZ) << "Dedicated Battery1 service available"; + batteryServicePath = it.key().path(); + break; + } else if (iface == QStringLiteral("org.bluez.Device1")) { + for (auto const& uuid : + battIter.value()[QStringLiteral("UUIDs")].toStringList()) { + if (QBluetoothUuid(uuid) == + QBluetoothUuid::ServiceClassUuid::BatteryService) { + qCDebug(QT_BT_BLUEZ) << "Battery service listed as available service"; + batteryServicePath = it.key().path(); + break; + } + } } } continue; @@ -468,6 +497,11 @@ void QLowEnergyControllerPrivateBluezDBus::discoverServices() QScopedPointer<OrgBluezGattService1Interface> service(new OrgBluezGattService1Interface( QStringLiteral("org.bluez"),it.key().path(), QDBusConnection::systemBus(), this)); + if (QBluetoothUuid(service->uUID()) == + QBluetoothUuid::ServiceClassUuid::BatteryService) { + qCDebug(QT_BT_BLUEZ) << "Using battery service via GattService1 interface"; + gattBatteryService = true; + } setupServicePrivate(service->primary() ? QLowEnergyService::PrimaryService : QLowEnergyService::IncludedService, @@ -476,6 +510,12 @@ void QLowEnergyControllerPrivateBluezDBus::discoverServices() } } + if (!gattBatteryService && !batteryServicePath.isEmpty()) { + setupServicePrivate(QLowEnergyService::PrimaryService, + QBluetoothUuid::ServiceClassUuid::BatteryService, + batteryServicePath, true); + } + setState(QLowEnergyController::DiscoveredState); emit q->discoveryFinished(); } @@ -1305,3 +1345,5 @@ QLowEnergyService *QLowEnergyControllerPrivateBluezDBus::addServiceHelper( } QT_END_NAMESPACE + +#include "moc_qlowenergycontroller_bluezdbus_p.cpp" |