lkml.org 
[lkml]   [2021]   [Jul]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 415/593] Bluetooth: Fix Set Extended (Scan Response) Data
    Date
    From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

    [ Upstream commit c9ed0a7077306f9d41d74fb006ab5dbada8349c5 ]

    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: a0fb3726ba551 ("Bluetooth: Use Set ext adv/scan rsp data if controller supports")
    Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
    Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    include/net/bluetooth/hci.h | 6 ++--
    include/net/bluetooth/hci_core.h | 8 ++---
    net/bluetooth/hci_request.c | 51 ++++++++++++++++++--------------
    3 files changed, 37 insertions(+), 28 deletions(-)

    diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
    index 6da4b3c5dd55..243de74e118e 100644
    --- a/include/net/bluetooth/hci.h
    +++ b/include/net/bluetooth/hci.h
    @@ -1773,13 +1773,15 @@ struct hci_cp_ext_adv_set {
    __u8 max_events;
    } __packed;

    +#define HCI_MAX_EXT_AD_LENGTH 251
    +
    #define HCI_OP_LE_SET_EXT_ADV_DATA 0x2037
    struct hci_cp_le_set_ext_adv_data {
    __u8 handle;
    __u8 operation;
    __u8 frag_pref;
    __u8 length;
    - __u8 data[HCI_MAX_AD_LENGTH];
    + __u8 data[];
    } __packed;

    #define HCI_OP_LE_SET_EXT_SCAN_RSP_DATA 0x2038
    @@ -1788,7 +1790,7 @@ struct hci_cp_le_set_ext_scan_rsp_data {
    __u8 operation;
    __u8 frag_pref;
    __u8 length;
    - __u8 data[HCI_MAX_AD_LENGTH];
    + __u8 data[];
    } __packed;

    #define LE_SET_ADV_DATA_OP_COMPLETE 0x03
    diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
    index df611c8b6b59..e534dff2874e 100644
    --- a/include/net/bluetooth/hci_core.h
    +++ b/include/net/bluetooth/hci_core.h
    @@ -226,9 +226,9 @@ struct adv_info {
    __u16 remaining_time;
    __u16 duration;
    __u16 adv_data_len;
    - __u8 adv_data[HCI_MAX_AD_LENGTH];
    + __u8 adv_data[HCI_MAX_EXT_AD_LENGTH];
    __u16 scan_rsp_len;
    - __u8 scan_rsp_data[HCI_MAX_AD_LENGTH];
    + __u8 scan_rsp_data[HCI_MAX_EXT_AD_LENGTH];
    __s8 tx_power;
    bdaddr_t random_addr;
    bool rpa_expired;
    @@ -523,9 +523,9 @@ struct hci_dev {
    DECLARE_BITMAP(dev_flags, __HCI_NUM_FLAGS);

    __s8 adv_tx_power;
    - __u8 adv_data[HCI_MAX_AD_LENGTH];
    + __u8 adv_data[HCI_MAX_EXT_AD_LENGTH];
    __u8 adv_data_len;
    - __u8 scan_rsp_data[HCI_MAX_AD_LENGTH];
    + __u8 scan_rsp_data[HCI_MAX_EXT_AD_LENGTH];
    __u8 scan_rsp_data_len;

    struct list_head adv_instances;
    diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
    index 33dc78c24b73..1a94ed2f8a4f 100644
    --- a/net/bluetooth/hci_request.c
    +++ b/net/bluetooth/hci_request.c
    @@ -1596,30 +1596,33 @@ void __hci_req_update_scan_rsp_data(struct hci_request *req, u8 instance)
    return;

    if (ext_adv_capable(hdev)) {
    - struct hci_cp_le_set_ext_scan_rsp_data cp;
    + struct {
    + struct hci_cp_le_set_ext_scan_rsp_data cp;
    + u8 data[HCI_MAX_EXT_AD_LENGTH];
    + } pdu;

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

    if (instance)
    len = create_instance_scan_rsp_data(hdev, instance,
    - cp.data);
    + pdu.data);
    else
    - len = create_default_scan_rsp_data(hdev, cp.data);
    + len = create_default_scan_rsp_data(hdev, pdu.data);

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

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

    - cp.handle = instance;
    - cp.length = len;
    - cp.operation = LE_SET_ADV_DATA_OP_COMPLETE;
    - cp.frag_pref = LE_SET_ADV_DATA_NO_FRAG;
    + pdu.cp.handle = instance;
    + pdu.cp.length = len;
    + pdu.cp.operation = LE_SET_ADV_DATA_OP_COMPLETE;
    + pdu.cp.frag_pref = LE_SET_ADV_DATA_NO_FRAG;

    - hci_req_add(req, HCI_OP_LE_SET_EXT_SCAN_RSP_DATA, sizeof(cp),
    - &cp);
    + hci_req_add(req, HCI_OP_LE_SET_EXT_SCAN_RSP_DATA,
    + sizeof(pdu.cp) + len, &pdu.cp);
    } else {
    struct hci_cp_le_set_scan_rsp_data cp;

    @@ -1742,26 +1745,30 @@ void __hci_req_update_adv_data(struct hci_request *req, u8 instance)
    return;

    if (ext_adv_capable(hdev)) {
    - struct hci_cp_le_set_ext_adv_data cp;
    + struct {
    + struct hci_cp_le_set_ext_adv_data cp;
    + u8 data[HCI_MAX_EXT_AD_LENGTH];
    + } pdu;

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

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

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

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

    - cp.length = len;
    - cp.handle = instance;
    - cp.operation = LE_SET_ADV_DATA_OP_COMPLETE;
    - cp.frag_pref = LE_SET_ADV_DATA_NO_FRAG;
    + pdu.cp.length = len;
    + pdu.cp.handle = instance;
    + pdu.cp.operation = LE_SET_ADV_DATA_OP_COMPLETE;
    + pdu.cp.frag_pref = LE_SET_ADV_DATA_NO_FRAG;

    - hci_req_add(req, HCI_OP_LE_SET_EXT_ADV_DATA, sizeof(cp), &cp);
    + hci_req_add(req, HCI_OP_LE_SET_EXT_ADV_DATA,
    + sizeof(pdu.cp) + len, &pdu.cp);
    } else {
    struct hci_cp_le_set_adv_data cp;

    --
    2.30.2


    \
     
     \ /
      Last update: 2021-07-12 09:40    [W:4.111 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site