linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/8] doc/advertising-api: Add Discoverable property
@ 2018-05-21 14:07 Luiz Augusto von Dentz
  2018-05-21 14:07 ` [PATCH BlueZ] shared/util: Add definition to BLE-MIDI UUIDs Luiz Augusto von Dentz
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-21 14:07 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] 9+ messages in thread

* [PATCH BlueZ] shared/util: Add definition to BLE-MIDI UUIDs
  2018-05-21 14:07 [PATCH v2 1/8] doc/advertising-api: Add Discoverable property Luiz Augusto von Dentz
@ 2018-05-21 14:07 ` Luiz Augusto von Dentz
  2018-05-21 14:07 ` [PATCH v2 2/8] shared/ad: Add bt_ad_add_flags and bt_ad_clear_flags Luiz Augusto von Dentz
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-21 14:07 UTC (permalink / raw)
  To: linux-bluetooth

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

This adds both UUIDs used by MMA BLE-MIDI as used by the midi plugin.
---
 src/shared/util.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/shared/util.c b/src/shared/util.c
index 43a81afa0..78dded2f2 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -831,6 +831,9 @@ static const struct {
 	{ "6e400001-b5a3-f393-e0a9-e50e24dcca9e", "Nordic UART Service" },
 	{ "6e400002-b5a3-f393-e0a9-e50e24dcca9e", "Nordic UART TX"	},
 	{ "6e400003-b5a3-f393-e0a9-e50e24dcca9e", "Nordic UART RX"	},
+	/* MMA BLE-MIDI */
+	{ "03B80E5A-EDE8-4B33-A751-6CE34EC4C700", "MMA MIDI"		},
+	{ "7772E5DB-3868-4112-A1A9-F2669D106BF3", "MMA MIDI IO"		},
 	{ }
 };
 
-- 
2.14.3


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

* [PATCH v2 2/8] shared/ad: Add bt_ad_add_flags and bt_ad_clear_flags
  2018-05-21 14:07 [PATCH v2 1/8] doc/advertising-api: Add Discoverable property Luiz Augusto von Dentz
  2018-05-21 14:07 ` [PATCH BlueZ] shared/util: Add definition to BLE-MIDI UUIDs Luiz Augusto von Dentz
@ 2018-05-21 14:07 ` Luiz Augusto von Dentz
  2018-05-21 14:07 ` [PATCH v2 3/8] advertising: Add implementation of Discoverable property Luiz Augusto von Dentz
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-21 14:07 UTC (permalink / raw)
  To: linux-bluetooth

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

This adds basically functionality to add and remove AD flags.
---
 src/shared/ad.c | 92 +++++++++++++++++++++++++++++++++++++--------------------
 src/shared/ad.h |  4 +++
 2 files changed, 64 insertions(+), 32 deletions(-)

diff --git a/src/shared/ad.c b/src/shared/ad.c
index f0e62cef1..102fe0e13 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,25 @@ 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);
+}
+
+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 +917,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 +925,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..0e30cdca9 100644
--- a/src/shared/ad.h
+++ b/src/shared/ad.h
@@ -147,6 +147,10 @@ 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);
+
+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] 9+ messages in thread

* [PATCH v2 3/8] advertising: Add implementation of Discoverable property
  2018-05-21 14:07 [PATCH v2 1/8] doc/advertising-api: Add Discoverable property Luiz Augusto von Dentz
  2018-05-21 14:07 ` [PATCH BlueZ] shared/util: Add definition to BLE-MIDI UUIDs Luiz Augusto von Dentz
  2018-05-21 14:07 ` [PATCH v2 2/8] shared/ad: Add bt_ad_add_flags and bt_ad_clear_flags Luiz Augusto von Dentz
@ 2018-05-21 14:07 ` Luiz Augusto von Dentz
  2018-05-21 14:07 ` [PATCH v2 4/8] client: Add advertise.discoverable command Luiz Augusto von Dentz
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-21 14:07 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 | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 57 insertions(+), 2 deletions(-)

diff --git a/src/advertising.c b/src/advertising.c
index b087b48b7..1fd114490 100644
--- a/src/advertising.c
+++ b/src/advertising.c
@@ -641,6 +641,47 @@ fail:
 	return false;
 }
 
+static void clear_flags(struct btd_adv_client *client)
+{
+	bt_ad_clear_flags(client->data);
+	client->flags &= ~MGMT_ADV_FLAG_MANAGED_FLAGS;
+}
+
+static bool parse_discoverable(DBusMessageIter *iter,
+				struct btd_adv_client *client)
+{
+	uint8_t flags;
+	dbus_bool_t discoverable;
+
+	if (!iter) {
+		clear_flags(client);
+		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;
+
+	DBG("Adding Flags 0x%02x", flags);
+
+	if (!bt_ad_add_flags(client->data, &flags, 1))
+		goto fail;
+
+	client->flags |= MGMT_ADV_FLAG_MANAGED_FLAGS;
+
+	return true;
+
+fail:
+	clear_flags(client);
+	return false;
+}
+
 static struct adv_parser {
 	const char *name;
 	bool (*func)(DBusMessageIter *iter, struct btd_adv_client *client);
@@ -656,6 +697,7 @@ static struct adv_parser {
 	{ "Duration", parse_duration },
 	{ "Timeout", parse_timeout },
 	{ "Data", parse_data },
+	{ "Discoverable", parse_discoverable },
 	{ },
 };
 
@@ -737,11 +779,12 @@ 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) &&
+				!(client->flags & MGMT_ADV_FLAG_MANAGED_FLAGS))
 			flags |= MGMT_ADV_FLAG_DISCOV;
 	}
 
-	flags |= client->flags;
+	flags |= client->flags & ~MGMT_ADV_FLAG_MANAGED_FLAGS;
 
 	adv_data = generate_adv_data(client, &flags, &adv_data_len);
 	if (!adv_data || (adv_data_len > calc_max_adv_len(client, flags))) {
@@ -881,6 +924,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 &&
+				client->flags & MGMT_ADV_FLAG_MANAGED_FLAGS) {
+		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] 9+ messages in thread

* [PATCH v2 4/8] client: Add advertise.discoverable command
  2018-05-21 14:07 [PATCH v2 1/8] doc/advertising-api: Add Discoverable property Luiz Augusto von Dentz
                   ` (2 preceding siblings ...)
  2018-05-21 14:07 ` [PATCH v2 3/8] advertising: Add implementation of Discoverable property Luiz Augusto von Dentz
@ 2018-05-21 14:07 ` Luiz Augusto von Dentz
  2018-05-21 14:07 ` [PATCH v2 5/8] client: Print AD Data and Discoverable once registered Luiz Augusto von Dentz
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-21 14:07 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] 9+ messages in thread

* [PATCH v2 5/8] client: Print AD Data and Discoverable once registered
  2018-05-21 14:07 [PATCH v2 1/8] doc/advertising-api: Add Discoverable property Luiz Augusto von Dentz
                   ` (3 preceding siblings ...)
  2018-05-21 14:07 ` [PATCH v2 4/8] client: Add advertise.discoverable command Luiz Augusto von Dentz
@ 2018-05-21 14:07 ` Luiz Augusto von Dentz
  2018-05-21 14:07 ` [PATCH v2 6/8] doc/advertising-api: Add DiscoverableTimeout property Luiz Augusto von Dentz
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-21 14:07 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] 9+ messages in thread

* [PATCH v2 6/8] doc/advertising-api: Add DiscoverableTimeout property
  2018-05-21 14:07 [PATCH v2 1/8] doc/advertising-api: Add Discoverable property Luiz Augusto von Dentz
                   ` (4 preceding siblings ...)
  2018-05-21 14:07 ` [PATCH v2 5/8] client: Print AD Data and Discoverable once registered Luiz Augusto von Dentz
@ 2018-05-21 14:07 ` Luiz Augusto von Dentz
  2018-05-21 14:07 ` [PATCH v2 7/8] advertising: Add implementation of " Luiz Augusto von Dentz
  2018-05-21 14:07 ` [PATCH v2 8/8] client: Add advertise.discoverable-timeout command Luiz Augusto von Dentz
  7 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-21 14:07 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] 9+ messages in thread

* [PATCH v2 7/8] advertising: Add implementation of DiscoverableTimeout property
  2018-05-21 14:07 [PATCH v2 1/8] doc/advertising-api: Add Discoverable property Luiz Augusto von Dentz
                   ` (5 preceding siblings ...)
  2018-05-21 14:07 ` [PATCH v2 6/8] doc/advertising-api: Add DiscoverableTimeout property Luiz Augusto von Dentz
@ 2018-05-21 14:07 ` Luiz Augusto von Dentz
  2018-05-21 14:07 ` [PATCH v2 8/8] client: Add advertise.discoverable-timeout command Luiz Augusto von Dentz
  7 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-21 14:07 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 | 106 ++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 87 insertions(+), 19 deletions(-)

diff --git a/src/advertising.c b/src/advertising.c
index 1fd114490..2ec9468c4 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);
@@ -682,25 +687,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;
@@ -834,6 +820,68 @@ 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;
+	uint8_t flags = 0x00;
+
+	DBG("");
+
+	client->disc_to_id = 0;
+
+	if (!bt_ad_add_flags(client->data, &flags, 1))
+		return false;
+
+	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)
 {
@@ -936,6 +984,26 @@ static DBusMessage *parse_advertisement(struct btd_adv_client *client)
 		goto fail;
 	}
 
+	if (client->flags & MGMT_ADV_FLAG_MANAGED_FLAGS) {
+		/* Set Limited Discoverable of DiscoverableTimeout is set */
+		if (client->disc_to_id) {
+			uint8_t flags = 0x01;
+			if (!bt_ad_add_flags(client->data, &flags, 1))
+				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->discoverable_to) {
+		/* DiscoverableTimeout must not be bigger than Timeout */
+		error("DiscoverableTimeout > Timeout");
+		goto fail;
+	}
+
 	err = refresh_adv(client, add_adv_callback);
 	if (!err)
 		return NULL;
-- 
2.14.3


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

* [PATCH v2 8/8] client: Add advertise.discoverable-timeout command
  2018-05-21 14:07 [PATCH v2 1/8] doc/advertising-api: Add Discoverable property Luiz Augusto von Dentz
                   ` (6 preceding siblings ...)
  2018-05-21 14:07 ` [PATCH v2 7/8] advertising: Add implementation of " Luiz Augusto von Dentz
@ 2018-05-21 14:07 ` Luiz Augusto von Dentz
  7 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2018-05-21 14:07 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] 9+ messages in thread

end of thread, other threads:[~2018-05-21 14:07 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-05-21 14:07 [PATCH v2 1/8] doc/advertising-api: Add Discoverable property Luiz Augusto von Dentz
2018-05-21 14:07 ` [PATCH BlueZ] shared/util: Add definition to BLE-MIDI UUIDs Luiz Augusto von Dentz
2018-05-21 14:07 ` [PATCH v2 2/8] shared/ad: Add bt_ad_add_flags and bt_ad_clear_flags Luiz Augusto von Dentz
2018-05-21 14:07 ` [PATCH v2 3/8] advertising: Add implementation of Discoverable property Luiz Augusto von Dentz
2018-05-21 14:07 ` [PATCH v2 4/8] client: Add advertise.discoverable command Luiz Augusto von Dentz
2018-05-21 14:07 ` [PATCH v2 5/8] client: Print AD Data and Discoverable once registered Luiz Augusto von Dentz
2018-05-21 14:07 ` [PATCH v2 6/8] doc/advertising-api: Add DiscoverableTimeout property Luiz Augusto von Dentz
2018-05-21 14:07 ` [PATCH v2 7/8] advertising: Add implementation of " Luiz Augusto von Dentz
2018-05-21 14:07 ` [PATCH v2 8/8] client: Add advertise.discoverable-timeout command 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).