linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Daniel Winkler <danielwinkler@google.com>
To: luiz.von.dentz@intel.com
Cc: linux-bluetooth@vger.kernel.org,
	chromeos-bluetooth-upstreaming@chromium.org,
	Daniel Winkler <danielwinkler@google.com>,
	Sonny Sasaka <sonnysasaka@chromium.org>,
	Alain Michaud <alainm@chromium.org>
Subject: [Bluez PATCH v4 05/10] advertising: Parse intervals and tx power from adv
Date: Thu,  1 Oct 2020 16:01:47 -0700	[thread overview]
Message-ID: <20201001155738.Bluez.v4.5.Ic4a3667da774f5f34477d5168a68a9280657e2da@changeid> (raw)
In-Reply-To: <20201001230152.2422908-1-danielwinkler@google.com>

This change adds parsers for the advertising intervals and tx power
properties of the LEAdvertisement1 object. It validates that each field
adheres to the 5.2 spec, and that min and max intervals are compatible
with each other, i.e. that min interval is less than max interval.

A note here for maintainers: The tx power that is sent in the hci
parameter command is an int8_t, but as far as I can tell, there is no
clean way to use a signed 8-bit integer in dbus. The dbus byte type
seems incompatible with negative values in high-level languages (python)
without awkward usage manipulation on the client side. For this reason,
I chose to use an int16_t type for the tx power dbus field, which is
then downcasted to the int8_t in bluetoothd, which at least makes the
signed-ness of the type crystal clear to the dbus client that uses it.

This change is manually verified by ensuring the intervals and tx power
parameters are correctly parsed from the LEAdvertisement1 object, and
that the parse fails if the parameters are incorrect or not compatible
with each other.

Reviewed-by: Sonny Sasaka <sonnysasaka@chromium.org>
Reviewed-by: Alain Michaud <alainm@chromium.org>
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 src/advertising.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 89 insertions(+)

diff --git a/src/advertising.c b/src/advertising.c
index 7c7599552..3690a2aac 100644
--- a/src/advertising.c
+++ b/src/advertising.c
@@ -54,6 +54,11 @@ struct btd_adv_manager {
 #define AD_TYPE_BROADCAST 0
 #define AD_TYPE_PERIPHERAL 1
 
+/* BLUETOOTH SPECIFICATION Version 5.2 | Vol 4, Part E, page 2585
+ * defines tx power value indicating no preference
+ */
+#define ADV_TX_POWER_NO_PREFERENCE 0x7F
+
 struct btd_adv_client {
 	struct btd_adv_manager *manager;
 	char *owner;
@@ -74,6 +79,9 @@ struct btd_adv_client {
 	struct bt_ad *data;
 	struct bt_ad *scan;
 	uint8_t instance;
+	uint32_t min_interval;
+	uint32_t max_interval;
+	int8_t tx_power;
 };
 
 struct dbus_obj_match {
@@ -937,6 +945,74 @@ static bool parse_secondary(DBusMessageIter *iter,
 	return false;
 }
 
+static bool parse_min_interval(DBusMessageIter *iter,
+					struct btd_adv_client *client)
+{
+	if (!iter)
+		return false;
+
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_UINT32)
+		return false;
+
+	dbus_message_iter_get_basic(iter, &client->min_interval);
+
+	/* BLUETOOTH SPECIFICATION Version 5.2 | Vol 4, Part E, page 2584
+	 * defines acceptable interval range
+	 */
+	if (client->min_interval < 0x20 || client->min_interval > 0xFFFFFF) {
+		client->min_interval = 0;
+		return false;
+	}
+
+	return true;
+}
+
+static bool parse_max_interval(DBusMessageIter *iter,
+					struct btd_adv_client *client)
+{
+	if (!iter)
+		return false;
+
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_UINT32)
+		return false;
+
+	dbus_message_iter_get_basic(iter, &client->max_interval);
+
+	/* BLUETOOTH SPECIFICATION Version 5.2 | Vol 4, Part E, page 2584
+	 * defines acceptable interval range
+	 */
+	if (client->max_interval < 0x20 || client->max_interval > 0xFFFFFF) {
+		client->max_interval = 0;
+		return false;
+	}
+
+	return true;
+}
+
+static bool parse_tx_power(DBusMessageIter *iter,
+					struct btd_adv_client *client)
+{
+	int16_t val;
+
+	if (!iter)
+		return false;
+
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INT16)
+		return false;
+
+	dbus_message_iter_get_basic(iter, &val);
+
+	/* BLUETOOTH SPECIFICATION Version 5.2 | Vol 4, Part E, page 2585
+	 * defines acceptable tx power range
+	 */
+	if (val < -127 || val > 20)
+		return false;
+
+	client->tx_power = val;
+
+	return true;
+}
+
 static struct adv_parser {
 	const char *name;
 	bool (*func)(DBusMessageIter *iter, struct btd_adv_client *client);
@@ -955,6 +1031,9 @@ static struct adv_parser {
 	{ "Discoverable", parse_discoverable },
 	{ "DiscoverableTimeout", parse_discoverable_timeout },
 	{ "SecondaryChannel", parse_secondary },
+	{ "MinInterval", parse_min_interval },
+	{ "MaxInterval", parse_max_interval },
+	{ "TxPower", parse_tx_power },
 	{ },
 };
 
@@ -1083,6 +1162,13 @@ static DBusMessage *parse_advertisement(struct btd_adv_client *client)
 		goto fail;
 	}
 
+	if (client->min_interval > client->max_interval) {
+		/* Min interval must not be bigger than max interval */
+		error("MinInterval must be less than MaxInterval (%lu > %lu)",
+				client->min_interval, client->max_interval);
+		goto fail;
+	}
+
 	err = refresh_adv(client, add_adv_callback, &client->add_adv_id);
 	if (!err)
 		return NULL;
@@ -1158,6 +1244,9 @@ static struct btd_adv_client *client_create(struct btd_adv_manager *manager,
 
 	client->manager = manager;
 	client->appearance = UINT16_MAX;
+	client->tx_power = ADV_TX_POWER_NO_PREFERENCE;
+	client->min_interval = 0;
+	client->max_interval = 0;
 
 	return client;
 
-- 
2.28.0.709.gb0816b6eb0-goog


  parent reply	other threads:[~2020-10-01 23:02 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-01 23:01 [Bluez PATCH v4 00/10] Bluetooth: Add new MGMT interface for advertising add Daniel Winkler
2020-10-01 23:01 ` [Bluez PATCH v4 01/10] doc/advertising-api: update API with new interface Daniel Winkler
2020-10-27 21:59   ` Luiz Augusto von Dentz
2020-10-01 23:01 ` [Bluez PATCH v4 02/10] doc/mgmt-api: Add new Advertising MGMT interfaces to mgmt-api Daniel Winkler
2020-10-01 23:01 ` [Bluez PATCH v4 03/10] doc/mgmt-api: Update controller capabilities MGMT command in mgmt-api Daniel Winkler
2020-10-01 23:01 ` [Bluez PATCH v4 04/10] advertising: Detect if extended advertising mgmt commands are supported Daniel Winkler
2020-10-01 23:01 ` Daniel Winkler [this message]
2020-10-27 22:03   ` [Bluez PATCH v4 05/10] advertising: Parse intervals and tx power from adv Luiz Augusto von Dentz
2020-10-01 23:01 ` [Bluez PATCH v4 06/10] advertising: Use new mgmt interface for advertising add Daniel Winkler
2020-10-01 23:01 ` [Bluez PATCH v4 07/10] advertising: Query LE TX range at manager initialization Daniel Winkler
2020-10-27 22:08   ` Luiz Augusto von Dentz
2020-10-01 23:01 ` [Bluez PATCH v4 08/10] advertising: Expose SupportedCapabilities for advertising Daniel Winkler
2020-10-27 22:05   ` Luiz Augusto von Dentz
2020-10-01 23:01 ` [Bluez PATCH v4 09/10] client: Add SupportedCapabilities to bluetoothctl Daniel Winkler
2020-10-01 23:01 ` [Bluez PATCH v4 10/10] monitor: Add new MGMT adv commands and events to monitor Daniel Winkler
2020-10-12 15:53 ` [Bluez PATCH v4 00/10] Bluetooth: Add new MGMT interface for advertising add Daniel Winkler
2020-10-26 22:02 ` Daniel Winkler
2020-10-27 22:13   ` Luiz Augusto von Dentz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201001155738.Bluez.v4.5.Ic4a3667da774f5f34477d5168a68a9280657e2da@changeid \
    --to=danielwinkler@google.com \
    --cc=alainm@chromium.org \
    --cc=chromeos-bluetooth-upstreaming@chromium.org \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=luiz.von.dentz@intel.com \
    --cc=sonnysasaka@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).