summaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_event.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2014-01-10 02:07:23 -0800
committerJohan Hedberg <johan.hedberg@intel.com>2014-02-13 09:51:32 +0200
commiteac83dc632a7afba72f7084266bc310219486253 (patch)
tree42a58e9bad2e9c0eec318f6f21d59a870d7f57df /net/bluetooth/hci_event.c
parente98d2ce293a941d41b5c8435975ff25a1b858bf9 (diff)
downloadlinux-stable-eac83dc632a7afba72f7084266bc310219486253.tar.gz
linux-stable-eac83dc632a7afba72f7084266bc310219486253.tar.bz2
linux-stable-eac83dc632a7afba72f7084266bc310219486253.zip
Bluetooth: Add management command for enabling Secure Connections
The support for Secure Connections need to be explicitly enabled by userspace. This is required since only userspace that can handle the new link key types should enable support for Secure Connections. This command handling is similar to how Secure Simple Pairing enabling is done. It also tracks the case when Secure Connections support is enabled via raw HCI commands. This makes sure that the host features page is updated as well. Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r--net/bluetooth/hci_event.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index b3c5396e0c1b..b6f0c241e236 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -461,6 +461,34 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
}
}
+static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ u8 status = *((u8 *) skb->data);
+ struct hci_cp_write_sc_support *sent;
+
+ BT_DBG("%s status 0x%2.2x", hdev->name, status);
+
+ sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT);
+ if (!sent)
+ return;
+
+ if (!status) {
+ if (sent->support)
+ hdev->features[1][0] |= LMP_HOST_SC;
+ else
+ hdev->features[1][0] &= ~LMP_HOST_SC;
+ }
+
+ if (test_bit(HCI_MGMT, &hdev->dev_flags))
+ mgmt_sc_enable_complete(hdev, sent->support, status);
+ else if (!status) {
+ if (sent->support)
+ set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
+ else
+ clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
+ }
+}
+
static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_rp_read_local_version *rp = (void *) skb->data;
@@ -2147,6 +2175,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_cc_write_ssp_mode(hdev, skb);
break;
+ case HCI_OP_WRITE_SC_SUPPORT:
+ hci_cc_write_sc_support(hdev, skb);
+ break;
+
case HCI_OP_READ_LOCAL_VERSION:
hci_cc_read_local_version(hdev, skb);
break;