Skip to content

Commit c9ed0a7

Browse files
Vudentzholtmann
authored andcommitted
Bluetooth: Fix Set Extended (Scan Response) Data
These command do have variable length and the length can go up to 251, so this changes the struct to not use a fixed size and then when creating the PDU only the actual length of the data send to the controller. Fixes: a0fb372 ("Bluetooth: Use Set ext adv/scan rsp data if controller supports") Signed-off-by: Luiz Augusto von Dentz <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent 3d4f9c0 commit c9ed0a7

File tree

3 files changed

+37
-28
lines changed

3 files changed

+37
-28
lines changed

include/net/bluetooth/hci.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,13 +1775,15 @@ struct hci_cp_ext_adv_set {
17751775
__u8 max_events;
17761776
} __packed;
17771777

1778+
#define HCI_MAX_EXT_AD_LENGTH 251
1779+
17781780
#define HCI_OP_LE_SET_EXT_ADV_DATA 0x2037
17791781
struct hci_cp_le_set_ext_adv_data {
17801782
__u8 handle;
17811783
__u8 operation;
17821784
__u8 frag_pref;
17831785
__u8 length;
1784-
__u8 data[HCI_MAX_AD_LENGTH];
1786+
__u8 data[];
17851787
} __packed;
17861788

17871789
#define HCI_OP_LE_SET_EXT_SCAN_RSP_DATA 0x2038
@@ -1790,7 +1792,7 @@ struct hci_cp_le_set_ext_scan_rsp_data {
17901792
__u8 operation;
17911793
__u8 frag_pref;
17921794
__u8 length;
1793-
__u8 data[HCI_MAX_AD_LENGTH];
1795+
__u8 data[];
17941796
} __packed;
17951797

17961798
#define LE_SET_ADV_DATA_OP_COMPLETE 0x03

include/net/bluetooth/hci_core.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,9 @@ struct adv_info {
228228
__u16 remaining_time;
229229
__u16 duration;
230230
__u16 adv_data_len;
231-
__u8 adv_data[HCI_MAX_AD_LENGTH];
231+
__u8 adv_data[HCI_MAX_EXT_AD_LENGTH];
232232
__u16 scan_rsp_len;
233-
__u8 scan_rsp_data[HCI_MAX_AD_LENGTH];
233+
__u8 scan_rsp_data[HCI_MAX_EXT_AD_LENGTH];
234234
__s8 tx_power;
235235
__u32 min_interval;
236236
__u32 max_interval;
@@ -551,9 +551,9 @@ struct hci_dev {
551551
DECLARE_BITMAP(dev_flags, __HCI_NUM_FLAGS);
552552

553553
__s8 adv_tx_power;
554-
__u8 adv_data[HCI_MAX_AD_LENGTH];
554+
__u8 adv_data[HCI_MAX_EXT_AD_LENGTH];
555555
__u8 adv_data_len;
556-
__u8 scan_rsp_data[HCI_MAX_AD_LENGTH];
556+
__u8 scan_rsp_data[HCI_MAX_EXT_AD_LENGTH];
557557
__u8 scan_rsp_data_len;
558558

559559
struct list_head adv_instances;

net/bluetooth/hci_request.c

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,30 +1716,33 @@ void __hci_req_update_scan_rsp_data(struct hci_request *req, u8 instance)
17161716
return;
17171717

17181718
if (ext_adv_capable(hdev)) {
1719-
struct hci_cp_le_set_ext_scan_rsp_data cp;
1719+
struct {
1720+
struct hci_cp_le_set_ext_scan_rsp_data cp;
1721+
u8 data[HCI_MAX_EXT_AD_LENGTH];
1722+
} pdu;
17201723

1721-
memset(&cp, 0, sizeof(cp));
1724+
memset(&pdu, 0, sizeof(pdu));
17221725

17231726
if (instance)
17241727
len = create_instance_scan_rsp_data(hdev, instance,
1725-
cp.data);
1728+
pdu.data);
17261729
else
1727-
len = create_default_scan_rsp_data(hdev, cp.data);
1730+
len = create_default_scan_rsp_data(hdev, pdu.data);
17281731

17291732
if (hdev->scan_rsp_data_len == len &&
1730-
!memcmp(cp.data, hdev->scan_rsp_data, len))
1733+
!memcmp(pdu.data, hdev->scan_rsp_data, len))
17311734
return;
17321735

1733-
memcpy(hdev->scan_rsp_data, cp.data, sizeof(cp.data));
1736+
memcpy(hdev->scan_rsp_data, pdu.data, len);
17341737
hdev->scan_rsp_data_len = len;
17351738

1736-
cp.handle = instance;
1737-
cp.length = len;
1738-
cp.operation = LE_SET_ADV_DATA_OP_COMPLETE;
1739-
cp.frag_pref = LE_SET_ADV_DATA_NO_FRAG;
1739+
pdu.cp.handle = instance;
1740+
pdu.cp.length = len;
1741+
pdu.cp.operation = LE_SET_ADV_DATA_OP_COMPLETE;
1742+
pdu.cp.frag_pref = LE_SET_ADV_DATA_NO_FRAG;
17401743

1741-
hci_req_add(req, HCI_OP_LE_SET_EXT_SCAN_RSP_DATA, sizeof(cp),
1742-
&cp);
1744+
hci_req_add(req, HCI_OP_LE_SET_EXT_SCAN_RSP_DATA,
1745+
sizeof(pdu.cp) + len, &pdu.cp);
17431746
} else {
17441747
struct hci_cp_le_set_scan_rsp_data cp;
17451748

@@ -1862,26 +1865,30 @@ void __hci_req_update_adv_data(struct hci_request *req, u8 instance)
18621865
return;
18631866

18641867
if (ext_adv_capable(hdev)) {
1865-
struct hci_cp_le_set_ext_adv_data cp;
1868+
struct {
1869+
struct hci_cp_le_set_ext_adv_data cp;
1870+
u8 data[HCI_MAX_EXT_AD_LENGTH];
1871+
} pdu;
18661872

1867-
memset(&cp, 0, sizeof(cp));
1873+
memset(&pdu, 0, sizeof(pdu));
18681874

1869-
len = create_instance_adv_data(hdev, instance, cp.data);
1875+
len = create_instance_adv_data(hdev, instance, pdu.data);
18701876

18711877
/* There's nothing to do if the data hasn't changed */
18721878
if (hdev->adv_data_len == len &&
1873-
memcmp(cp.data, hdev->adv_data, len) == 0)
1879+
memcmp(pdu.data, hdev->adv_data, len) == 0)
18741880
return;
18751881

1876-
memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
1882+
memcpy(hdev->adv_data, pdu.data, len);
18771883
hdev->adv_data_len = len;
18781884

1879-
cp.length = len;
1880-
cp.handle = instance;
1881-
cp.operation = LE_SET_ADV_DATA_OP_COMPLETE;
1882-
cp.frag_pref = LE_SET_ADV_DATA_NO_FRAG;
1885+
pdu.cp.length = len;
1886+
pdu.cp.handle = instance;
1887+
pdu.cp.operation = LE_SET_ADV_DATA_OP_COMPLETE;
1888+
pdu.cp.frag_pref = LE_SET_ADV_DATA_NO_FRAG;
18831889

1884-
hci_req_add(req, HCI_OP_LE_SET_EXT_ADV_DATA, sizeof(cp), &cp);
1890+
hci_req_add(req, HCI_OP_LE_SET_EXT_ADV_DATA,
1891+
sizeof(pdu.cp) + len, &pdu.cp);
18851892
} else {
18861893
struct hci_cp_le_set_adv_data cp;
18871894

0 commit comments

Comments
 (0)