linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH BlueZ 1/3] doc/adapter-api: Add pattern filter
@ 2020-02-20  0:28 Luiz Augusto von Dentz
  2020-02-20  0:28 ` [PATCH BlueZ 2/3] adapter: Implement Pattern filter Luiz Augusto von Dentz
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Luiz Augusto von Dentz @ 2020-02-20  0:28 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds a pattern filter which can be used to filter devices by
address or name prefix which is quite convenient on a crowded
environment.
---
 doc/adapter-api.txt | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/doc/adapter-api.txt b/doc/adapter-api.txt
index 2afd61bc3..acae032d9 100644
--- a/doc/adapter-api.txt
+++ b/doc/adapter-api.txt
@@ -119,6 +119,21 @@ Methods		void StartDiscovery()
 				if the adapter is already discoverable setting
 				this filter won't do anything.
 
+			string Pattern (Default: none)
+
+				Discover devices where the pattern matches
+				either the prefix of the address or
+				device name which is convenient way to limited
+				the number of device objects created during a
+				discovery.
+
+				When set disregards device discoverable flags.
+
+				Note: The pattern matching is ignored if there
+				are other client that don't set any pattern as
+				it work as a logical OR, also setting empty
+				string "" pattern will match any device found.
+
 			When discovery filter is set, Device objects will be
 			created as new devices with matching criteria are
 			discovered regardless of they are connectable or
-- 
2.21.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH BlueZ 2/3] adapter: Implement Pattern filter
  2020-02-20  0:28 [PATCH BlueZ 1/3] doc/adapter-api: Add pattern filter Luiz Augusto von Dentz
@ 2020-02-20  0:28 ` Luiz Augusto von Dentz
  2020-02-20  0:28 ` [PATCH BlueZ 3/3] client: Add scan.pattern command Luiz Augusto von Dentz
  2020-02-26 17:36 ` [PATCH BlueZ 1/3] doc/adapter-api: Add pattern filter Luiz Augusto von Dentz
  2 siblings, 0 replies; 4+ messages in thread
From: Luiz Augusto von Dentz @ 2020-02-20  0:28 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This implements the new Pattern filter as documented in the
adapter-api.txt.
---
 src/adapter.c | 92 ++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 76 insertions(+), 16 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 329c3ae0b..972d88772 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -174,6 +174,7 @@ struct conn_param {
 
 struct discovery_filter {
 	uint8_t type;
+	char *pattern;
 	uint16_t pathloss;
 	int16_t rssi;
 	GSList *uuids;
@@ -2423,6 +2424,22 @@ static bool parse_discoverable(DBusMessageIter *value,
 	return true;
 }
 
+static bool parse_pattern(DBusMessageIter *value,
+					struct discovery_filter *filter)
+{
+	const char *pattern;
+
+	if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_STRING)
+		return false;
+
+	dbus_message_iter_get_basic(value, &pattern);
+
+	free(filter->pattern);
+	filter->pattern = strdup(pattern);
+
+	return true;
+}
+
 struct filter_parser {
 	const char *name;
 	bool (*func)(DBusMessageIter *iter, struct discovery_filter *filter);
@@ -2433,6 +2450,7 @@ struct filter_parser {
 	{ "Transport", parse_transport },
 	{ "DuplicateData", parse_duplicate_data },
 	{ "Discoverable", parse_discoverable },
+	{ "Pattern", parse_pattern },
 	{ }
 };
 
@@ -2473,6 +2491,7 @@ static bool parse_discovery_filter_dict(struct btd_adapter *adapter,
 	(*filter)->type = get_scan_type(adapter);
 	(*filter)->duplicate = false;
 	(*filter)->discoverable = false;
+	(*filter)->pattern = NULL;
 
 	dbus_message_iter_init(msg, &iter);
 	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
@@ -2518,10 +2537,11 @@ static bool parse_discovery_filter_dict(struct btd_adapter *adapter,
 		goto invalid_args;
 
 	DBG("filtered discovery params: transport: %d rssi: %d pathloss: %d "
-		" duplicate data: %s discoverable %s", (*filter)->type,
-		(*filter)->rssi, (*filter)->pathloss,
+		" duplicate data: %s discoverable %s pattern %s",
+		(*filter)->type, (*filter)->rssi, (*filter)->pathloss,
 		(*filter)->duplicate ? "true" : "false",
-		(*filter)->discoverable ? "true" : "false");
+		(*filter)->discoverable ? "true" : "false",
+		(*filter)->pattern);
 
 	return true;
 
@@ -6146,6 +6166,52 @@ static void filter_duplicate_data(void *data, void *user_data)
 	*duplicate = client->discovery_filter->duplicate;
 }
 
+static bool device_is_discoverable(struct btd_adapter *adapter,
+					struct eir_data *eir, const char *addr,
+					uint8_t bdaddr_type)
+{
+	GSList *l;
+	bool discoverable;
+
+	if (bdaddr_type == BDADDR_BREDR || adapter->filtered_discovery)
+		discoverable = true;
+	else
+		discoverable = eir->flags & (EIR_LIM_DISC | EIR_GEN_DISC);
+
+	/*
+	 * Mark as not discoverable if no client has requested discovery and
+	 * report has not set any discoverable flags.
+	 */
+	if (!adapter->discovery_list && !discoverable)
+		return false;
+
+	/* Do a prefix match for both address and name if pattern is set */
+	for (l = adapter->discovery_list; l; l = g_slist_next(l)) {
+		struct watch_client *client = l->data;
+		struct discovery_filter *filter = client->discovery_filter;
+		size_t pattern_len;
+
+		if (!filter || !filter->pattern)
+			continue;
+
+		/* Reset discoverable if a client has a pattern filter */
+		discoverable = false;
+
+		pattern_len = strlen(filter->pattern);
+		if (!pattern_len)
+			return true;
+
+		if (!strncmp(filter->pattern, addr, pattern_len))
+			return true;
+
+		if (eir->name && !strncmp(filter->pattern, eir->name,
+							pattern_len))
+			return true;
+	}
+
+	return discoverable;
+}
+
 static void update_found_devices(struct btd_adapter *adapter,
 					const bdaddr_t *bdaddr,
 					uint8_t bdaddr_type, int8_t rssi,
@@ -6162,21 +6228,14 @@ static void update_found_devices(struct btd_adapter *adapter,
 	memset(&eir_data, 0, sizeof(eir_data));
 	eir_parse(&eir_data, data, data_len);
 
-	if (bdaddr_type == BDADDR_BREDR || adapter->filtered_discovery)
-		discoverable = true;
-	else
-		discoverable = eir_data.flags & (EIR_LIM_DISC | EIR_GEN_DISC);
-
 	ba2str(bdaddr, addr);
 
+	discoverable = device_is_discoverable(adapter, &eir_data, addr,
+							bdaddr_type);
+
 	dev = btd_adapter_find_device(adapter, bdaddr, bdaddr_type);
 	if (!dev) {
-		/*
-		 * If no client has requested discovery or the device is
-		 * not marked as discoverable, then do not create new
-		 * device objects.
-		 */
-		if (!adapter->discovery_list || !discoverable) {
+		if (!discoverable) {
 			eir_data_free(&eir_data);
 			return;
 		}
@@ -6219,8 +6278,9 @@ static void update_found_devices(struct btd_adapter *adapter,
 		return;
 	}
 
-	if (adapter->filtered_discovery &&
-	    !is_filter_match(adapter->discovery_list, &eir_data, rssi)) {
+	/* Don't continue if not discoverable or if filter don't match */
+	if (!discoverable || (adapter->filtered_discovery &&
+	    !is_filter_match(adapter->discovery_list, &eir_data, rssi))) {
 		eir_data_free(&eir_data);
 		return;
 	}
-- 
2.21.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH BlueZ 3/3] client: Add scan.pattern command
  2020-02-20  0:28 [PATCH BlueZ 1/3] doc/adapter-api: Add pattern filter Luiz Augusto von Dentz
  2020-02-20  0:28 ` [PATCH BlueZ 2/3] adapter: Implement Pattern filter Luiz Augusto von Dentz
@ 2020-02-20  0:28 ` Luiz Augusto von Dentz
  2020-02-26 17:36 ` [PATCH BlueZ 1/3] doc/adapter-api: Add pattern filter Luiz Augusto von Dentz
  2 siblings, 0 replies; 4+ messages in thread
From: Luiz Augusto von Dentz @ 2020-02-20  0:28 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This uses the new Pattern filter:

[bluetooth]# scan.pattern Living
[bluetooth]# scan on
SetDiscoveryFilter success
Discovery started
[CHG] Controller XX:XX:XX:XX:XX:XX Discovering: yes
[NEW] Device XX:XX:XX:XX:XX:XX Living Room TV
---
 client/main.c | 33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/client/main.c b/client/main.c
index 8bd0bac9e..422da5593 100644
--- a/client/main.c
+++ b/client/main.c
@@ -1157,6 +1157,7 @@ static void cmd_default_agent(int argc, char *argv[])
 
 static struct set_discovery_filter_args {
 	char *transport;
+	char *pattern;
 	dbus_uint16_t rssi;
 	dbus_int16_t pathloss;
 	char **uuids;
@@ -1241,6 +1242,10 @@ static void set_discovery_filter_setup(DBusMessageIter *iter, void *user_data)
 						DBUS_TYPE_BOOLEAN,
 						&args->discoverable);
 
+	if (args->pattern != NULL)
+		g_dbus_dict_append_entry(&dict, "Pattern", DBUS_TYPE_STRING,
+						&args->pattern);
+
 	dbus_message_iter_close_container(iter, &dict);
 }
 
@@ -1440,6 +1445,22 @@ static void cmd_scan_filter_discoverable(int argc, char *argv[])
 		set_discovery_filter(false);
 }
 
+static void cmd_scan_filter_pattern(int argc, char *argv[])
+{
+	if (argc < 2 || !strlen(argv[1])) {
+		bt_shell_printf("Pattern: %s\n", filter.pattern);
+		return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+	}
+
+	free(filter.pattern);
+	filter.pattern = strdup(argv[1]);
+
+	filter.set = false;
+
+	if (filter.active)
+		set_discovery_filter(false);
+}
+
 static void filter_clear_uuids(void)
 {
 	g_strfreev(filter.uuids);
@@ -1473,6 +1494,12 @@ static void filter_clear_discoverable(void)
 	filter.discoverable = false;
 }
 
+static void filter_clear_pattern(void)
+{
+	free(filter.pattern);
+	filter.pattern = NULL;
+}
+
 struct clear_entry {
 	const char *name;
 	void (*clear) (void);
@@ -1485,6 +1512,7 @@ static const struct clear_entry filter_clear[] = {
 	{ "transport", filter_clear_transport },
 	{ "duplicate-data", filter_clear_duplicate },
 	{ "discoverable", filter_clear_discoverable },
+	{ "pattern", filter_clear_pattern },
 	{}
 };
 
@@ -2639,8 +2667,11 @@ static const struct bt_shell_menu scan_menu = {
 	{ "discoverable", "[on/off]", cmd_scan_filter_discoverable,
 				"Set/Get discoverable filter",
 				NULL },
+	{ "pattern", "[value]", cmd_scan_filter_pattern,
+				"Set/Get pattern filter",
+				NULL },
 	{ "clear",
-		"[uuids/rssi/pathloss/transport/duplicate-data/discoverable]",
+	"[uuids/rssi/pathloss/transport/duplicate-data/discoverable/pattern]",
 				cmd_scan_filter_clear,
 				"Clears discovery filter.",
 				filter_clear_generator },
-- 
2.21.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH BlueZ 1/3] doc/adapter-api: Add pattern filter
  2020-02-20  0:28 [PATCH BlueZ 1/3] doc/adapter-api: Add pattern filter Luiz Augusto von Dentz
  2020-02-20  0:28 ` [PATCH BlueZ 2/3] adapter: Implement Pattern filter Luiz Augusto von Dentz
  2020-02-20  0:28 ` [PATCH BlueZ 3/3] client: Add scan.pattern command Luiz Augusto von Dentz
@ 2020-02-26 17:36 ` Luiz Augusto von Dentz
  2 siblings, 0 replies; 4+ messages in thread
From: Luiz Augusto von Dentz @ 2020-02-26 17:36 UTC (permalink / raw)
  To: linux-bluetooth

Hi,

On Wed, Feb 19, 2020 at 4:28 PM Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
>
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> This adds a pattern filter which can be used to filter devices by
> address or name prefix which is quite convenient on a crowded
> environment.
> ---
>  doc/adapter-api.txt | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
>
> diff --git a/doc/adapter-api.txt b/doc/adapter-api.txt
> index 2afd61bc3..acae032d9 100644
> --- a/doc/adapter-api.txt
> +++ b/doc/adapter-api.txt
> @@ -119,6 +119,21 @@ Methods            void StartDiscovery()
>                                 if the adapter is already discoverable setting
>                                 this filter won't do anything.
>
> +                       string Pattern (Default: none)
> +
> +                               Discover devices where the pattern matches
> +                               either the prefix of the address or
> +                               device name which is convenient way to limited
> +                               the number of device objects created during a
> +                               discovery.
> +
> +                               When set disregards device discoverable flags.
> +
> +                               Note: The pattern matching is ignored if there
> +                               are other client that don't set any pattern as
> +                               it work as a logical OR, also setting empty
> +                               string "" pattern will match any device found.
> +
>                         When discovery filter is set, Device objects will be
>                         created as new devices with matching criteria are
>                         discovered regardless of they are connectable or
> --
> 2.21.1

Applied.

-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-02-26 17:36 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-20  0:28 [PATCH BlueZ 1/3] doc/adapter-api: Add pattern filter Luiz Augusto von Dentz
2020-02-20  0:28 ` [PATCH BlueZ 2/3] adapter: Implement Pattern filter Luiz Augusto von Dentz
2020-02-20  0:28 ` [PATCH BlueZ 3/3] client: Add scan.pattern command Luiz Augusto von Dentz
2020-02-26 17:36 ` [PATCH BlueZ 1/3] doc/adapter-api: Add pattern filter Luiz Augusto von Dentz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).