mirror of
https://github.com/torvalds/linux
synced 2024-10-13 14:56:40 +00:00
Bluetooth: Add support for Set Privacy command
This patch adds support for handling the Set Privacy mgmt command, including copying the value to hdev->irk and toggling the HCI_PRIVACY flag. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
parent
c982b2ea29
commit
62b04cd124
|
@ -81,6 +81,7 @@ static const u16 mgmt_commands[] = {
|
||||||
MGMT_OP_SET_SCAN_PARAMS,
|
MGMT_OP_SET_SCAN_PARAMS,
|
||||||
MGMT_OP_SET_SECURE_CONN,
|
MGMT_OP_SET_SECURE_CONN,
|
||||||
MGMT_OP_SET_DEBUG_KEYS,
|
MGMT_OP_SET_DEBUG_KEYS,
|
||||||
|
MGMT_OP_SET_PRIVACY,
|
||||||
MGMT_OP_LOAD_IRKS,
|
MGMT_OP_LOAD_IRKS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4227,6 +4228,51 @@ static int set_debug_keys(struct sock *sk, struct hci_dev *hdev,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_privacy(struct sock *sk, struct hci_dev *hdev, void *cp_data,
|
||||||
|
u16 len)
|
||||||
|
{
|
||||||
|
struct mgmt_cp_set_privacy *cp = cp_data;
|
||||||
|
bool changed;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
BT_DBG("request for %s", hdev->name);
|
||||||
|
|
||||||
|
if (!lmp_le_capable(hdev))
|
||||||
|
return cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY,
|
||||||
|
MGMT_STATUS_NOT_SUPPORTED);
|
||||||
|
|
||||||
|
if (cp->privacy != 0x00 && cp->privacy != 0x01)
|
||||||
|
return cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY,
|
||||||
|
MGMT_STATUS_INVALID_PARAMS);
|
||||||
|
|
||||||
|
if (hdev_is_powered(hdev))
|
||||||
|
return cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY,
|
||||||
|
MGMT_STATUS_REJECTED);
|
||||||
|
|
||||||
|
hci_dev_lock(hdev);
|
||||||
|
|
||||||
|
if (cp->privacy) {
|
||||||
|
changed = !test_and_set_bit(HCI_PRIVACY, &hdev->dev_flags);
|
||||||
|
memcpy(hdev->irk, cp->irk, sizeof(hdev->irk));
|
||||||
|
set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
|
||||||
|
} else {
|
||||||
|
changed = test_and_clear_bit(HCI_PRIVACY, &hdev->dev_flags);
|
||||||
|
memset(hdev->irk, 0, sizeof(hdev->irk));
|
||||||
|
clear_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
err = send_settings_rsp(sk, MGMT_OP_SET_PRIVACY, hdev);
|
||||||
|
if (err < 0)
|
||||||
|
goto unlock;
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
err = new_settings(hdev, sk);
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
hci_dev_unlock(hdev);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static bool irk_is_valid(struct mgmt_irk_info *irk)
|
static bool irk_is_valid(struct mgmt_irk_info *irk)
|
||||||
{
|
{
|
||||||
switch (irk->addr.type) {
|
switch (irk->addr.type) {
|
||||||
|
@ -4441,7 +4487,7 @@ static const struct mgmt_handler {
|
||||||
{ set_scan_params, false, MGMT_SET_SCAN_PARAMS_SIZE },
|
{ set_scan_params, false, MGMT_SET_SCAN_PARAMS_SIZE },
|
||||||
{ set_secure_conn, false, MGMT_SETTING_SIZE },
|
{ set_secure_conn, false, MGMT_SETTING_SIZE },
|
||||||
{ set_debug_keys, false, MGMT_SETTING_SIZE },
|
{ set_debug_keys, false, MGMT_SETTING_SIZE },
|
||||||
{ },
|
{ set_privacy, false, MGMT_SET_PRIVACY_SIZE },
|
||||||
{ load_irks, true, MGMT_LOAD_IRKS_SIZE },
|
{ load_irks, true, MGMT_LOAD_IRKS_SIZE },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue