Skip to content

Commit

Permalink
Bluetooth: Store advertising handle so it can be re-enabled
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Marcel Holtmann <[email protected]>
  • Loading branch information
Vudentz authored and holtmann committed Aug 16, 2021
1 parent cafae4c commit 7087c4f
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 16 deletions.
1 change: 1 addition & 0 deletions include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
45 changes: 29 additions & 16 deletions net/bluetooth/hci_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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.
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand All @@ -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))
Expand All @@ -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);
}
}

Expand Down

0 comments on commit 7087c4f

Please sign in to comment.