]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
Bluetooth: hci_core: Fix tracking of periodic advertisement
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Wed, 22 Oct 2025 20:03:19 +0000 (16:03 -0400)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Fri, 24 Oct 2025 14:31:59 +0000 (10:31 -0400)
Periodic advertising enabled flag cannot be tracked by the enabled
flag since advertising and periodic advertising each can be
enabled/disabled separately from one another causing the states to be
inconsistent when for example an advertising set is disabled its
enabled flag is set to false which is then used for periodic which has
not being disabled.

Fixes: eca0ae4aea66 ("Bluetooth: Add initial implementation of BIS connections")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
include/net/bluetooth/hci_core.h
net/bluetooth/hci_event.c
net/bluetooth/hci_sync.c

index 2924c2bf2a983d4ae241a9489edeb8629db02f6f..b8100dbfe5d7e4d2f5eacd5eb9711ef4db5b9b98 100644 (file)
@@ -244,6 +244,7 @@ struct adv_info {
        bool    enabled;
        bool    pending;
        bool    periodic;
+       bool    periodic_enabled;
        __u8    mesh;
        __u8    instance;
        __u8    handle;
index 1dabf5a7ae188dcf8d9706be959f61187f0ac692..d37db364acf7403c00ff61573887c5efe23ecec6 100644 (file)
@@ -1607,7 +1607,7 @@ static u8 hci_cc_le_set_ext_adv_enable(struct hci_dev *hdev, void *data,
 
                hci_dev_set_flag(hdev, HCI_LE_ADV);
 
-               if (adv && !adv->periodic)
+               if (adv)
                        adv->enabled = true;
                else if (!set->handle)
                        hci_dev_set_flag(hdev, HCI_LE_ADV_0);
@@ -3963,8 +3963,11 @@ static u8 hci_cc_le_set_per_adv_enable(struct hci_dev *hdev, void *data,
                hci_dev_set_flag(hdev, HCI_LE_PER_ADV);
 
                if (adv)
-                       adv->enabled = true;
+                       adv->periodic_enabled = true;
        } else {
+               if (adv)
+                       adv->periodic_enabled = false;
+
                /* If just one instance was disabled check if there are
                 * any other instance enabled before clearing HCI_LE_PER_ADV.
                 * The current periodic adv instance will be marked as
index 28ad08cd7d70671603dd307c4cd591d60af1f9d8..73fc41b68b6870ac54e8a7e1a70d203137b47239 100644 (file)
@@ -1607,7 +1607,7 @@ int hci_disable_per_advertising_sync(struct hci_dev *hdev, u8 instance)
 
        /* If periodic advertising already disabled there is nothing to do. */
        adv = hci_find_adv_instance(hdev, instance);
-       if (!adv || !adv->periodic || !adv->enabled)
+       if (!adv || !adv->periodic_enabled)
                return 0;
 
        memset(&cp, 0, sizeof(cp));
@@ -1672,7 +1672,7 @@ static int hci_enable_per_advertising_sync(struct hci_dev *hdev, u8 instance)
 
        /* If periodic advertising already enabled there is nothing to do. */
        adv = hci_find_adv_instance(hdev, instance);
-       if (adv && adv->periodic && adv->enabled)
+       if (adv && adv->periodic_enabled)
                return 0;
 
        memset(&cp, 0, sizeof(cp));