linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 1/8] doc/advertising-api: Add Discoverable property
@ 2018-05-22  9:50 Luiz Augusto von Dentz
  2018-05-22  9:50 ` [PATCH v3 2/8] shared/ad: Add function to manipulate flags Luiz Augusto von Dentz
                   ` (7 more replies)
  0 siblings, 8 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-22  9:50 UTC (permalink / raw)
  To: linux-bluetooth

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

This adds Discoverable which the application can use in case it want
to set the General Discoverable flag per instance.

Note: This would allow for example an application to advertise as
discoverable even if the adapter is not discoverable which may be
required by dual-mode as it may not require BR/EDR to be discoverable.
---
 doc/advertising-api.txt | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/doc/advertising-api.txt b/doc/advertising-api.txt
index eef98ad91..96deeeccd 100644
--- a/doc/advertising-api.txt
+++ b/doc/advertising-api.txt
@@ -78,6 +78,14 @@ Properties	string Type
 				<Transport Discovery> <Organization Flags...>
 				0x26                   0x01         0x01...
 
+		bool Discoverable [Experimental]
+
+			Advertise as general discoverable. When present this
+			will override adapter Discoverable property.
+
+			Note: This property shall not be set when Type is set
+			to broadcast.
+
 		array{string} Includes
 
 			List of features to be included in the advertising
-- 
2.14.3


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

* [PATCH v3 2/8] shared/ad: Add function to manipulate flags
  2018-05-22  9:50 [PATCH v3 1/8] doc/advertising-api: Add Discoverable property Luiz Augusto von Dentz
@ 2018-05-22  9:50 ` Luiz Augusto von Dentz
  2018-05-22  9:50 ` [PATCH v3 3/8] advertising: Add implementation of Discoverable property Luiz Augusto von Dentz
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-22  9:50 UTC (permalink / raw)
  To: linux-bluetooth

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

This adds basically functionality to manipulate AD flags.
---
 src/shared/ad.c | 106 +++++++++++++++++++++++++++++++++++++++-----------------
 src/shared/ad.h |   6 ++++
 2 files changed, 80 insertions(+), 32 deletions(-)

diff --git a/src/shared/ad.c b/src/shared/ad.c
index f0e62cef1..3ceb87632 100644
--- a/src/shared/ad.c
+++ b/src/shared/ad.c
@@ -127,6 +127,48 @@ void bt_ad_unref(struct bt_ad *ad)
 	free(ad);
 }
 
+static bool data_type_match(const void *data, const void *user_data)
+{
+	const struct bt_ad_data *a = data;
+	const uint8_t type = PTR_TO_UINT(user_data);
+
+	return a->type == type;
+}
+
+static bool ad_replace_data(struct bt_ad *ad, uint8_t type, void *data,
+							size_t len)
+{
+	struct bt_ad_data *new_data;
+
+	new_data = queue_find(ad->data, data_type_match, UINT_TO_PTR(type));
+	if (new_data) {
+		if (new_data->len == len && !memcmp(new_data->data, data, len))
+			return false;
+		new_data->data = realloc(new_data->data, len);
+		memcpy(new_data->data, data, len);
+		new_data->len = len;
+		return true;
+	}
+
+	new_data = new0(struct bt_ad_data, 1);
+	new_data->type = type;
+	new_data->data = malloc(len);
+	if (!new_data->data) {
+		free(new_data);
+		return false;
+	}
+
+	memcpy(new_data->data, data, len);
+	new_data->len = len;
+
+	if (queue_push_tail(ad->data, new_data))
+		return true;
+
+	data_destroy(new_data);
+
+	return false;
+}
+
 static size_t uuid_list_length(struct queue *uuid_queue)
 {
 	bool uuid16_included = false;
@@ -809,12 +851,39 @@ void bt_ad_clear_appearance(struct bt_ad *ad)
 	ad->appearance = UINT16_MAX;
 }
 
-static bool data_type_match(const void *data, const void *user_data)
+bool bt_ad_add_flags(struct bt_ad *ad, uint8_t *flags, size_t len)
 {
-	const struct bt_ad_data *a = data;
-	const uint8_t type = PTR_TO_UINT(user_data);
+	if (!ad)
+		return false;
 
-	return a->type == type;
+	/* TODO: Add table to check other flags */
+	if (len > 1 || flags[0] & 0xe0)
+		return false;
+
+	return ad_replace_data(ad, BT_AD_FLAGS, flags, len);
+}
+
+bool bt_ad_has_flags(struct bt_ad *ad)
+{
+	struct bt_ad_data *data;
+
+	if (!ad)
+		return false;
+
+	data = queue_find(ad->data, data_type_match, UINT_TO_PTR(BT_AD_FLAGS));
+	if (!data)
+		return false;
+
+	return true;
+}
+
+void bt_ad_clear_flags(struct bt_ad *ad)
+{
+	if (!ad)
+		return;
+
+	queue_remove_all(ad->data, data_type_match, UINT_TO_PTR(BT_AD_FLAGS),
+							data_destroy);
 }
 
 static uint8_t type_blacklist[] = {
@@ -862,7 +931,6 @@ static uint8_t type_blacklist[] = {
 
 bool bt_ad_add_data(struct bt_ad *ad, uint8_t type, void *data, size_t len)
 {
-	struct bt_ad_data *new_data;
 	size_t i;
 
 	if (!ad)
@@ -871,38 +939,12 @@ bool bt_ad_add_data(struct bt_ad *ad, uint8_t type, void *data, size_t len)
 	if (len > (MAX_ADV_DATA_LEN - 2))
 		return false;
 
-	new_data = queue_find(ad->data, data_type_match, UINT_TO_PTR(type));
-	if (new_data) {
-		if (new_data->len == len && !memcmp(new_data->data, data, len))
-			return false;
-		new_data->data = realloc(new_data->data, len);
-		memcpy(new_data->data, data, len);
-		new_data->len = len;
-		return true;
-	}
-
 	for (i = 0; i < sizeof(type_blacklist); i++) {
 		if (type == type_blacklist[i])
 			return false;
 	}
 
-	new_data = new0(struct bt_ad_data, 1);
-	new_data->type = type;
-	new_data->data = malloc(len);
-	if (!new_data->data) {
-		free(new_data);
-		return false;
-	}
-
-	memcpy(new_data->data, data, len);
-	new_data->len = len;
-
-	if (queue_push_tail(ad->data, new_data))
-		return true;
-
-	data_destroy(new_data);
-
-	return false;
+	return ad_replace_data(ad, type, data, len);
 }
 
 static bool data_match(const void *data, const void *user_data)
diff --git a/src/shared/ad.h b/src/shared/ad.h
index 8d705323b..a31df0fe5 100644
--- a/src/shared/ad.h
+++ b/src/shared/ad.h
@@ -147,6 +147,12 @@ bool bt_ad_add_appearance(struct bt_ad *ad, uint16_t appearance);
 
 void bt_ad_clear_appearance(struct bt_ad *ad);
 
+bool bt_ad_add_flags(struct bt_ad *ad, uint8_t *flags, size_t len);
+
+bool bt_ad_has_flags(struct bt_ad *ad);
+
+void bt_ad_clear_flags(struct bt_ad *ad);
+
 bool bt_ad_add_data(struct bt_ad *ad, uint8_t type, void *data, size_t len);
 
 bool bt_ad_has_data(struct bt_ad *ad, const struct bt_ad_data *data);
-- 
2.14.3


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

* [PATCH v3 3/8] advertising: Add implementation of Discoverable property
  2018-05-22  9:50 [PATCH v3 1/8] doc/advertising-api: Add Discoverable property Luiz Augusto von Dentz
  2018-05-22  9:50 ` [PATCH v3 2/8] shared/ad: Add function to manipulate flags Luiz Augusto von Dentz
@ 2018-05-22  9:50 ` Luiz Augusto von Dentz
  2018-05-22  9:50 ` [PATCH v3 4/8] client: Add advertise.discoverable command Luiz Augusto von Dentz
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-22  9:50 UTC (permalink / raw)
  To: linux-bluetooth

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

This parses the contents of Discoverable property and add it to AD data
directly using bt_ad_add_flags.
---
 src/advertising.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/src/advertising.c b/src/advertising.c
index b087b48b7..cba30ada0 100644
--- a/src/advertising.c
+++ b/src/advertising.c
@@ -641,6 +641,56 @@ fail:
 	return false;
 }
 
+static bool set_flags(struct btd_adv_client *client, uint8_t flags)
+{
+	if (!flags) {
+		bt_ad_clear_flags(client->data);
+		return true;
+	}
+
+	/* Set BR/EDR Not Supported for LE only */
+	if (!btd_adapter_get_bredr(client->manager->adapter))
+		flags |= 0x04;
+
+	if (!bt_ad_add_flags(client->data, &flags, 1))
+		return false;
+
+	return true;
+}
+
+static bool parse_discoverable(DBusMessageIter *iter,
+				struct btd_adv_client *client)
+{
+	uint8_t flags;
+	dbus_bool_t discoverable;
+
+	if (!iter) {
+		bt_ad_clear_flags(client->data);
+		return true;
+	}
+
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_BOOLEAN)
+		return false;
+
+	dbus_message_iter_get_basic(iter, &discoverable);
+
+	if (discoverable)
+		flags = 0x02;
+	else
+		flags = 0x00;
+
+	if (!set_flags(client , flags))
+		goto fail;
+
+	DBG("Adding Flags 0x%02x", flags);
+
+	return true;
+
+fail:
+	bt_ad_clear_flags(client->data);
+	return false;
+}
+
 static struct adv_parser {
 	const char *name;
 	bool (*func)(DBusMessageIter *iter, struct btd_adv_client *client);
@@ -656,6 +706,7 @@ static struct adv_parser {
 	{ "Duration", parse_duration },
 	{ "Timeout", parse_timeout },
 	{ "Data", parse_data },
+	{ "Discoverable", parse_discoverable },
 	{ },
 };
 
@@ -737,7 +788,8 @@ static int refresh_adv(struct btd_adv_client *client, mgmt_request_func_t func)
 	if (client->type == AD_TYPE_PERIPHERAL) {
 		flags = MGMT_ADV_FLAG_CONNECTABLE;
 
-		if (btd_adapter_get_discoverable(client->manager->adapter))
+		if (btd_adapter_get_discoverable(client->manager->adapter) &&
+				!(bt_ad_has_flags(client->data)))
 			flags |= MGMT_ADV_FLAG_DISCOV;
 	}
 
@@ -881,6 +933,18 @@ static DBusMessage *parse_advertisement(struct btd_adv_client *client)
 		}
 	}
 
+	/* BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part C page 2042:
+	 * A device in the broadcast mode shall not set the
+	 * ‘LE General Discoverable Mode’ flag or the
+	 * ‘LE Limited Discoverable Mode’ flag in the Flags AD Type as
+	 * defined in [Core Specification Supplement], Part A, Section 1.3.
+	 */
+	if (client->type == AD_TYPE_BROADCAST &&
+				bt_ad_has_flags(client->data)) {
+		error("Broadcast cannot set flags");
+		goto fail;
+	}
+
 	err = refresh_adv(client, add_adv_callback);
 	if (!err)
 		return NULL;
-- 
2.14.3


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

* [PATCH v3 4/8] client: Add advertise.discoverable command
  2018-05-22  9:50 [PATCH v3 1/8] doc/advertising-api: Add Discoverable property Luiz Augusto von Dentz
  2018-05-22  9:50 ` [PATCH v3 2/8] shared/ad: Add function to manipulate flags Luiz Augusto von Dentz
  2018-05-22  9:50 ` [PATCH v3 3/8] advertising: Add implementation of Discoverable property Luiz Augusto von Dentz
@ 2018-05-22  9:50 ` Luiz Augusto von Dentz
  2018-05-22  9:50 ` [PATCH v3 5/8] client: Print AD Data and Discoverable once registered Luiz Augusto von Dentz
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-22  9:50 UTC (permalink / raw)
  To: linux-bluetooth

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

This adds advertise.discoverable command which can be used to set it
own instance:

[bluetooth]# advertise.discoverable on
[bluetooth]# advertise on

@ MGMT Command: Add Advertising (0x003e) plen 14
        Instance: 1
        Flags: 0x00000001
          Switch into Connectable mode
        Duration: 0
        Timeout: 0
        Advertising data length: 3
        Flags: 0x02
          LE General Discoverable Mode
        Scan response length: 0
< HCI Command: LE Set Advertising Data (0x08|0x0008) plen 32
        Length: 3
        Flags: 0x02
          LE General Discoverable Mode
---
 client/advertising.c | 35 +++++++++++++++++++++++++++++++++++
 client/advertising.h |  1 +
 client/main.c        | 17 +++++++++++++++++
 3 files changed, 53 insertions(+)

diff --git a/client/advertising.c b/client/advertising.c
index 39f99467b..cb0ca4a57 100644
--- a/client/advertising.c
+++ b/client/advertising.c
@@ -71,6 +71,7 @@ static struct ad {
 	struct service_data service;
 	struct manufacturer_data manufacturer;
 	struct data data;
+	bool discoverable;
 	bool tx_power;
 	bool name;
 	bool appearance;
@@ -401,6 +402,21 @@ static gboolean get_data(const GDBusPropertyTable *property,
 	return TRUE;
 }
 
+static gboolean discoverable_exists(const GDBusPropertyTable *property,
+							void *data)
+{
+	return ad.discoverable;
+}
+
+static gboolean get_discoverable(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *user_data)
+{
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
+							&ad.discoverable);
+
+	return TRUE;
+}
+
 static const GDBusPropertyTable ad_props[] = {
 	{ "Type", "s", get_type },
 	{ "ServiceUUIDs", "as", get_uuids, NULL, uuids_exists },
@@ -408,6 +424,7 @@ static const GDBusPropertyTable ad_props[] = {
 	{ "ManufacturerData", "a{qv}", get_manufacturer_data, NULL,
 						manufacturer_data_exists },
 	{ "Data", "a{yv}", get_data, NULL, data_exists },
+	{ "Discoverable", "b", get_discoverable, NULL, discoverable_exists },
 	{ "Includes", "as", get_includes, NULL, includes_exists },
 	{ "LocalName", "s", get_local_name, NULL, local_name_exits },
 	{ "Appearance", "q", get_appearance, NULL, appearance_exits },
@@ -708,6 +725,24 @@ void ad_disable_data(DBusConnection *conn)
 	return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
+void ad_advertise_discoverable(DBusConnection *conn, dbus_bool_t *value)
+{
+	if (!value) {
+		bt_shell_printf("Discoverable: %s\n",
+				ad.discoverable ? "on" : "off");
+		return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+	}
+
+	if (ad.discoverable == *value)
+		return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+
+	ad.discoverable = *value;
+
+	g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE, "Discoverable");
+
+	return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
 void ad_advertise_tx_power(DBusConnection *conn, dbus_bool_t *value)
 {
 	if (!value) {
diff --git a/client/advertising.h b/client/advertising.h
index 12b4d69c1..599190866 100644
--- a/client/advertising.h
+++ b/client/advertising.h
@@ -39,3 +39,4 @@ void ad_advertise_duration(DBusConnection *conn, long int *value);
 void ad_advertise_timeout(DBusConnection *conn, long int *value);
 void ad_advertise_data(DBusConnection *conn, int argc, char *argv[]);
 void ad_disable_data(DBusConnection *conn);
+void ad_advertise_discoverable(DBusConnection *conn, dbus_bool_t *value);
diff --git a/client/main.c b/client/main.c
index 52d807946..26ce94947 100644
--- a/client/main.c
+++ b/client/main.c
@@ -2213,6 +2213,21 @@ static void cmd_advertise_data(int argc, char *argv[])
 	ad_advertise_data(dbus_conn, argc, argv);
 }
 
+static void cmd_advertise_discoverable(int argc, char *argv[])
+{
+	dbus_bool_t discoverable;
+
+	if (argc < 2) {
+		ad_advertise_discoverable(dbus_conn, NULL);
+		return;
+	}
+
+	if (!parse_argument(argc, argv, NULL, NULL, &discoverable, NULL))
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
+
+	ad_advertise_discoverable(dbus_conn, &discoverable);
+}
+
 static void cmd_advertise_tx_power(int argc, char *argv[])
 {
 	dbus_bool_t powered;
@@ -2403,6 +2418,8 @@ static const struct bt_shell_menu advertise_menu = {
 			"Set/Get advertise manufacturer data" },
 	{ "data", "[type] [data=xx xx ...]", cmd_advertise_data,
 			"Set/Get advertise data" },
+	{ "discoverable", "[on/off]", cmd_advertise_discoverable,
+			"Set/Get advertise discoverable" },
 	{ "tx-power", "[on/off]", cmd_advertise_tx_power,
 			"Show/Enable/Disable TX power to be advertised",
 							NULL },
-- 
2.14.3


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

* [PATCH v3 5/8] client: Print AD Data and Discoverable once registered
  2018-05-22  9:50 [PATCH v3 1/8] doc/advertising-api: Add Discoverable property Luiz Augusto von Dentz
                   ` (2 preceding siblings ...)
  2018-05-22  9:50 ` [PATCH v3 4/8] client: Add advertise.discoverable command Luiz Augusto von Dentz
@ 2018-05-22  9:50 ` Luiz Augusto von Dentz
  2018-05-22  9:50 ` [PATCH v3 6/8] doc/advertising-api: Add DiscoverableTimeout property Luiz Augusto von Dentz
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-22  9:50 UTC (permalink / raw)
  To: linux-bluetooth

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

This prints both Data and Discoverable if advertise command succeeds:

[bluetooth]# advertise.data 0x26 0x01 0x00
[bluetooth]# advertise.discoverable on
[bluetooth]# advertise on
Advertising object registered
Data Type: 0x26
  01 00                                            ..
Tx Power: off
Name: off
Apperance: off
Discoverable: on
---
 client/advertising.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/client/advertising.c b/client/advertising.c
index cb0ca4a57..8abf4785b 100644
--- a/client/advertising.c
+++ b/client/advertising.c
@@ -164,6 +164,11 @@ static void print_ad(void)
 						ad.manufacturer.data.len);
 	}
 
+	if (ad.data.data.len) {
+		bt_shell_printf("Data Type: 0x%02x\n", ad.data.type);
+		bt_shell_hexdump(ad.data.data.data, ad.data.data.len);
+	}
+
 	bt_shell_printf("Tx Power: %s\n", ad.tx_power ? "on" : "off");
 
 	if (ad.local_name)
@@ -179,6 +184,8 @@ static void print_ad(void)
 		bt_shell_printf("Apperance: %s\n",
 					ad.appearance ? "on" : "off");
 
+	bt_shell_printf("Discoverable: %s\n", ad.discoverable ? "on": "off");
+
 	if (ad.duration)
 		bt_shell_printf("Duration: %u sec\n", ad.duration);
 
-- 
2.14.3


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

* [PATCH v3 6/8] doc/advertising-api: Add DiscoverableTimeout property
  2018-05-22  9:50 [PATCH v3 1/8] doc/advertising-api: Add Discoverable property Luiz Augusto von Dentz
                   ` (3 preceding siblings ...)
  2018-05-22  9:50 ` [PATCH v3 5/8] client: Print AD Data and Discoverable once registered Luiz Augusto von Dentz
@ 2018-05-22  9:50 ` Luiz Augusto von Dentz
  2018-05-22  9:50 ` [PATCH v3 7/8] advertising: Add implementation of " Luiz Augusto von Dentz
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-22  9:50 UTC (permalink / raw)
  To: linux-bluetooth

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

This property can control how long an instance is visible.
---
 doc/advertising-api.txt | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/doc/advertising-api.txt b/doc/advertising-api.txt
index 96deeeccd..cfce0f9a3 100644
--- a/doc/advertising-api.txt
+++ b/doc/advertising-api.txt
@@ -86,6 +86,15 @@ Properties	string Type
 			Note: This property shall not be set when Type is set
 			to broadcast.
 
+		uint16 DiscoverableTimeout [Experimental]
+
+			The discoverable timeout in seconds. A value of zero
+			means that the timeout is disabled and it will stay in
+			discoverable/limited mode forever.
+
+			Note: This property shall not be set when Type is set
+			to broadcast.
+
 		array{string} Includes
 
 			List of features to be included in the advertising
-- 
2.14.3


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

* [PATCH v3 7/8] advertising: Add implementation of DiscoverableTimeout property
  2018-05-22  9:50 [PATCH v3 1/8] doc/advertising-api: Add Discoverable property Luiz Augusto von Dentz
                   ` (4 preceding siblings ...)
  2018-05-22  9:50 ` [PATCH v3 6/8] doc/advertising-api: Add DiscoverableTimeout property Luiz Augusto von Dentz
@ 2018-05-22  9:50 ` Luiz Augusto von Dentz
  2018-05-22  9:50 ` [PATCH v3 8/8] client: Add advertise.discoverable-timeout command Luiz Augusto von Dentz
  2018-05-22 10:25 ` [PATCH v3 1/8] doc/advertising-api: Add Discoverable property David Llewellyn-Jones
  7 siblings, 0 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-22  9:50 UTC (permalink / raw)
  To: linux-bluetooth

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

This parses the contents of DiscoverableTimeout property and add
a timeout handler which clears the discoverable when it expires.
---
 src/advertising.c | 122 +++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 94 insertions(+), 28 deletions(-)

diff --git a/src/advertising.c b/src/advertising.c
index cba30ada0..444effaab 100644
--- a/src/advertising.c
+++ b/src/advertising.c
@@ -65,7 +65,9 @@ struct btd_adv_client {
 	uint16_t appearance;
 	uint16_t duration;
 	uint16_t timeout;
+	uint16_t discoverable_to;
 	unsigned int to_id;
+	unsigned int disc_to_id;
 	GDBusClient *client;
 	GDBusProxy *proxy;
 	DBusMessage *reg;
@@ -102,6 +104,9 @@ static void client_free(void *data)
 	if (client->to_id > 0)
 		g_source_remove(client->to_id);
 
+	if (client->disc_to_id > 0)
+		g_source_remove(client->disc_to_id);
+
 	if (client->client) {
 		g_dbus_client_set_disconnect_watch(client->client, NULL, NULL);
 		g_dbus_client_unref(client->client);
@@ -691,25 +696,6 @@ fail:
 	return false;
 }
 
-static struct adv_parser {
-	const char *name;
-	bool (*func)(DBusMessageIter *iter, struct btd_adv_client *client);
-} parsers[] = {
-	{ "Type", parse_type },
-	{ "ServiceUUIDs", parse_service_uuids },
-	{ "SolicitUUIDs", parse_solicit_uuids },
-	{ "ManufacturerData", parse_manufacturer_data },
-	{ "ServiceData", parse_service_data },
-	{ "Includes", parse_includes },
-	{ "LocalName", parse_local_name },
-	{ "Appearance", parse_appearance },
-	{ "Duration", parse_duration },
-	{ "Timeout", parse_timeout },
-	{ "Data", parse_data },
-	{ "Discoverable", parse_discoverable },
-	{ },
-};
-
 static size_t calc_max_adv_len(struct btd_adv_client *client, uint32_t flags)
 {
 	size_t max = client->manager->max_adv_len;
@@ -843,6 +829,66 @@ static int refresh_adv(struct btd_adv_client *client, mgmt_request_func_t func)
 	return 0;
 }
 
+static gboolean client_discoverable_timeout(void *user_data)
+{
+	struct btd_adv_client *client = user_data;
+
+	DBG("");
+
+	client->disc_to_id = 0;
+
+	bt_ad_clear_flags(client->data);
+
+	refresh_adv(client, NULL);
+
+	return FALSE;
+}
+
+static bool parse_discoverable_timeout(DBusMessageIter *iter,
+					struct btd_adv_client *client)
+{
+	if (!iter) {
+		client->discoverable_to = 0;
+		g_source_remove(client->disc_to_id);
+		client->disc_to_id = 0;
+		return true;
+	}
+
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_UINT16)
+		return false;
+
+	dbus_message_iter_get_basic(iter, &client->discoverable_to);
+
+	if (client->disc_to_id)
+		g_source_remove(client->disc_to_id);
+
+	client->disc_to_id = g_timeout_add_seconds(client->discoverable_to,
+						client_discoverable_timeout,
+						client);
+
+	return true;
+}
+
+static struct adv_parser {
+	const char *name;
+	bool (*func)(DBusMessageIter *iter, struct btd_adv_client *client);
+} parsers[] = {
+	{ "Type", parse_type },
+	{ "ServiceUUIDs", parse_service_uuids },
+	{ "SolicitUUIDs", parse_solicit_uuids },
+	{ "ManufacturerData", parse_manufacturer_data },
+	{ "ServiceData", parse_service_data },
+	{ "Includes", parse_includes },
+	{ "LocalName", parse_local_name },
+	{ "Appearance", parse_appearance },
+	{ "Duration", parse_duration },
+	{ "Timeout", parse_timeout },
+	{ "Data", parse_data },
+	{ "Discoverable", parse_discoverable },
+	{ "DiscoverableTimeout", parse_discoverable_timeout },
+	{ },
+};
+
 static void properties_changed(GDBusProxy *proxy, const char *name,
 					DBusMessageIter *iter, void *user_data)
 {
@@ -933,15 +979,35 @@ static DBusMessage *parse_advertisement(struct btd_adv_client *client)
 		}
 	}
 
-	/* BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part C page 2042:
-	 * A device in the broadcast mode shall not set the
-	 * ‘LE General Discoverable Mode’ flag or the
-	 * ‘LE Limited Discoverable Mode’ flag in the Flags AD Type as
-	 * defined in [Core Specification Supplement], Part A, Section 1.3.
-	 */
-	if (client->type == AD_TYPE_BROADCAST &&
-				bt_ad_has_flags(client->data)) {
-		error("Broadcast cannot set flags");
+	if (bt_ad_has_flags(client->data)) {
+		/* BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part C
+		 * page 2042:
+		 * A device in the broadcast mode shall not set the
+		 * ‘LE General Discoverable Mode’ flag or the
+		 * ‘LE Limited Discoverable Mode’ flag in the Flags AD Type
+		 * as defined in [Core Specification Supplement], Part A,
+		 * Section 1.3.
+		 */
+		if (client->type == AD_TYPE_BROADCAST) {
+			error("Broadcast cannot set flags");
+			goto fail;
+		}
+
+		/* Set Limited Discoverable if DiscoverableTimeout is set */
+		if (client->disc_to_id && !set_flags(client, 0x01)) {
+			error("Failed to set Limited Discoverable Flag");
+			goto fail;
+		}
+	} else if (client->disc_to_id) {
+		/* Ignore DiscoverableTimeout if not discoverable */
+		g_source_remove(client->disc_to_id);
+		client->disc_to_id = 0;
+		client->discoverable_to = 0;
+	}
+
+	if (client->timeout && client->timeout < client->discoverable_to) {
+		/* DiscoverableTimeout must not be bigger than Timeout */
+		error("DiscoverableTimeout > Timeout");
 		goto fail;
 	}
 
-- 
2.14.3


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

* [PATCH v3 8/8] client: Add advertise.discoverable-timeout command
  2018-05-22  9:50 [PATCH v3 1/8] doc/advertising-api: Add Discoverable property Luiz Augusto von Dentz
                   ` (5 preceding siblings ...)
  2018-05-22  9:50 ` [PATCH v3 7/8] advertising: Add implementation of " Luiz Augusto von Dentz
@ 2018-05-22  9:50 ` Luiz Augusto von Dentz
  2018-05-22 10:25 ` [PATCH v3 1/8] doc/advertising-api: Add Discoverable property David Llewellyn-Jones
  7 siblings, 0 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-22  9:50 UTC (permalink / raw)
  To: linux-bluetooth

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

This adds advertise.discoverable-timeout command which can be used to
limit the amount of time the advertisement is discoverable:

[bluetooth]# advertise.discoverable on
[bluetooth]# advertise.discoverable-timeout 10
[bluetooth]# advertise on

@ MGMT Command: Add Advertising (0x003e) plen 14
        Instance: 1
        Flags: 0x00000001
          Switch into Connectable mode
        Duration: 0
        Timeout: 0
        Advertising data length: 3
        Flags: 0x02
          LE General Discoverable Mode
        Scan response length: 0
@ MGMT Event: Advertising Added (0x0023) plen 1
        Instance: 1
@ MGMT Event: Command Complete (0x0001) plen 4
      Add Advertising (0x003e) plen 1
        Status: Success (0x00)
        Instance: 1
@ MGMT Command: Add Advertising (0x003e) plen 14
        Instance: 1
        Flags: 0x00000001
          Switch into Connectable mode
        Duration: 0
        Timeout: 0
        Advertising data length: 3
        Flags: 0x00
        Scan response length: 0
---
 client/advertising.c | 38 ++++++++++++++++++++++++++++++++++++++
 client/advertising.h |  1 +
 client/main.c        | 22 ++++++++++++++++++++++
 3 files changed, 61 insertions(+)

diff --git a/client/advertising.c b/client/advertising.c
index 8abf4785b..73f2f3df8 100644
--- a/client/advertising.c
+++ b/client/advertising.c
@@ -66,6 +66,7 @@ static struct ad {
 	uint16_t local_appearance;
 	uint16_t duration;
 	uint16_t timeout;
+	uint16_t discoverable_to;
 	char **uuids;
 	size_t uuids_len;
 	struct service_data service;
@@ -424,6 +425,21 @@ static gboolean get_discoverable(const GDBusPropertyTable *property,
 	return TRUE;
 }
 
+static gboolean discoverable_timeout_exits(const GDBusPropertyTable *property,
+							void *data)
+{
+	return ad.discoverable_to;
+}
+
+static gboolean get_discoverable_timeout(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *user_data)
+{
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16,
+							&ad.discoverable_to);
+
+	return TRUE;
+}
+
 static const GDBusPropertyTable ad_props[] = {
 	{ "Type", "s", get_type },
 	{ "ServiceUUIDs", "as", get_uuids, NULL, uuids_exists },
@@ -432,6 +448,8 @@ static const GDBusPropertyTable ad_props[] = {
 						manufacturer_data_exists },
 	{ "Data", "a{yv}", get_data, NULL, data_exists },
 	{ "Discoverable", "b", get_discoverable, NULL, discoverable_exists },
+	{ "DiscoverableTimeout", "q", get_discoverable_timeout, NULL,
+						discoverable_timeout_exits },
 	{ "Includes", "as", get_includes, NULL, includes_exists },
 	{ "LocalName", "s", get_local_name, NULL, local_name_exits },
 	{ "Appearance", "q", get_appearance, NULL, appearance_exits },
@@ -750,6 +768,26 @@ void ad_advertise_discoverable(DBusConnection *conn, dbus_bool_t *value)
 	return bt_shell_noninteractive_quit(EXIT_SUCCESS);
 }
 
+void ad_advertise_discoverable_timeout(DBusConnection *conn, long int *value)
+{
+	if (!value) {
+		if (ad.discoverable_to)
+			bt_shell_printf("Timeout: %u sec\n",
+					ad.discoverable_to);
+		return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+	}
+
+	if (ad.discoverable_to == *value)
+		return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+
+	ad.discoverable_to = *value;
+
+	g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE,
+					"DiscoverableTimeout");
+
+	return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
 void ad_advertise_tx_power(DBusConnection *conn, dbus_bool_t *value)
 {
 	if (!value) {
diff --git a/client/advertising.h b/client/advertising.h
index 599190866..fe3a7c8c6 100644
--- a/client/advertising.h
+++ b/client/advertising.h
@@ -40,3 +40,4 @@ void ad_advertise_timeout(DBusConnection *conn, long int *value);
 void ad_advertise_data(DBusConnection *conn, int argc, char *argv[]);
 void ad_disable_data(DBusConnection *conn);
 void ad_advertise_discoverable(DBusConnection *conn, dbus_bool_t *value);
+void ad_advertise_discoverable_timeout(DBusConnection *conn, long int *value);
diff --git a/client/main.c b/client/main.c
index 26ce94947..180f841ae 100644
--- a/client/main.c
+++ b/client/main.c
@@ -2228,6 +2228,25 @@ static void cmd_advertise_discoverable(int argc, char *argv[])
 	ad_advertise_discoverable(dbus_conn, &discoverable);
 }
 
+static void cmd_advertise_discoverable_timeout(int argc, char *argv[])
+{
+	long int value;
+	char *endptr = NULL;
+
+	if (argc < 2) {
+		ad_advertise_discoverable_timeout(dbus_conn, NULL);
+		return;
+	}
+
+	value = strtol(argv[1], &endptr, 0);
+	if (!endptr || *endptr != '\0' || value > UINT16_MAX) {
+		bt_shell_printf("Invalid argument\n");
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
+	}
+
+	ad_advertise_discoverable_timeout(dbus_conn, &value);
+}
+
 static void cmd_advertise_tx_power(int argc, char *argv[])
 {
 	dbus_bool_t powered;
@@ -2420,6 +2439,9 @@ static const struct bt_shell_menu advertise_menu = {
 			"Set/Get advertise data" },
 	{ "discoverable", "[on/off]", cmd_advertise_discoverable,
 			"Set/Get advertise discoverable" },
+	{ "discoverable-timeout", "[seconds]",
+			cmd_advertise_discoverable_timeout,
+			"Set/Get advertise discoverable timeout" },
 	{ "tx-power", "[on/off]", cmd_advertise_tx_power,
 			"Show/Enable/Disable TX power to be advertised",
 							NULL },
-- 
2.14.3


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

* Re: [PATCH v3 1/8] doc/advertising-api: Add Discoverable property
  2018-05-22  9:50 [PATCH v3 1/8] doc/advertising-api: Add Discoverable property Luiz Augusto von Dentz
                   ` (6 preceding siblings ...)
  2018-05-22  9:50 ` [PATCH v3 8/8] client: Add advertise.discoverable-timeout command Luiz Augusto von Dentz
@ 2018-05-22 10:25 ` David Llewellyn-Jones
  2018-05-22 10:45   ` Luiz Augusto von Dentz
  7 siblings, 1 reply; 12+ messages in thread
From: David Llewellyn-Jones @ 2018-05-22 10:25 UTC (permalink / raw)
  To: Luiz Augusto von Dentz, linux-bluetooth

On 22/05/18 10:50, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> 
> This adds Discoverable which the application can use in case it want
> to set the General Discoverable flag per instance.
> 
> Note: This would allow for example an application to advertise as
> discoverable even if the adapter is not discoverable which may be
> required by dual-mode as it may not require BR/EDR to be discoverable.

Thanks for these patches Luiz. I'm not sure whether it's useful for me
to comment on them, or whether this is just part of the process of them
winding their way towards a release.

Is there anything helpful I can do with regards these?

David
-- 
Website: http://www.flypig.co.uk

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

* Re: [PATCH v3 1/8] doc/advertising-api: Add Discoverable property
  2018-05-22 10:25 ` [PATCH v3 1/8] doc/advertising-api: Add Discoverable property David Llewellyn-Jones
@ 2018-05-22 10:45   ` Luiz Augusto von Dentz
  2018-05-22 10:52     ` David Llewellyn-Jones
  0 siblings, 1 reply; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-22 10:45 UTC (permalink / raw)
  To: David Llewellyn-Jones; +Cc: linux-bluetooth@vger.kernel.org

Hi David,

On Tue, May 22, 2018 at 1:25 PM, David Llewellyn-Jones
<david@flypig.co.uk> wrote:
> On 22/05/18 10:50, Luiz Augusto von Dentz wrote:
>> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>>
>> This adds Discoverable which the application can use in case it want
>> to set the General Discoverable flag per instance.
>>
>> Note: This would allow for example an application to advertise as
>> discoverable even if the adapter is not discoverable which may be
>> required by dual-mode as it may not require BR/EDR to be discoverable.
>
> Thanks for these patches Luiz. I'm not sure whether it's useful for me
> to comment on them, or whether this is just part of the process of them
> winding their way towards a release.
>
> Is there anything helpful I can do with regards these?

It is just the regular process, Marcel made some comments that this
set should fix, but feel free to comment if you find there is
something that we should address.


-- 
Luiz Augusto von Dentz

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

* Re: [PATCH v3 1/8] doc/advertising-api: Add Discoverable property
  2018-05-22 10:45   ` Luiz Augusto von Dentz
@ 2018-05-22 10:52     ` David Llewellyn-Jones
  2018-05-24 11:05       ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 12+ messages in thread
From: David Llewellyn-Jones @ 2018-05-22 10:52 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth@vger.kernel.org

Hi Luiz,

On 22/05/18 11:45, Luiz Augusto von Dentz wrote:
> Hi David,
> 
> On Tue, May 22, 2018 at 1:25 PM, David Llewellyn-Jones
> <david@flypig.co.uk> wrote:
>> On 22/05/18 10:50, Luiz Augusto von Dentz wrote:
>>> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>>>
>>> This adds Discoverable which the application can use in case it want
>>> to set the General Discoverable flag per instance.
>>>
>>> Note: This would allow for example an application to advertise as
>>> discoverable even if the adapter is not discoverable which may be
>>> required by dual-mode as it may not require BR/EDR to be discoverable.
>>
>> Thanks for these patches Luiz. I'm not sure whether it's useful for me
>> to comment on them, or whether this is just part of the process of them
>> winding their way towards a release.
>>
>> Is there anything helpful I can do with regards these?
> 
> It is just the regular process, Marcel made some comments that this
> set should fix, but feel free to comment if you find there is
> something that we should address.

Okay, thank you for clarifying. I'd hesitate to make comments without
having tried it, so I'll give it a go and see if anything comes up.

Thanks for all of your work on this. It'll be great to have this
controllable.

David
-- 
Website: http://www.flypig.co.uk

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

* Re: [PATCH v3 1/8] doc/advertising-api: Add Discoverable property
  2018-05-22 10:52     ` David Llewellyn-Jones
@ 2018-05-24 11:05       ` Luiz Augusto von Dentz
  0 siblings, 0 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-24 11:05 UTC (permalink / raw)
  To: David Llewellyn-Jones; +Cc: linux-bluetooth@vger.kernel.org

Hi,

On Tue, May 22, 2018 at 1:52 PM, David Llewellyn-Jones
<david@flypig.co.uk> wrote:
> Hi Luiz,
>
> On 22/05/18 11:45, Luiz Augusto von Dentz wrote:
>> Hi David,
>>
>> On Tue, May 22, 2018 at 1:25 PM, David Llewellyn-Jones
>> <david@flypig.co.uk> wrote:
>>> On 22/05/18 10:50, Luiz Augusto von Dentz wrote:
>>>> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>>>>
>>>> This adds Discoverable which the application can use in case it want
>>>> to set the General Discoverable flag per instance.
>>>>
>>>> Note: This would allow for example an application to advertise as
>>>> discoverable even if the adapter is not discoverable which may be
>>>> required by dual-mode as it may not require BR/EDR to be discoverable.
>>>
>>> Thanks for these patches Luiz. I'm not sure whether it's useful for me
>>> to comment on them, or whether this is just part of the process of them
>>> winding their way towards a release.
>>>
>>> Is there anything helpful I can do with regards these?
>>
>> It is just the regular process, Marcel made some comments that this
>> set should fix, but feel free to comment if you find there is
>> something that we should address.
>
> Okay, thank you for clarifying. I'd hesitate to make comments without
> having tried it, so I'll give it a go and see if anything comes up.
>
> Thanks for all of your work on this. It'll be great to have this
> controllable.

Applied.

-- 
Luiz Augusto von Dentz

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

end of thread, other threads:[~2018-05-24 11:05 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-05-22  9:50 [PATCH v3 1/8] doc/advertising-api: Add Discoverable property Luiz Augusto von Dentz
2018-05-22  9:50 ` [PATCH v3 2/8] shared/ad: Add function to manipulate flags Luiz Augusto von Dentz
2018-05-22  9:50 ` [PATCH v3 3/8] advertising: Add implementation of Discoverable property Luiz Augusto von Dentz
2018-05-22  9:50 ` [PATCH v3 4/8] client: Add advertise.discoverable command Luiz Augusto von Dentz
2018-05-22  9:50 ` [PATCH v3 5/8] client: Print AD Data and Discoverable once registered Luiz Augusto von Dentz
2018-05-22  9:50 ` [PATCH v3 6/8] doc/advertising-api: Add DiscoverableTimeout property Luiz Augusto von Dentz
2018-05-22  9:50 ` [PATCH v3 7/8] advertising: Add implementation of " Luiz Augusto von Dentz
2018-05-22  9:50 ` [PATCH v3 8/8] client: Add advertise.discoverable-timeout command Luiz Augusto von Dentz
2018-05-22 10:25 ` [PATCH v3 1/8] doc/advertising-api: Add Discoverable property David Llewellyn-Jones
2018-05-22 10:45   ` Luiz Augusto von Dentz
2018-05-22 10:52     ` David Llewellyn-Jones
2018-05-24 11:05       ` 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).