Bluetooth: HCI: Add proper tracking for enable status of adv instances
This adds a field to track if advertising instances are enabled or not and only clear HCI_LE_ADV flag if there is no instance left advertising. 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:
Родитель
654e6f7700
Коммит
102793136c
|
@ -221,6 +221,7 @@ struct oob_data {
|
||||||
|
|
||||||
struct adv_info {
|
struct adv_info {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
bool enabled;
|
||||||
bool pending;
|
bool pending;
|
||||||
__u8 instance;
|
__u8 instance;
|
||||||
__u32 flags;
|
__u32 flags;
|
||||||
|
|
|
@ -1277,7 +1277,9 @@ static void hci_cc_le_set_ext_adv_enable(struct hci_dev *hdev,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct hci_cp_le_set_ext_adv_enable *cp;
|
struct hci_cp_le_set_ext_adv_enable *cp;
|
||||||
|
struct hci_cp_ext_adv_set *set;
|
||||||
__u8 status = *((__u8 *) skb->data);
|
__u8 status = *((__u8 *) skb->data);
|
||||||
|
struct adv_info *adv = NULL, *n;
|
||||||
|
|
||||||
BT_DBG("%s status 0x%2.2x", hdev->name, status);
|
BT_DBG("%s status 0x%2.2x", hdev->name, status);
|
||||||
|
|
||||||
|
@ -1288,22 +1290,48 @@ static void hci_cc_le_set_ext_adv_enable(struct hci_dev *hdev,
|
||||||
if (!cp)
|
if (!cp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
set = (void *)cp->data;
|
||||||
|
|
||||||
hci_dev_lock(hdev);
|
hci_dev_lock(hdev);
|
||||||
|
|
||||||
|
if (cp->num_of_sets)
|
||||||
|
adv = hci_find_adv_instance(hdev, set->handle);
|
||||||
|
|
||||||
if (cp->enable) {
|
if (cp->enable) {
|
||||||
struct hci_conn *conn;
|
struct hci_conn *conn;
|
||||||
|
|
||||||
hci_dev_set_flag(hdev, HCI_LE_ADV);
|
hci_dev_set_flag(hdev, HCI_LE_ADV);
|
||||||
|
|
||||||
|
if (adv)
|
||||||
|
adv->enabled = true;
|
||||||
|
|
||||||
conn = hci_lookup_le_connect(hdev);
|
conn = hci_lookup_le_connect(hdev);
|
||||||
if (conn)
|
if (conn)
|
||||||
queue_delayed_work(hdev->workqueue,
|
queue_delayed_work(hdev->workqueue,
|
||||||
&conn->le_conn_timeout,
|
&conn->le_conn_timeout,
|
||||||
conn->conn_timeout);
|
conn->conn_timeout);
|
||||||
} else {
|
} else {
|
||||||
|
if (adv) {
|
||||||
|
adv->enabled = false;
|
||||||
|
/* If just one instance was disabled check if there are
|
||||||
|
* any other instance enabled before clearing HCI_LE_ADV
|
||||||
|
*/
|
||||||
|
list_for_each_entry_safe(adv, n, &hdev->adv_instances,
|
||||||
|
list) {
|
||||||
|
if (adv->enabled)
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* All instances shall be considered disabled */
|
||||||
|
list_for_each_entry_safe(adv, n, &hdev->adv_instances,
|
||||||
|
list)
|
||||||
|
adv->enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
hci_dev_clear_flag(hdev, HCI_LE_ADV);
|
hci_dev_clear_flag(hdev, HCI_LE_ADV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
hci_dev_unlock(hdev);
|
hci_dev_unlock(hdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче