* [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