mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
Bluetooth: HCI: Fix not always setting Scan Response/Advertising Data
The scan response and advertising data needs to be tracked on a per instance (adv_info) since when these instaces are removed so are their data, to fix that new flags are introduced which is used to mark when the data changes and then checked to confirm when the data needs to be synced with the controller. Tested-by: Tedd Ho-Jeong An <tedd.an@intel.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
@@ -1728,18 +1728,12 @@ int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
|
||||
}
|
||||
|
||||
adv_instance->flags = flags;
|
||||
adv_instance->adv_data_len = adv_data_len;
|
||||
adv_instance->scan_rsp_len = scan_rsp_len;
|
||||
adv_instance->min_interval = min_interval;
|
||||
adv_instance->max_interval = max_interval;
|
||||
adv_instance->tx_power = tx_power;
|
||||
|
||||
if (adv_data_len)
|
||||
memcpy(adv_instance->adv_data, adv_data, adv_data_len);
|
||||
|
||||
if (scan_rsp_len)
|
||||
memcpy(adv_instance->scan_rsp_data,
|
||||
scan_rsp_data, scan_rsp_len);
|
||||
hci_set_adv_instance_data(hdev, instance, adv_data_len, adv_data,
|
||||
scan_rsp_len, scan_rsp_data);
|
||||
|
||||
adv_instance->timeout = timeout;
|
||||
adv_instance->remaining_time = timeout;
|
||||
@@ -1762,29 +1756,33 @@ int hci_set_adv_instance_data(struct hci_dev *hdev, u8 instance,
|
||||
u16 adv_data_len, u8 *adv_data,
|
||||
u16 scan_rsp_len, u8 *scan_rsp_data)
|
||||
{
|
||||
struct adv_info *adv_instance;
|
||||
struct adv_info *adv;
|
||||
|
||||
adv_instance = hci_find_adv_instance(hdev, instance);
|
||||
adv = hci_find_adv_instance(hdev, instance);
|
||||
|
||||
/* If advertisement doesn't exist, we can't modify its data */
|
||||
if (!adv_instance)
|
||||
if (!adv)
|
||||
return -ENOENT;
|
||||
|
||||
if (adv_data_len) {
|
||||
memset(adv_instance->adv_data, 0,
|
||||
sizeof(adv_instance->adv_data));
|
||||
memcpy(adv_instance->adv_data, adv_data, adv_data_len);
|
||||
adv_instance->adv_data_len = adv_data_len;
|
||||
if (adv_data_len && ADV_DATA_CMP(adv, adv_data, adv_data_len)) {
|
||||
memset(adv->adv_data, 0, sizeof(adv->adv_data));
|
||||
memcpy(adv->adv_data, adv_data, adv_data_len);
|
||||
adv->adv_data_len = adv_data_len;
|
||||
adv->adv_data_changed = true;
|
||||
}
|
||||
|
||||
if (scan_rsp_len) {
|
||||
memset(adv_instance->scan_rsp_data, 0,
|
||||
sizeof(adv_instance->scan_rsp_data));
|
||||
memcpy(adv_instance->scan_rsp_data,
|
||||
scan_rsp_data, scan_rsp_len);
|
||||
adv_instance->scan_rsp_len = scan_rsp_len;
|
||||
if (scan_rsp_len && SCAN_RSP_CMP(adv, scan_rsp_data, scan_rsp_len)) {
|
||||
memset(adv->scan_rsp_data, 0, sizeof(adv->scan_rsp_data));
|
||||
memcpy(adv->scan_rsp_data, scan_rsp_data, scan_rsp_len);
|
||||
adv->scan_rsp_len = scan_rsp_len;
|
||||
adv->scan_rsp_changed = true;
|
||||
}
|
||||
|
||||
/* Mark as changed if there are flags which would affect it */
|
||||
if (((adv->flags & MGMT_ADV_FLAG_APPEARANCE) && hdev->appearance) ||
|
||||
adv->flags & MGMT_ADV_FLAG_LOCAL_NAME)
|
||||
adv->scan_rsp_changed = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user