All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/8] Bluetooth: Add macros for advertising instance flags
@ 2015-03-26  1:53 Arman Uguray
  2015-03-26  1:53 ` [PATCH v2 2/8] Bluetooth: Support the "connectable mode" adv flag Arman Uguray
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Arman Uguray @ 2015-03-26  1:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Arman Uguray

This patch adds macro definitions for possible advertising instance
flags that can be passed to the "Add Advertising" command.

Signed-off-by: Arman Uguray <armansito@chromium.org>
---
 include/net/bluetooth/mgmt.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 68abd4b..b831242 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -554,6 +554,14 @@ struct mgmt_rp_add_advertising {
 	__u8	instance;
 } __packed;
 
+#define MGMT_ADV_FLAG_CONNECTABLE	BIT(0)
+#define MGMT_ADV_FLAG_DISCOV		BIT(1)
+#define MGMT_ADV_FLAG_LIMITED_DISCOV	BIT(2)
+#define MGMT_ADV_FLAG_MANAGED_FLAGS	BIT(3)
+#define MGMT_ADV_FLAG_TX_POWER		BIT(4)
+#define MGMT_ADV_FLAG_APPEARANCE	BIT(5)
+#define MGMT_ADV_FLAG_LOCAL_NAME	BIT(6)
+
 #define MGMT_OP_REMOVE_ADVERTISING	0x003F
 struct mgmt_cp_remove_advertising {
 	__u8	instance;
-- 
2.2.0.rc0.207.ga3a616c


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

* [PATCH v2 2/8] Bluetooth: Support the "connectable mode" adv flag
  2015-03-26  1:53 [PATCH v2 1/8] Bluetooth: Add macros for advertising instance flags Arman Uguray
@ 2015-03-26  1:53 ` Arman Uguray
  2015-03-26  1:53 ` [PATCH v2 3/8] Bluetooth: Support the "discoverable" " Arman Uguray
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Arman Uguray @ 2015-03-26  1:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Arman Uguray

This patch adds support for the "connectable mode" flag of the
Add Advertising command.

Signed-off-by: Arman Uguray <armansito@chromium.org>
---
 net/bluetooth/mgmt.c | 87 +++++++++++++++++++++++++++++++++-------------------
 1 file changed, 56 insertions(+), 31 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 38b03bd..e6280dc 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1013,11 +1013,8 @@ static void update_adv_data_for_instance(struct hci_request *req, u8 instance)
 	hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
 }
 
-static void update_adv_data(struct hci_request *req)
+static u8 get_current_adv_instance(struct hci_dev *hdev)
 {
-	struct hci_dev *hdev = req->hdev;
-	u8 instance;
-
 	/* The "Set Advertising" setting supersedes the "Add Advertising"
 	 * setting. Here we set the advertising data based on which
 	 * setting was set. When neither apply, default to the global settings,
@@ -1025,9 +1022,54 @@ static void update_adv_data(struct hci_request *req)
 	 */
 	if (hci_dev_test_flag(hdev, HCI_ADVERTISING_INSTANCE) &&
 	    !hci_dev_test_flag(hdev, HCI_ADVERTISING))
-		instance = 0x01;
-	else
-		instance = 0x00;
+		return 0x01;
+
+	return 0x00;
+}
+
+static bool get_connectable(struct hci_dev *hdev)
+{
+	struct mgmt_pending_cmd *cmd;
+
+	/* If there's a pending mgmt command the flag will not yet have
+	 * it's final value, so check for this first.
+	 */
+	cmd = pending_find(MGMT_OP_SET_CONNECTABLE, hdev);
+	if (cmd) {
+		struct mgmt_mode *cp = cmd->param;
+
+		return cp->val;
+	}
+
+	return hci_dev_test_flag(hdev, HCI_CONNECTABLE);
+}
+
+static u32 get_adv_instance_flags(struct hci_dev *hdev, u8 instance)
+{
+	u32 flags;
+
+	if (instance > 0x01)
+		return 0;
+
+	if (instance == 1)
+		return hdev->adv_instance.flags;
+
+	flags = 0;
+
+	/* For instance 0, assemble the flags from global settings */
+	if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE) ||
+	    get_connectable(hdev))
+		flags |= MGMT_ADV_FLAG_CONNECTABLE;
+
+	/* TODO: Add the rest of the flags */
+
+	return flags;
+}
+
+static void update_adv_data(struct hci_request *req)
+{
+	struct hci_dev *hdev = req->hdev;
+	u8 instance = get_current_adv_instance(hdev);
 
 	update_adv_data_for_instance(req, instance);
 }
@@ -1159,22 +1201,6 @@ static void update_class(struct hci_request *req)
 	hci_req_add(req, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod);
 }
 
-static bool get_connectable(struct hci_dev *hdev)
-{
-	struct mgmt_pending_cmd *cmd;
-
-	/* If there's a pending mgmt command the flag will not yet have
-	 * it's final value, so check for this first.
-	 */
-	cmd = pending_find(MGMT_OP_SET_CONNECTABLE, hdev);
-	if (cmd) {
-		struct mgmt_mode *cp = cmd->param;
-		return cp->val;
-	}
-
-	return hci_dev_test_flag(hdev, HCI_CONNECTABLE);
-}
-
 static void disable_advertising(struct hci_request *req)
 {
 	u8 enable = 0x00;
@@ -1188,6 +1214,8 @@ static void enable_advertising(struct hci_request *req)
 	struct hci_cp_le_set_adv_param cp;
 	u8 own_addr_type, enable = 0x01;
 	bool connectable;
+	u8 instance;
+	u32 flags;
 
 	if (hci_conn_num(hdev, LE_LINK) > 0)
 		return;
@@ -1202,10 +1230,9 @@ static void enable_advertising(struct hci_request *req)
 	 */
 	hci_dev_clear_flag(hdev, HCI_LE_ADV);
 
-	if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE))
-		connectable = true;
-	else
-		connectable = get_connectable(hdev);
+	instance = get_current_adv_instance(hdev);
+	flags = get_adv_instance_flags(hdev, instance);
+	connectable = (flags & MGMT_ADV_FLAG_CONNECTABLE);
 
 	/* Set require_privacy to true only when non-connectable
 	 * advertising is used. In that case it is fine to use a
@@ -6623,10 +6650,8 @@ static int add_advertising(struct sock *sk, struct hci_dev *hdev,
 	flags = __le32_to_cpu(cp->flags);
 	timeout = __le16_to_cpu(cp->timeout);
 
-	/* The current implementation only supports adding one instance and
-	 * doesn't support flags.
-	 */
-	if (cp->instance != 0x01 || flags)
+	/* The current implementation only supports adding one instance */
+	if (cp->instance != 0x01)
 		return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING,
 				       MGMT_STATUS_INVALID_PARAMS);
 
-- 
2.2.0.rc0.207.ga3a616c


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

* [PATCH v2 3/8] Bluetooth: Support the "discoverable" adv flag
  2015-03-26  1:53 [PATCH v2 1/8] Bluetooth: Add macros for advertising instance flags Arman Uguray
  2015-03-26  1:53 ` [PATCH v2 2/8] Bluetooth: Support the "connectable mode" adv flag Arman Uguray
@ 2015-03-26  1:53 ` Arman Uguray
  2015-03-26  1:53 ` [PATCH v2 4/8] Bluetooth: Support the "limited-discoverable" " Arman Uguray
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Arman Uguray @ 2015-03-26  1:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Arman Uguray

This patch adds support for the "discoverable" flag of the
Add Advertising command.

Signed-off-by: Arman Uguray <armansito@chromium.org>
---
 net/bluetooth/mgmt.c | 38 ++++++++++++++++++++++++++++++--------
 1 file changed, 30 insertions(+), 8 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index e6280dc..03ddcfe 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -975,13 +975,28 @@ static u8 create_default_adv_data(struct hci_dev *hdev, u8 *ptr)
 
 static u8 create_instance_adv_data(struct hci_dev *hdev, u8 *ptr)
 {
-	/* TODO: Set the appropriate entries based on advertising instance flags
-	 * here once flags other than 0 are supported.
-	 */
+	u8 ad_len = 0, flags = 0;
+
+	if (hdev->adv_instance.flags & MGMT_ADV_FLAG_DISCOV)
+		flags |= LE_AD_GENERAL;
+
+	if (flags) {
+		if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
+			flags |= LE_AD_NO_BREDR;
+
+		ptr[0] = 0x02;
+		ptr[1] = EIR_FLAGS;
+		ptr[2] = flags;
+
+		ad_len += 3;
+		ptr += 3;
+	}
+
 	memcpy(ptr, hdev->adv_instance.adv_data,
 	       hdev->adv_instance.adv_data_len);
+	ad_len += hdev->adv_instance.adv_data_len;
 
-	return hdev->adv_instance.adv_data_len;
+	return ad_len;
 }
 
 static void update_adv_data_for_instance(struct hci_request *req, u8 instance)
@@ -6556,12 +6571,16 @@ static int read_adv_features(struct sock *sk, struct hci_dev *hdev,
 }
 
 static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data,
-			      u8 len)
+			      u8 len, bool is_adv_data)
 {
 	u8 max_len = HCI_MAX_AD_LENGTH;
 	int i, cur_len;
+	bool flags_managed = false;
 
-	/* TODO: Correctly reduce len based on adv_flags. */
+	if (is_adv_data && (adv_flags & MGMT_ADV_FLAG_DISCOV)) {
+		flags_managed = true;
+		max_len -= 3;
+	}
 
 	if (len > max_len)
 		return false;
@@ -6570,6 +6589,9 @@ static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data,
 	for (i = 0, cur_len = 0; i < len; i += (cur_len + 1)) {
 		cur_len = data[i];
 
+		if (flags_managed && data[i + 1] == EIR_FLAGS)
+			return false;
+
 		/* If the current field length would exceed the total data
 		 * length, then it's invalid.
 		 */
@@ -6671,9 +6693,9 @@ static int add_advertising(struct sock *sk, struct hci_dev *hdev,
 		goto unlock;
 	}
 
-	if (!tlv_data_is_valid(hdev, flags, cp->data, cp->adv_data_len) ||
+	if (!tlv_data_is_valid(hdev, flags, cp->data, cp->adv_data_len, true) ||
 	    !tlv_data_is_valid(hdev, flags, cp->data + cp->adv_data_len,
-			       cp->scan_rsp_len)) {
+			       cp->scan_rsp_len, false)) {
 		err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING,
 				      MGMT_STATUS_INVALID_PARAMS);
 		goto unlock;
-- 
2.2.0.rc0.207.ga3a616c


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

* [PATCH v2 4/8] Bluetooth: Support the "limited-discoverable" adv flag
  2015-03-26  1:53 [PATCH v2 1/8] Bluetooth: Add macros for advertising instance flags Arman Uguray
  2015-03-26  1:53 ` [PATCH v2 2/8] Bluetooth: Support the "connectable mode" adv flag Arman Uguray
  2015-03-26  1:53 ` [PATCH v2 3/8] Bluetooth: Support the "discoverable" " Arman Uguray
@ 2015-03-26  1:53 ` Arman Uguray
  2015-03-26  1:53 ` [PATCH v2 5/8] Bluetooth: Support the "managed-flags" " Arman Uguray
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Arman Uguray @ 2015-03-26  1:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Arman Uguray

This patch adds support for the "limited-discoverable" flag of the
Add Advertising command.

Signed-off-by: Arman Uguray <armansito@chromium.org>
---
 net/bluetooth/mgmt.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 03ddcfe..4cb02f3 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -977,9 +977,15 @@ static u8 create_instance_adv_data(struct hci_dev *hdev, u8 *ptr)
 {
 	u8 ad_len = 0, flags = 0;
 
+	/* The Add Advertising command allows userspace to set both the general
+	 * and limited discoverable flags.
+	 */
 	if (hdev->adv_instance.flags & MGMT_ADV_FLAG_DISCOV)
 		flags |= LE_AD_GENERAL;
 
+	if (hdev->adv_instance.flags & MGMT_ADV_FLAG_LIMITED_DISCOV)
+		flags |= LE_AD_LIMITED;
+
 	if (flags) {
 		if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
 			flags |= LE_AD_NO_BREDR;
@@ -6576,8 +6582,9 @@ static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data,
 	u8 max_len = HCI_MAX_AD_LENGTH;
 	int i, cur_len;
 	bool flags_managed = false;
+	u32 flags_params = MGMT_ADV_FLAG_DISCOV | MGMT_ADV_FLAG_LIMITED_DISCOV;
 
-	if (is_adv_data && (adv_flags & MGMT_ADV_FLAG_DISCOV)) {
+	if (is_adv_data && (adv_flags & flags_params)) {
 		flags_managed = true;
 		max_len -= 3;
 	}
-- 
2.2.0.rc0.207.ga3a616c


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

* [PATCH v2 5/8] Bluetooth: Support the "managed-flags" adv flag
  2015-03-26  1:53 [PATCH v2 1/8] Bluetooth: Add macros for advertising instance flags Arman Uguray
                   ` (2 preceding siblings ...)
  2015-03-26  1:53 ` [PATCH v2 4/8] Bluetooth: Support the "limited-discoverable" " Arman Uguray
@ 2015-03-26  1:53 ` Arman Uguray
  2015-03-26  1:53 ` [PATCH v2 6/8] Bluetooth: Support the "tx-power" " Arman Uguray
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Arman Uguray @ 2015-03-26  1:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Arman Uguray

This patch adds support for the "managed-flags" flag of the Add
Advertising command.

Signed-off-by: Arman Uguray <armansito@chromium.org>
---
 net/bluetooth/mgmt.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 4cb02f3..0ce4bd6 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -986,7 +986,13 @@ static u8 create_instance_adv_data(struct hci_dev *hdev, u8 *ptr)
 	if (hdev->adv_instance.flags & MGMT_ADV_FLAG_LIMITED_DISCOV)
 		flags |= LE_AD_LIMITED;
 
-	if (flags) {
+	if (flags || (hdev->adv_instance.flags & MGMT_ADV_FLAG_MANAGED_FLAGS)) {
+		/* If a discovery flag wasn't provided, simply use the global
+		 * settings.
+		 */
+		if (!flags)
+			flags |= get_adv_discov_flags(hdev);
+
 		if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
 			flags |= LE_AD_NO_BREDR;
 
@@ -6582,7 +6588,8 @@ static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data,
 	u8 max_len = HCI_MAX_AD_LENGTH;
 	int i, cur_len;
 	bool flags_managed = false;
-	u32 flags_params = MGMT_ADV_FLAG_DISCOV | MGMT_ADV_FLAG_LIMITED_DISCOV;
+	u32 flags_params = MGMT_ADV_FLAG_DISCOV | MGMT_ADV_FLAG_LIMITED_DISCOV |
+			   MGMT_ADV_FLAG_MANAGED_FLAGS;
 
 	if (is_adv_data && (adv_flags & flags_params)) {
 		flags_managed = true;
-- 
2.2.0.rc0.207.ga3a616c


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

* [PATCH v2 6/8] Bluetooth: Support the "tx-power" adv flag
  2015-03-26  1:53 [PATCH v2 1/8] Bluetooth: Add macros for advertising instance flags Arman Uguray
                   ` (3 preceding siblings ...)
  2015-03-26  1:53 ` [PATCH v2 5/8] Bluetooth: Support the "managed-flags" " Arman Uguray
@ 2015-03-26  1:53 ` Arman Uguray
  2015-03-26  1:53 ` [PATCH v2 7/8] Bluetooth: Update supported_flags for AD features Arman Uguray
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Arman Uguray @ 2015-03-26  1:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Arman Uguray

This patch adds support for the "tx-power" flag of the Add
Advertising command.

Signed-off-by: Arman Uguray <armansito@chromium.org>
---
 net/bluetooth/mgmt.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 0ce4bd6..fd41b20 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1004,6 +1004,16 @@ static u8 create_instance_adv_data(struct hci_dev *hdev, u8 *ptr)
 		ptr += 3;
 	}
 
+	if (hdev->adv_tx_power != HCI_TX_POWER_INVALID &&
+	    (hdev->adv_instance.flags & MGMT_ADV_FLAG_TX_POWER)) {
+		ptr[0] = 0x02;
+		ptr[1] = EIR_TX_POWER;
+		ptr[2] = (u8)hdev->adv_tx_power;
+
+		ad_len += 3;
+		ptr += 3;
+	}
+
 	memcpy(ptr, hdev->adv_instance.adv_data,
 	       hdev->adv_instance.adv_data_len);
 	ad_len += hdev->adv_instance.adv_data_len;
@@ -6588,6 +6598,7 @@ static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data,
 	u8 max_len = HCI_MAX_AD_LENGTH;
 	int i, cur_len;
 	bool flags_managed = false;
+	bool tx_power_managed = false;
 	u32 flags_params = MGMT_ADV_FLAG_DISCOV | MGMT_ADV_FLAG_LIMITED_DISCOV |
 			   MGMT_ADV_FLAG_MANAGED_FLAGS;
 
@@ -6596,6 +6607,11 @@ static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data,
 		max_len -= 3;
 	}
 
+	if (is_adv_data && (adv_flags & MGMT_ADV_FLAG_TX_POWER)) {
+		tx_power_managed = true;
+		max_len -= 3;
+	}
+
 	if (len > max_len)
 		return false;
 
@@ -6606,6 +6622,9 @@ static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data,
 		if (flags_managed && data[i + 1] == EIR_FLAGS)
 			return false;
 
+		if (tx_power_managed && data[i + 1] == EIR_TX_POWER)
+			return false;
+
 		/* If the current field length would exceed the total data
 		 * length, then it's invalid.
 		 */
-- 
2.2.0.rc0.207.ga3a616c


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

* [PATCH v2 7/8] Bluetooth: Update supported_flags for AD features
  2015-03-26  1:53 [PATCH v2 1/8] Bluetooth: Add macros for advertising instance flags Arman Uguray
                   ` (4 preceding siblings ...)
  2015-03-26  1:53 ` [PATCH v2 6/8] Bluetooth: Support the "tx-power" " Arman Uguray
@ 2015-03-26  1:53 ` Arman Uguray
  2015-03-26  1:53 ` [PATCH v2 8/8] Bluetooth: Unify advertising data code paths Arman Uguray
  2015-03-26  2:32 ` [PATCH v2 1/8] Bluetooth: Add macros for advertising instance flags Marcel Holtmann
  7 siblings, 0 replies; 9+ messages in thread
From: Arman Uguray @ 2015-03-26  1:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Arman Uguray

This patch updates the "supported_flags" parameter returned from the
"Read Advertising Features" command. Add Advertising will now return
an error if an unsupported flag is provided.

Signed-off-by: Arman Uguray <armansito@chromium.org>
---
 net/bluetooth/mgmt.c | 32 +++++++++++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index fd41b20..71d4130 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -6540,6 +6540,21 @@ done:
 	return err;
 }
 
+static u32 get_supported_adv_flags(struct hci_dev *hdev)
+{
+	u32 flags = 0;
+
+	flags |= MGMT_ADV_FLAG_CONNECTABLE;
+	flags |= MGMT_ADV_FLAG_DISCOV;
+	flags |= MGMT_ADV_FLAG_LIMITED_DISCOV;
+	flags |= MGMT_ADV_FLAG_MANAGED_FLAGS;
+
+	if (hdev->adv_tx_power != HCI_TX_POWER_INVALID)
+		flags |= MGMT_ADV_FLAG_TX_POWER;
+
+	return flags;
+}
+
 static int read_adv_features(struct sock *sk, struct hci_dev *hdev,
 			     void *data, u16 data_len)
 {
@@ -6547,9 +6562,14 @@ static int read_adv_features(struct sock *sk, struct hci_dev *hdev,
 	size_t rp_len;
 	int err;
 	bool instance;
+	u32 supported_flags;
 
 	BT_DBG("%s", hdev->name);
 
+	if (!lmp_le_capable(hdev))
+		return mgmt_cmd_status(sk, hdev->id, MGMT_OP_READ_ADV_FEATURES,
+				       MGMT_STATUS_REJECTED);
+
 	hci_dev_lock(hdev);
 
 	rp_len = sizeof(*rp);
@@ -6567,7 +6587,9 @@ static int read_adv_features(struct sock *sk, struct hci_dev *hdev,
 		return -ENOMEM;
 	}
 
-	rp->supported_flags = cpu_to_le32(0);
+	supported_flags = get_supported_adv_flags(hdev);
+
+	rp->supported_flags = cpu_to_le32(supported_flags);
 	rp->max_adv_data_len = HCI_MAX_AD_LENGTH;
 	rp->max_scan_rsp_len = HCI_MAX_AD_LENGTH;
 	rp->max_instances = 1;
@@ -6689,6 +6711,7 @@ static int add_advertising(struct sock *sk, struct hci_dev *hdev,
 	struct mgmt_cp_add_advertising *cp = data;
 	struct mgmt_rp_add_advertising rp;
 	u32 flags;
+	u32 supported_flags;
 	u8 status;
 	u16 timeout;
 	int err;
@@ -6705,8 +6728,11 @@ static int add_advertising(struct sock *sk, struct hci_dev *hdev,
 	flags = __le32_to_cpu(cp->flags);
 	timeout = __le16_to_cpu(cp->timeout);
 
-	/* The current implementation only supports adding one instance */
-	if (cp->instance != 0x01)
+	/* The current implementation only supports adding one instance and only
+	 * a subset of the specified flags.
+	 */
+	supported_flags = get_supported_adv_flags(hdev);
+	if (cp->instance != 0x01 || (flags & ~supported_flags))
 		return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING,
 				       MGMT_STATUS_INVALID_PARAMS);
 
-- 
2.2.0.rc0.207.ga3a616c


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

* [PATCH v2 8/8] Bluetooth: Unify advertising data code paths
  2015-03-26  1:53 [PATCH v2 1/8] Bluetooth: Add macros for advertising instance flags Arman Uguray
                   ` (5 preceding siblings ...)
  2015-03-26  1:53 ` [PATCH v2 7/8] Bluetooth: Update supported_flags for AD features Arman Uguray
@ 2015-03-26  1:53 ` Arman Uguray
  2015-03-26  2:32 ` [PATCH v2 1/8] Bluetooth: Add macros for advertising instance flags Marcel Holtmann
  7 siblings, 0 replies; 9+ messages in thread
From: Arman Uguray @ 2015-03-26  1:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Arman Uguray

This patch simplifies the code paths for assembling the advertising data
used by advertising instances 0 and 1.

Signed-off-by: Arman Uguray <armansito@chromium.org>
---
 net/bluetooth/mgmt.c | 155 +++++++++++++++++++++------------------------------
 1 file changed, 64 insertions(+), 91 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 71d4130..5fc1ebf 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -941,52 +941,73 @@ static u8 get_adv_discov_flags(struct hci_dev *hdev)
 	return 0;
 }
 
-static u8 create_default_adv_data(struct hci_dev *hdev, u8 *ptr)
+static u8 get_current_adv_instance(struct hci_dev *hdev)
 {
-	u8 ad_len = 0, flags = 0;
-
-	flags |= get_adv_discov_flags(hdev);
+	/* The "Set Advertising" setting supersedes the "Add Advertising"
+	 * setting. Here we set the advertising data based on which
+	 * setting was set. When neither apply, default to the global settings,
+	 * represented by instance "0".
+	 */
+	if (hci_dev_test_flag(hdev, HCI_ADVERTISING_INSTANCE) &&
+	    !hci_dev_test_flag(hdev, HCI_ADVERTISING))
+		return 0x01;
 
-	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
-		flags |= LE_AD_NO_BREDR;
+	return 0x00;
+}
 
-	if (flags) {
-		BT_DBG("adv flags 0x%02x", flags);
+static bool get_connectable(struct hci_dev *hdev)
+{
+	struct mgmt_pending_cmd *cmd;
 
-		ptr[0] = 2;
-		ptr[1] = EIR_FLAGS;
-		ptr[2] = flags;
+	/* If there's a pending mgmt command the flag will not yet have
+	 * it's final value, so check for this first.
+	 */
+	cmd = pending_find(MGMT_OP_SET_CONNECTABLE, hdev);
+	if (cmd) {
+		struct mgmt_mode *cp = cmd->param;
 
-		ad_len += 3;
-		ptr += 3;
+		return cp->val;
 	}
 
-	if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) {
-		ptr[0] = 2;
-		ptr[1] = EIR_TX_POWER;
-		ptr[2] = (u8) hdev->adv_tx_power;
+	return hci_dev_test_flag(hdev, HCI_CONNECTABLE);
+}
 
-		ad_len += 3;
-		ptr += 3;
-	}
+static u32 get_adv_instance_flags(struct hci_dev *hdev, u8 instance)
+{
+	u32 flags;
 
-	return ad_len;
+	if (instance > 0x01)
+		return 0;
+
+	if (instance == 0x01)
+		return hdev->adv_instance.flags;
+
+	/* Instance 0 always manages the "Tx Power" and "Flags" fields */
+	flags = MGMT_ADV_FLAG_TX_POWER | MGMT_ADV_FLAG_MANAGED_FLAGS;
+
+	/* For instance 0, assemble the flags from global settings */
+	if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE) ||
+	    get_connectable(hdev))
+		flags |= MGMT_ADV_FLAG_CONNECTABLE;
+
+	return flags;
 }
 
-static u8 create_instance_adv_data(struct hci_dev *hdev, u8 *ptr)
+static u8 create_instance_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
 {
 	u8 ad_len = 0, flags = 0;
+	u32 instance_flags = get_adv_instance_flags(hdev, instance);
 
 	/* The Add Advertising command allows userspace to set both the general
 	 * and limited discoverable flags.
 	 */
-	if (hdev->adv_instance.flags & MGMT_ADV_FLAG_DISCOV)
+	if (instance_flags & MGMT_ADV_FLAG_DISCOV)
 		flags |= LE_AD_GENERAL;
 
-	if (hdev->adv_instance.flags & MGMT_ADV_FLAG_LIMITED_DISCOV)
+	if (instance_flags & MGMT_ADV_FLAG_LIMITED_DISCOV)
 		flags |= LE_AD_LIMITED;
 
-	if (flags || (hdev->adv_instance.flags & MGMT_ADV_FLAG_MANAGED_FLAGS)) {
+	if (flags || (instance_flags & MGMT_ADV_FLAG_MANAGED_FLAGS)) {
 		/* If a discovery flag wasn't provided, simply use the global
 		 * settings.
 		 */
@@ -996,16 +1017,22 @@ static u8 create_instance_adv_data(struct hci_dev *hdev, u8 *ptr)
 		if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
 			flags |= LE_AD_NO_BREDR;
 
-		ptr[0] = 0x02;
-		ptr[1] = EIR_FLAGS;
-		ptr[2] = flags;
+		/* If flags would still be empty, then there is no need to
+		 * include the "Flags" AD field".
+		 */
+		if (flags) {
+			ptr[0] = 0x02;
+			ptr[1] = EIR_FLAGS;
+			ptr[2] = flags;
 
-		ad_len += 3;
-		ptr += 3;
+			ad_len += 3;
+			ptr += 3;
+		}
 	}
 
+	/* Provide Tx Power only if we can provide a valid value for it */
 	if (hdev->adv_tx_power != HCI_TX_POWER_INVALID &&
-	    (hdev->adv_instance.flags & MGMT_ADV_FLAG_TX_POWER)) {
+	    (instance_flags & MGMT_ADV_FLAG_TX_POWER)) {
 		ptr[0] = 0x02;
 		ptr[1] = EIR_TX_POWER;
 		ptr[2] = (u8)hdev->adv_tx_power;
@@ -1014,9 +1041,11 @@ static u8 create_instance_adv_data(struct hci_dev *hdev, u8 *ptr)
 		ptr += 3;
 	}
 
-	memcpy(ptr, hdev->adv_instance.adv_data,
-	       hdev->adv_instance.adv_data_len);
-	ad_len += hdev->adv_instance.adv_data_len;
+	if (instance) {
+		memcpy(ptr, hdev->adv_instance.adv_data,
+		       hdev->adv_instance.adv_data_len);
+		ad_len += hdev->adv_instance.adv_data_len;
+	}
 
 	return ad_len;
 }
@@ -1032,10 +1061,7 @@ static void update_adv_data_for_instance(struct hci_request *req, u8 instance)
 
 	memset(&cp, 0, sizeof(cp));
 
-	if (instance)
-		len = create_instance_adv_data(hdev, cp.data);
-	else
-		len = create_default_adv_data(hdev, cp.data);
+	len = create_instance_adv_data(hdev, instance, cp.data);
 
 	/* There's nothing to do if the data hasn't changed */
 	if (hdev->adv_data_len == len &&
@@ -1050,59 +1076,6 @@ static void update_adv_data_for_instance(struct hci_request *req, u8 instance)
 	hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
 }
 
-static u8 get_current_adv_instance(struct hci_dev *hdev)
-{
-	/* The "Set Advertising" setting supersedes the "Add Advertising"
-	 * setting. Here we set the advertising data based on which
-	 * setting was set. When neither apply, default to the global settings,
-	 * represented by instance "0".
-	 */
-	if (hci_dev_test_flag(hdev, HCI_ADVERTISING_INSTANCE) &&
-	    !hci_dev_test_flag(hdev, HCI_ADVERTISING))
-		return 0x01;
-
-	return 0x00;
-}
-
-static bool get_connectable(struct hci_dev *hdev)
-{
-	struct mgmt_pending_cmd *cmd;
-
-	/* If there's a pending mgmt command the flag will not yet have
-	 * it's final value, so check for this first.
-	 */
-	cmd = pending_find(MGMT_OP_SET_CONNECTABLE, hdev);
-	if (cmd) {
-		struct mgmt_mode *cp = cmd->param;
-
-		return cp->val;
-	}
-
-	return hci_dev_test_flag(hdev, HCI_CONNECTABLE);
-}
-
-static u32 get_adv_instance_flags(struct hci_dev *hdev, u8 instance)
-{
-	u32 flags;
-
-	if (instance > 0x01)
-		return 0;
-
-	if (instance == 1)
-		return hdev->adv_instance.flags;
-
-	flags = 0;
-
-	/* For instance 0, assemble the flags from global settings */
-	if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE) ||
-	    get_connectable(hdev))
-		flags |= MGMT_ADV_FLAG_CONNECTABLE;
-
-	/* TODO: Add the rest of the flags */
-
-	return flags;
-}
-
 static void update_adv_data(struct hci_request *req)
 {
 	struct hci_dev *hdev = req->hdev;
-- 
2.2.0.rc0.207.ga3a616c


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

* Re: [PATCH v2 1/8] Bluetooth: Add macros for advertising instance flags
  2015-03-26  1:53 [PATCH v2 1/8] Bluetooth: Add macros for advertising instance flags Arman Uguray
                   ` (6 preceding siblings ...)
  2015-03-26  1:53 ` [PATCH v2 8/8] Bluetooth: Unify advertising data code paths Arman Uguray
@ 2015-03-26  2:32 ` Marcel Holtmann
  7 siblings, 0 replies; 9+ messages in thread
From: Marcel Holtmann @ 2015-03-26  2:32 UTC (permalink / raw)
  To: Arman Uguray; +Cc: linux-bluetooth

Hi Arman,

> This patch adds macro definitions for possible advertising instance
> flags that can be passed to the "Add Advertising" command.
> 
> Signed-off-by: Arman Uguray <armansito@chromium.org>
> ---
> include/net/bluetooth/mgmt.h | 8 ++++++++
> 1 file changed, 8 insertions(+)

all 8 patches have been applied to bluetooth-next tree.

Regards

Marcel


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

end of thread, other threads:[~2015-03-26  2:32 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-26  1:53 [PATCH v2 1/8] Bluetooth: Add macros for advertising instance flags Arman Uguray
2015-03-26  1:53 ` [PATCH v2 2/8] Bluetooth: Support the "connectable mode" adv flag Arman Uguray
2015-03-26  1:53 ` [PATCH v2 3/8] Bluetooth: Support the "discoverable" " Arman Uguray
2015-03-26  1:53 ` [PATCH v2 4/8] Bluetooth: Support the "limited-discoverable" " Arman Uguray
2015-03-26  1:53 ` [PATCH v2 5/8] Bluetooth: Support the "managed-flags" " Arman Uguray
2015-03-26  1:53 ` [PATCH v2 6/8] Bluetooth: Support the "tx-power" " Arman Uguray
2015-03-26  1:53 ` [PATCH v2 7/8] Bluetooth: Update supported_flags for AD features Arman Uguray
2015-03-26  1:53 ` [PATCH v2 8/8] Bluetooth: Unify advertising data code paths Arman Uguray
2015-03-26  2:32 ` [PATCH v2 1/8] Bluetooth: Add macros for advertising instance flags Marcel Holtmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.