[PATCH v1] gdbus: Skip BLE random-address devices and remove broad match rule

Xiuzhuo Shang <[email protected]> Fri, 10 Jul 2026 15:55:48 +0800
Newsgroups dev.linux.lists.ofono,org.kernel.vger.linux-bluetooth
Message-ID <[email protected]>
Two related changes to reduce dbus-daemon load caused by high-rate
BLE advertising signals:

1. In parse_properties(), skip creating a GDBusProxy for Device1
   objects whose AddressType is 'random' (BLE-only devices). Each
   proxy registers a per-device PropertiesChanged watch via
   g_dbus_add_properties_watch(); with hundreds of BLE peripherals
   advertising simultaneously, this results in hundreds of match rules
   and dbus-daemon routing thousands of RSSI PropertiesChanged signals
   per second to ofono, none of which ofono processes. The
   AddressType property is available in the InterfacesAdded dict at
   the time parse_properties() is called, so the check is reliable
   and race-free.

   BR/EDR devices (AddressType='public') are unaffected: their proxies
   are created as before, and the property_changed callback continues
   to receive Paired and ServicesResolved updates needed for HFP/HSP.

2. In g_dbus_client_new_full(), remove the broad
   type='signal',sender=<service>,path_namespace=<path> match rule.
   This rule was the sole feeder for the signal_func path in
   message_filter(). ofono never calls g_dbus_client_set_signal_watch()
   so signal_func is always NULL; the broad rule therefore served no
   purpose and caused dbus-daemon to route every bluetoothd signal
   (including all BLE PropertiesChanged) to ofono.

   InterfacesAdded and InterfacesRemoved are already covered by the
   precise watches registered via g_dbus_add_signal_watch() earlier in
   g_dbus_client_new_full(), so no functionality is lost.

Together these two changes prevent dbus-daemon from routing BLE
advertising PropertiesChanged signals to ofono entirely, eliminating
the dbus-daemon memory growth and bluetoothd socket backpressure seen
after hours of BLE scanning.

Signed-off-by: Xiuzhuo Shang <[email protected]>
---
 gdbus/client.c | 46 ++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 38 insertions(+), 8 deletions(-)

diff --git a/gdbus/client.c b/gdbus/client.c
index 48711ae8..dd3c17f9 100644
--- a/gdbus/client.c
+++ b/gdbus/client.c
@@ -937,6 +937,44 @@ static void parse_properties(GDBusClient *client, const char *path,
 	if (g_str_equal(interface, DBUS_INTERFACE_PROPERTIES) == TRUE)
 		return;
 
+	/*
+	 * Skip BLE devices (AddressType='random') to avoid registering a
+	 * per-device PropertiesChanged watch for every advertising BLE
+	 * peripheral. ofono only needs BR/EDR devices for HFP/HSP; the
+	 * high-rate RSSI PropertiesChanged signals from BLE scanners cause
+	 * dbus-daemon memory bloat and socket backpressure in bluetoothd.
+	 *
+	 * The AddressType property is present in the InterfacesAdded dict
+	 * (iter) at this point, so it can be checked before proxy_new().
+	 */
+	if (g_str_equal(interface, "org.bluez.Device1") == TRUE) {
+		DBusMessageIter props, entry;
+		DBusMessageIter copy = *iter;
+
+		if (dbus_message_iter_get_arg_type(&copy) == DBUS_TYPE_ARRAY) {
+			dbus_message_iter_recurse(&copy, &props);
+			while (dbus_message_iter_get_arg_type(&props) ==
+						DBUS_TYPE_DICT_ENTRY) {
+				const char *key;
+				dbus_message_iter_recurse(&props, &entry);
+				dbus_message_iter_get_basic(&entry, &key);
+				if (g_str_equal(key, "AddressType") == TRUE) {
+					DBusMessageIter var;
+					const char *addr_type;
+					dbus_message_iter_next(&entry);
+					dbus_message_iter_recurse(&entry, &var);
+					dbus_message_iter_get_basic(&var,
+								&addr_type);
+					if (g_str_equal(addr_type,
+							"random") == TRUE)
+						return;
+					break;
+				}
+				dbus_message_iter_next(&props);
+			}
+		}
+	}
+
 	proxy = proxy_lookup(client, path, interface);
 	if (proxy) {
 		update_properties(proxy, iter, FALSE);
@@ -1255,14 +1293,6 @@ GDBusClient *g_dbus_client_new_full(DBusConnection *connection,
 						"InterfacesRemoved",
 						interfaces_removed,
 						client, NULL);
-	g_ptr_array_add(client->match_rules, g_strdup_printf("type='signal',"
-				"sender='%s',path_namespace='%s'",
-				client->service_name, client->base_path));
-
-	for (i = 0; i < client->match_rules->len; i++) {
-		modify_match(client->dbus_conn, "AddMatch",
-				g_ptr_array_index(client->match_rules, i));
-	}
 
 	return g_dbus_client_ref(client);
 }
-- 
2.43.0