Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH 0/3] Bluetooth: LE Advertising fixes & improvements
@ 2013-10-05 10:01 johan.hedberg
  2013-10-05 10:01 ` [PATCH 1/3] Bluetooth: Rename HCI_LE_PERIPHERAL to HCI_ADVERTISING johan.hedberg
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: johan.hedberg @ 2013-10-05 10:01 UTC (permalink / raw)
  To: linux-bluetooth

Hi,

Here's a patch set to improve and fix LE advertising behavior. The first
one renames the used flag to something more appropriate, and the two
other ones fix advertising re-enablement due to the automatic disabling
that controllers do when they get a new connection.

Johan

----------------------------------------------------------------
Johan Hedberg (3):
      Bluetooth: Rename HCI_LE_PERIPHERAL to HCI_ADVERTISING
      Bluetooth: Add public mgmt function to send New Settings event
      Bluetooth: Fix re-enabling advertising after a connection

 include/net/bluetooth/hci.h      |  2 +-
 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/hci_conn.c         |  2 +-
 net/bluetooth/hci_core.c         |  2 +-
 net/bluetooth/hci_event.c        | 57 +++++++++++++++++++++++++++++++++++++---
 net/bluetooth/mgmt.c             | 23 +++++++++-------
 6 files changed, 71 insertions(+), 16 deletions(-)


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

* [PATCH 1/3] Bluetooth: Rename HCI_LE_PERIPHERAL to HCI_ADVERTISING
  2013-10-05 10:01 [PATCH 0/3] Bluetooth: LE Advertising fixes & improvements johan.hedberg
@ 2013-10-05 10:01 ` johan.hedberg
  2013-10-05 10:01 ` [PATCH 2/3] Bluetooth: Add public mgmt function to send New Settings event johan.hedberg
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: johan.hedberg @ 2013-10-05 10:01 UTC (permalink / raw)
  To: linux-bluetooth

From: Johan Hedberg <johan.hedberg@intel.com>

This flag is used to indicate whether we want to have advertising
enabled or not, so give it a more suitable name.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/hci.h |  2 +-
 net/bluetooth/hci_conn.c    |  2 +-
 net/bluetooth/hci_core.c    |  2 +-
 net/bluetooth/hci_event.c   |  6 +++---
 net/bluetooth/mgmt.c        | 18 +++++++++---------
 5 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index b90eec5..e8bba05 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -118,7 +118,7 @@ enum {
 	HCI_SSP_ENABLED,
 	HCI_HS_ENABLED,
 	HCI_LE_ENABLED,
-	HCI_LE_PERIPHERAL,
+	HCI_ADVERTISING,
 	HCI_CONNECTABLE,
 	HCI_DISCOVERABLE,
 	HCI_LINK_SECURITY,
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 08e601c..8b0d08f 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -546,7 +546,7 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
 {
 	struct hci_conn *conn;
 
-	if (test_bit(HCI_LE_PERIPHERAL, &hdev->flags))
+	if (test_bit(HCI_ADVERTISING, &hdev->flags))
 		return ERR_PTR(-ENOTSUPP);
 
 	conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 82dbdc6..aa63ebb 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1105,7 +1105,7 @@ static u8 create_ad(struct hci_dev *hdev, u8 *ptr)
 	u8 ad_len = 0, flags = 0;
 	size_t name_len;
 
-	if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
+	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
 		flags |= LE_AD_GENERAL;
 
 	if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 4785ab0..e1ad858 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -918,9 +918,9 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
 
 	if (!status) {
 		if (*sent)
-			set_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
+			set_bit(HCI_ADVERTISING, &hdev->dev_flags);
 		else
-			clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
+			clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
 	}
 
 	if (!test_bit(HCI_INIT, &hdev->flags)) {
@@ -1005,7 +1005,7 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
 		} else {
 			hdev->features[1][0] &= ~LMP_HOST_LE;
 			clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
-			clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
+			clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
 		}
 
 		if (sent->simul)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 16125ff9..7e43d37 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -425,7 +425,7 @@ static u32 get_current_settings(struct hci_dev *hdev)
 	if (test_bit(HCI_HS_ENABLED, &hdev->dev_flags))
 		settings |= MGMT_SETTING_HS;
 
-	if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
+	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
 		settings |= MGMT_SETTING_ADVERTISING;
 
 	return settings;
@@ -1463,8 +1463,8 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
 			changed = true;
 		}
 
-		if (!val && test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags)) {
-			clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
+		if (!val && test_bit(HCI_ADVERTISING, &hdev->dev_flags)) {
+			clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
 			changed = true;
 		}
 
@@ -1500,7 +1500,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
 
 	hci_req_init(&req, hdev);
 
-	if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags) && !val)
+	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags) && !val)
 		hci_req_add(&req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(val), &val);
 
 	hci_req_add(&req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp),
@@ -2888,7 +2888,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
 			goto failed;
 		}
 
-		if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags)) {
+		if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) {
 			err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
 					 MGMT_STATUS_REJECTED);
 			mgmt_pending_remove(cmd);
@@ -3236,13 +3236,13 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data, u1
 	hci_dev_lock(hdev);
 
 	val = !!cp->val;
-	enabled = test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
+	enabled = test_bit(HCI_ADVERTISING, &hdev->dev_flags);
 
 	if (!hdev_is_powered(hdev) || val == enabled) {
 		bool changed = false;
 
-		if (val != test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags)) {
-			change_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
+		if (val != test_bit(HCI_ADVERTISING, &hdev->dev_flags)) {
+			change_bit(HCI_ADVERTISING, &hdev->dev_flags);
 			changed = true;
 		}
 
@@ -3851,7 +3851,7 @@ static int powered_update_hci(struct hci_dev *hdev)
 				    &hdev->static_addr);
 	}
 
-	if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags)) {
+	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) {
 		u8 adv = 0x01;
 
 		hci_req_add(&req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(adv), &adv);
-- 
1.8.3.1


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

* [PATCH 2/3] Bluetooth: Add public mgmt function to send New Settings event
  2013-10-05 10:01 [PATCH 0/3] Bluetooth: LE Advertising fixes & improvements johan.hedberg
  2013-10-05 10:01 ` [PATCH 1/3] Bluetooth: Rename HCI_LE_PERIPHERAL to HCI_ADVERTISING johan.hedberg
@ 2013-10-05 10:01 ` johan.hedberg
  2013-10-05 10:01 ` [PATCH 3/3] Bluetooth: Fix re-enabling advertising after a connection johan.hedberg
  2013-10-05 10:04 ` [PATCH 0/3] Bluetooth: LE Advertising fixes & improvements Marcel Holtmann
  3 siblings, 0 replies; 5+ messages in thread
From: johan.hedberg @ 2013-10-05 10:01 UTC (permalink / raw)
  To: linux-bluetooth

From: Johan Hedberg <johan.hedberg@intel.com>

A function is needed so that the HCI event processing can ask the mgmt
code to emit a new settings event. This is necessary e.g. when the event
processing does updates to mgmt related states without any dependency of
actual mgmt commands.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/hci_core.h | 1 +
 net/bluetooth/mgmt.c             | 5 +++++
 2 files changed, 6 insertions(+)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index e09c305..079c5c5 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1123,6 +1123,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event);
 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
 int mgmt_index_added(struct hci_dev *hdev);
 int mgmt_index_removed(struct hci_dev *hdev);
+int mgmt_new_settings(struct hci_dev *hdev);
 int mgmt_set_powered_failed(struct hci_dev *hdev, int err);
 int mgmt_powered(struct hci_dev *hdev, u8 powered);
 int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 7e43d37..6e808d1 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -890,6 +890,11 @@ static int new_settings(struct hci_dev *hdev, struct sock *skip)
 	return mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), skip);
 }
 
+int mgmt_new_settings(struct hci_dev *hdev)
+{
+	return new_settings(hdev, NULL);
+}
+
 struct cmd_lookup {
 	struct sock *sk;
 	struct hci_dev *hdev;
-- 
1.8.3.1


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

* [PATCH 3/3] Bluetooth: Fix re-enabling advertising after a connection
  2013-10-05 10:01 [PATCH 0/3] Bluetooth: LE Advertising fixes & improvements johan.hedberg
  2013-10-05 10:01 ` [PATCH 1/3] Bluetooth: Rename HCI_LE_PERIPHERAL to HCI_ADVERTISING johan.hedberg
  2013-10-05 10:01 ` [PATCH 2/3] Bluetooth: Add public mgmt function to send New Settings event johan.hedberg
@ 2013-10-05 10:01 ` johan.hedberg
  2013-10-05 10:04 ` [PATCH 0/3] Bluetooth: LE Advertising fixes & improvements Marcel Holtmann
  3 siblings, 0 replies; 5+ messages in thread
From: johan.hedberg @ 2013-10-05 10:01 UTC (permalink / raw)
  To: linux-bluetooth

From: Johan Hedberg <johan.hedberg@intel.com>

LE controllers will automatically disable advertising whenever they
accept a new connection. In order not to fall out of sync with the
advertising setting we need to re-enable advertising whenever the last
LE connection drops. A failure to re-enable advertising should cause the
setting to be disabled, so this patch also calls mgmt_new_settings()
when this happens.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/hci_event.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 50 insertions(+), 1 deletion(-)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index e1ad858..6eaef6e 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1796,6 +1796,40 @@ static u8 hci_to_mgmt_reason(u8 err)
 	}
 }
 
+static void adv_enable_complete(struct hci_dev *hdev, u8 status)
+{
+	BT_DBG("%s status %u", hdev->name, status);
+
+	/* Clear the advertising mgmt setting if we failed to re-enable it */
+	if (status) {
+		clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
+		mgmt_new_settings(hdev);
+	}
+}
+
+static void reenable_advertising(struct hci_dev *hdev)
+{
+	struct hci_request req;
+	u8 enable = 0x01;
+
+	if (hdev->conn_hash.le_num)
+		return;
+
+	if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags))
+		return;
+
+	hci_req_init(&req, hdev);
+	hci_req_add(&req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
+
+	/* If this fails we have no option but to let user space know
+	 * that we've disabled advertising.
+	 */
+	if (hci_req_run(&req, adv_enable_complete) < 0) {
+		clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
+		mgmt_new_settings(hdev);
+	}
+}
+
 static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_disconn_complete *ev = (void *) skb->data;
@@ -1826,10 +1860,25 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	}
 
 	if (ev->status == 0) {
-		if (conn->type == ACL_LINK && conn->flush_key)
+		u8 type = conn->type;
+
+		if (type == ACL_LINK && conn->flush_key)
 			hci_remove_link_key(hdev, &conn->dst);
 		hci_proto_disconn_cfm(conn, ev->reason);
 		hci_conn_del(conn);
+
+		/* Re-enable advertising if necessary, since it might
+		 * have been disabled by the connection. From the
+		 * HCI_LE_Set_Advertise_Enable command description in
+		 * the core specification (v4.0):
+		 * "The Controller shall continue advertising until the Host
+		 * issues an LE_Set_Advertise_Enable command with
+		 * Advertising_Enable set to 0x00 (Advertising is disabled)
+		 * or until a connection is created or until the Advertising
+		 * is timed out due to Directed Advertising."
+		 */
+		if (type == LE_LINK)
+			reenable_advertising(hdev);
 	}
 
 unlock:
-- 
1.8.3.1


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

* Re: [PATCH 0/3] Bluetooth: LE Advertising fixes & improvements
  2013-10-05 10:01 [PATCH 0/3] Bluetooth: LE Advertising fixes & improvements johan.hedberg
                   ` (2 preceding siblings ...)
  2013-10-05 10:01 ` [PATCH 3/3] Bluetooth: Fix re-enabling advertising after a connection johan.hedberg
@ 2013-10-05 10:04 ` Marcel Holtmann
  3 siblings, 0 replies; 5+ messages in thread
From: Marcel Holtmann @ 2013-10-05 10:04 UTC (permalink / raw)
  To: johan.hedberg; +Cc: linux-bluetooth

Hi Johan,

> Here's a patch set to improve and fix LE advertising behavior. The first
> one renames the used flag to something more appropriate, and the two
> other ones fix advertising re-enablement due to the automatic disabling
> that controllers do when they get a new connection.
> 
> Johan
> 
> ----------------------------------------------------------------
> Johan Hedberg (3):
>      Bluetooth: Rename HCI_LE_PERIPHERAL to HCI_ADVERTISING
>      Bluetooth: Add public mgmt function to send New Settings event
>      Bluetooth: Fix re-enabling advertising after a connection
> 
> include/net/bluetooth/hci.h      |  2 +-
> include/net/bluetooth/hci_core.h |  1 +
> net/bluetooth/hci_conn.c         |  2 +-
> net/bluetooth/hci_core.c         |  2 +-
> net/bluetooth/hci_event.c        | 57 +++++++++++++++++++++++++++++++++++++---
> net/bluetooth/mgmt.c             | 23 +++++++++-------
> 6 files changed, 71 insertions(+), 16 deletions(-)

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

Regards

Marcel


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

end of thread, other threads:[~2013-10-05 10:04 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-05 10:01 [PATCH 0/3] Bluetooth: LE Advertising fixes & improvements johan.hedberg
2013-10-05 10:01 ` [PATCH 1/3] Bluetooth: Rename HCI_LE_PERIPHERAL to HCI_ADVERTISING johan.hedberg
2013-10-05 10:01 ` [PATCH 2/3] Bluetooth: Add public mgmt function to send New Settings event johan.hedberg
2013-10-05 10:01 ` [PATCH 3/3] Bluetooth: Fix re-enabling advertising after a connection johan.hedberg
2013-10-05 10:04 ` [PATCH 0/3] Bluetooth: LE Advertising fixes & improvements Marcel Holtmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox