mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 16:53:20 -04:00
Bluetooth: hci_sync: Disable legacy instance's ext adv before setup snapshot
hci_setup_ext_adv_instance_sync(...) only disabled HCI_OP_LE_SET_EXT_ADV_ENABLE before setup snapshot in case of non-legacy instances (instance > 0) and never disabled the same for legacy instance (instance == 0). This would lead to failure in setting ext adv params with HCI_ERROR_COMMAND_DISALLOWED (0x0c) error like below, when toggling the discoverable/connectable property of a controller with advertising enabled. ``` $ btmgmt advertising off hci0 Set Advertising complete, settings: powered ssp br/edr le secure-conn wide-band-speech cis-central cis-peripheral $ btmgmt connectable on hci0 Set Connectable complete, settings: powered connectable ssp br/edr le secure-conn wide-band-speech cis-central cis-peripheral $ btmgmt connectable off hci0 Set Connectable complete, settings: powered ssp br/edr le secure-conn wide-band-speech cis-central cis-peripheral $ btmgmt advertising on hci0 Set Advertising complete, settings: powered connectable ssp br/edr le advertising secure-conn wide-band-speech cis-central cis-peripheral $ btmgmt connectable on Set Connectable for hci0 failed with status 0x0a (Busy) $ btmgmt connectable off Set Connectable for hci0 failed with status 0x0a (Busy) $ dmesg ... [ 21.970527] hci0: Opcode 0x2036 [ 21.970529] hci0: opcode 0x2036 plen 25 [ 21.970537] hci0: skb len 28 [ 21.970539] hci0: length 1 [ 21.976099] hci0: result 0x0c [ 21.976105] hci0: end: err -16 [ 21.976114] Bluetooth: hci0: Opcode 0x2036 failed: -16 ``` Signed-off-by: Muhammad Saheed <muhammad.saheed.iam@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
committed by
Luiz Augusto von Dentz
parent
e3643fbddb
commit
75722cde87
@@ -1150,6 +1150,32 @@ int hci_update_random_address_sync(struct hci_dev *hdev, bool require_privacy,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hci_disable_ext_adv_legacy_instance_sync(struct hci_dev *hdev)
|
||||
{
|
||||
struct hci_cp_le_set_ext_adv_enable *cp;
|
||||
struct hci_cp_ext_adv_set *set;
|
||||
u8 data[sizeof(*cp) + sizeof(*set) * 1];
|
||||
u8 size;
|
||||
|
||||
if (!hci_dev_test_flag(hdev, HCI_LE_ADV_0))
|
||||
return 0;
|
||||
|
||||
memset(data, 0, sizeof(data));
|
||||
|
||||
cp = (void *)data;
|
||||
set = (void *)cp->data;
|
||||
|
||||
cp->num_of_sets = 0x01;
|
||||
cp->enable = 0x00;
|
||||
|
||||
set->handle = 0x00;
|
||||
|
||||
size = sizeof(*cp) + sizeof(*set) * cp->num_of_sets;
|
||||
|
||||
return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_ADV_ENABLE,
|
||||
size, data, HCI_CMD_TIMEOUT);
|
||||
}
|
||||
|
||||
static int hci_disable_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance)
|
||||
{
|
||||
struct hci_cp_le_set_ext_adv_enable *cp;
|
||||
@@ -1375,6 +1401,10 @@ int hci_setup_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance)
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
err = hci_disable_ext_adv_legacy_instance_sync(hdev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
adv = NULL;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user