]> git.ipfire.org Git - thirdparty/kernel/stable.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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 13 Nov 2025 20:33:58 +0000 (15:33 -0500)
[ Upstream commit 751463ceefc3397566d03c8b64ef4a77f5fd88ac ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
include/net/bluetooth/hci_core.h
net/bluetooth/hci_event.c
net/bluetooth/hci_sync.c

index ca75c71b58588f7f0c3e1d89164cd83a99269e5d..35b5f58b562cbac9b55562aff16df8e69e4f8e18 100644 (file)
@@ -240,6 +240,7 @@ struct adv_info {
        bool    enabled;
        bool    pending;
        bool    periodic;
+       bool    periodic_enabled;
        __u8    mesh;
        __u8    instance;
        __u8    handle;
index 176565ef47c6309ae957a7f8bb1a8d3f289bab01..ccc73742de35695cf4eb66767856880f7ba6c86c 100644 (file)
@@ -1598,7 +1598,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);
@@ -3955,8 +3955,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 06d8ab997bd85c83726c86e2c358e0bf0639d10c..f79b38603205caa1e5b98d8bc2e3fea03df82020 100644 (file)
@@ -1605,7 +1605,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));
@@ -1670,7 +1670,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));