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: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
parent
cafae4cd62
commit
7087c4f694
@ -629,6 +629,7 @@ struct hci_conn {
|
||||
__u8 init_addr_type;
|
||||
bdaddr_t resp_addr;
|
||||
__u8 resp_addr_type;
|
||||
__u8 adv_instance;
|
||||
__u16 handle;
|
||||
__u16 state;
|
||||
__u8 mode;
|
||||
|
@ -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));
|
||||
if (conn) {
|
||||
u8 type = conn->type;
|
||||
|
||||
mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
|
||||
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
|
||||
* does not retry to disconnect in current implementation.
|
||||
* Hence, we need to do some basic cleanup here and re-enable
|
||||
* advertising if necessary.
|
||||
*/
|
||||
hci_conn_del(conn);
|
||||
if (type == LE_LINK)
|
||||
hci_req_reenable_advertising(hdev);
|
||||
}
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
@ -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 *conn;
|
||||
bool mgmt_connected;
|
||||
u8 type;
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
type = conn->type;
|
||||
|
||||
hci_disconn_cfm(conn, ev->reason);
|
||||
hci_conn_del(conn);
|
||||
|
||||
/* The suspend notifier is waiting for all devices to disconnect so
|
||||
* 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)
|
||||
* or until a connection is created or until the 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_conn_del(conn);
|
||||
|
||||
unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
@ -5323,6 +5324,13 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
|
||||
conn->handle = handle;
|
||||
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_latency = latency;
|
||||
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)
|
||||
{
|
||||
struct hci_evt_le_ext_adv_set_term *ev = (void *) skb->data;
|
||||
struct hci_conn *conn;
|
||||
struct adv_info *adv;
|
||||
|
||||
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
|
||||
|
||||
if (ev->status) {
|
||||
struct adv_info *adv;
|
||||
adv = hci_find_adv_instance(hdev, ev->handle);
|
||||
|
||||
adv = hci_find_adv_instance(hdev, ev->handle);
|
||||
if (ev->status) {
|
||||
if (!adv)
|
||||
return;
|
||||
|
||||
@ -5423,9 +5431,15 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
return;
|
||||
}
|
||||
|
||||
if (adv)
|
||||
adv->enabled = false;
|
||||
|
||||
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->conn_handle));
|
||||
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 ||
|
||||
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)
|
||||
return;
|
||||
}
|
||||
|
||||
adv_instance = hci_find_adv_instance(hdev, ev->handle);
|
||||
if (adv_instance)
|
||||
bacpy(&conn->resp_addr, &adv_instance->random_addr);
|
||||
if (adv)
|
||||
bacpy(&conn->resp_addr, &adv->random_addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user