Skip to content

Commit 2a8504c

Browse files
authored
[bluetooth] Fix BlueZ events stopping after reconnect (no SERVICES_DISCOVERED) (openhab#20950)
openhab#20903 changed onServicesResolved() to call discoverServices() instead of firing SERVICES_DISCOVERED unconditionally. discoverServices() only notified when the openHAB-side service list *grew* (getGattServices().size() > getServices().size()). That list (supportedServices) is only cleared on BlueZ object removal, so on a normal reconnect BlueZ re-fires ServicesResolved=true while the list is already fully populated, the "grew" check is false, and SERVICES_DISCOVERED is never re-fired. Consumers built on ConnectedBluetoothHandler re-arm their notifications and polling off onServicesDiscovered() (e.g. grundfosalpha enables notifications and schedules its read loop there; the generic binding rebuilds channels). Swallowing the event leaves the Thing ONLINE but silent after every reconnect - no events are received, matching openhab#20947. Fire SERVICES_DISCOVERED whenever the GATT is resolved with services present, not only when the list just grew. Population still happens only when the list grows, but the notification now always reaches listeners on a resolve. The event is idempotent for all consumers (generic only adds missing channels; ConnectedBluetoothHandler/grundfosalpha re-enabling notifications is a no-op when already notifying). Fixes openhab#20947 Signed-off-by: Vlad Kolotoff <vkolotoff@pm.me>
1 parent 6e83787 commit 2a8504c

1 file changed

Lines changed: 11 additions & 3 deletions

File tree

  • bundles/org.openhab.binding.bluetooth.bluez/src/main/java/org/openhab/binding/bluetooth/bluez/internal

bundles/org.openhab.binding.bluetooth.bluez/src/main/java/org/openhab/binding/bluetooth/bluez/internal/BlueZBluetoothDevice.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -386,13 +386,13 @@ public void onDBusBlueZEvent(BlueZEvent event) {
386386
@Override
387387
public void onServicesResolved(ServicesResolvedEvent event) {
388388
if (event.isResolved()) {
389-
// Populate our service/characteristic list from the now-resolved GATT before notifying
389+
// Populate our service/characteristic list from the now-resolved GATT and notify
390390
// listeners. BlueZ can deliver ServicesResolved=true while our own supportedServices list
391391
// is still empty (e.g. right after a reconnect, before discoverServices() has run); firing
392392
// SERVICES_DISCOVERED then makes listeners (e.g. the generic handler's channel builder) run
393393
// against an empty list and miss every characteristic. discoverServices() populates the
394-
// list and fires SERVICES_DISCOVERED itself once it has added services, so it is the
395-
// correct trigger here. If the services are already known it is a cheap no-op.
394+
// list and fires SERVICES_DISCOVERED once the GATT is resolved with services present -
395+
// including on a reconnect where the list is unchanged - so it is the correct trigger here.
396396
discoverServices();
397397
}
398398
}
@@ -505,6 +505,14 @@ public boolean discoverServices() {
505505
}
506506
addService(service);
507507
}
508+
}
509+
// Notify whenever the GATT is resolved with services present, not only when our list just
510+
// grew. On a reconnect BlueZ re-fires ServicesResolved=true while our supportedServices map
511+
// is already fully populated from the previous connection (it is only cleared on object
512+
// removal), so the "grew" check above is false. Consumers such as ConnectedBluetoothHandler
513+
// re-arm their notifications/polling off SERVICES_DISCOVERED, so swallowing it here leaves the
514+
// Thing online but silent after every reconnect. The notification is idempotent for listeners.
515+
if (!getServices().isEmpty()) {
508516
notifyListeners(BluetoothEventType.SERVICES_DISCOVERED);
509517
}
510518
return true;

0 commit comments

Comments
 (0)