Commit 7087c4f6 authored by Luiz Augusto von Dentz's avatar Luiz Augusto von Dentz Committed by Marcel Holtmann

Bluetooth: Store advertising handle so it can be re-enabled

This stores the advertising handle/instance into hci_conn so it is
accessible when re-enabling the advertising once disconnected.
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent cafae4cd
...@@ -629,6 +629,7 @@ struct hci_conn { ...@@ -629,6 +629,7 @@ struct hci_conn {
__u8 init_addr_type; __u8 init_addr_type;
bdaddr_t resp_addr; bdaddr_t resp_addr;
__u8 resp_addr_type; __u8 resp_addr_type;
__u8 adv_instance;
__u16 handle; __u16 handle;
__u16 state; __u16 state;
__u8 mode; __u8 mode;
......
...@@ -2348,19 +2348,20 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) ...@@ -2348,19 +2348,20 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
if (conn) { if (conn) {
u8 type = conn->type;
mgmt_disconnect_failed(hdev, &conn->dst, conn->type, mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
conn->dst_type, status); conn->dst_type, status);
if (conn->type == LE_LINK) {
hdev->cur_adv_instance = conn->adv_instance;
hci_req_reenable_advertising(hdev);
}
/* If the disconnection failed for any reason, the upper layer /* If the disconnection failed for any reason, the upper layer
* does not retry to disconnect in current implementation. * does not retry to disconnect in current implementation.
* Hence, we need to do some basic cleanup here and re-enable * Hence, we need to do some basic cleanup here and re-enable
* advertising if necessary. * advertising if necessary.
*/ */
hci_conn_del(conn); hci_conn_del(conn);
if (type == LE_LINK)
hci_req_reenable_advertising(hdev);
} }
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
...@@ -2886,7 +2887,6 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -2886,7 +2887,6 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
struct hci_conn_params *params; struct hci_conn_params *params;
struct hci_conn *conn; struct hci_conn *conn;
bool mgmt_connected; bool mgmt_connected;
u8 type;
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
...@@ -2941,10 +2941,7 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -2941,10 +2941,7 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
} }
} }
type = conn->type;
hci_disconn_cfm(conn, ev->reason); hci_disconn_cfm(conn, ev->reason);
hci_conn_del(conn);
/* The suspend notifier is waiting for all devices to disconnect so /* The suspend notifier is waiting for all devices to disconnect so
* clear the bit from pending tasks and inform the wait queue. * clear the bit from pending tasks and inform the wait queue.
...@@ -2964,8 +2961,12 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -2964,8 +2961,12 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
* or until a connection is created or until the Advertising * or until a connection is created or until the Advertising
* is timed out due to Directed Advertising." * is timed out due to Directed Advertising."
*/ */
if (type == LE_LINK) if (conn->type == LE_LINK) {
hdev->cur_adv_instance = conn->adv_instance;
hci_req_reenable_advertising(hdev); hci_req_reenable_advertising(hdev);
}
hci_conn_del(conn);
unlock: unlock:
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
...@@ -5323,6 +5324,13 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, ...@@ -5323,6 +5324,13 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
conn->handle = handle; conn->handle = handle;
conn->state = BT_CONFIG; conn->state = BT_CONFIG;
/* Store current advertising instance as connection advertising instance
* when sotfware rotation is in use so it can be re-enabled when
* disconnected.
*/
if (!ext_adv_capable(hdev))
conn->adv_instance = hdev->cur_adv_instance;
conn->le_conn_interval = interval; conn->le_conn_interval = interval;
conn->le_conn_latency = latency; conn->le_conn_latency = latency;
conn->le_supv_timeout = supervision_timeout; conn->le_supv_timeout = supervision_timeout;
...@@ -5406,13 +5414,13 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -5406,13 +5414,13 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, struct sk_buff *skb)
{ {
struct hci_evt_le_ext_adv_set_term *ev = (void *) skb->data; struct hci_evt_le_ext_adv_set_term *ev = (void *) skb->data;
struct hci_conn *conn; struct hci_conn *conn;
struct adv_info *adv;
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
if (ev->status) { adv = hci_find_adv_instance(hdev, ev->handle);
struct adv_info *adv;
adv = hci_find_adv_instance(hdev, ev->handle); if (ev->status) {
if (!adv) if (!adv)
return; return;
...@@ -5423,9 +5431,15 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -5423,9 +5431,15 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, struct sk_buff *skb)
return; return;
} }
if (adv)
adv->enabled = false;
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->conn_handle)); conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->conn_handle));
if (conn) { if (conn) {
struct adv_info *adv_instance; /* Store handle in the connection so the correct advertising
* instance can be re-enabled when disconnected.
*/
conn->adv_instance = ev->handle;
if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM || if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM ||
bacmp(&conn->resp_addr, BDADDR_ANY)) bacmp(&conn->resp_addr, BDADDR_ANY))
...@@ -5436,9 +5450,8 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -5436,9 +5450,8 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, struct sk_buff *skb)
return; return;
} }
adv_instance = hci_find_adv_instance(hdev, ev->handle); if (adv)
if (adv_instance) bacpy(&conn->resp_addr, &adv->random_addr);
bacpy(&conn->resp_addr, &adv_instance->random_addr);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment