Skip to content

Commit

Permalink
Bluetooth: Fix sending write_le_host_supporte for LE-only controllers
Browse files Browse the repository at this point in the history
The Bluetooth Core Specification (4.0) defines the Write LE Host
Supported HCI command as only available for controllers supporting
BR/EDR. This is further reflected in the Read Local Extended Features
HCI command also not being available for LE-only controllers. In other
words, host-side LE support is implicit for single-mode LE controllers
and doesn't have explicit HCI-level enablement.

This patch ensures that the LE setting is always exposed as enabled
through mgmt and returns a "rejected" response if user space tries to
toggle the setting. The patch also ensures that Write LE Host Supported
is never sent for LE-only controllers.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
  • Loading branch information
Johan Hedberg authored and Gustavo Padovan committed Apr 23, 2013
1 parent 07dc93d commit c73eee9
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 1 deletion.
10 changes: 10 additions & 0 deletions net/bluetooth/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,8 @@ static void bredr_setup(struct hci_request *req)

static void le_setup(struct hci_request *req)
{
struct hci_dev *hdev = req->hdev;

/* Read LE Buffer Size */
hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);

Expand All @@ -391,6 +393,10 @@ static void le_setup(struct hci_request *req)

/* Read LE Supported States */
hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);

/* LE-only controllers have LE implicitly enabled */
if (!lmp_bredr_capable(hdev))
set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
}

static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
Expand Down Expand Up @@ -574,6 +580,10 @@ static void hci_set_le_support(struct hci_request *req)
struct hci_dev *hdev = req->hdev;
struct hci_cp_write_le_host_supported cp;

/* LE-only devices do not support explicit enablement */
if (!lmp_bredr_capable(hdev))
return;

memset(&cp, 0, sizeof(cp));

if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
Expand Down
8 changes: 7 additions & 1 deletion net/bluetooth/mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1351,6 +1351,11 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
return cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
MGMT_STATUS_INVALID_PARAMS);

/* LE-only devices do not allow toggling LE on/off */
if (!lmp_bredr_capable(hdev))
return cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
MGMT_STATUS_REJECTED);

hci_dev_lock(hdev);

val = !!cp->val;
Expand Down Expand Up @@ -3347,7 +3352,8 @@ static int powered_update_hci(struct hci_dev *hdev)
hci_req_add(&req, HCI_OP_WRITE_SSP_MODE, 1, &ssp);
}

if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags) &&
lmp_bredr_capable(hdev)) {
struct hci_cp_write_le_host_supported cp;

cp.le = 1;
Expand Down

0 comments on commit c73eee9

Please sign in to comment.