aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2012-02-22 04:58:37 -0500
committerJohan Hedberg <johan.hedberg@intel.com>2012-02-23 06:06:58 -0500
commit47990ea09d393da8fb6cf284f4dba704c3661973 (patch)
tree60cdfa2ffaacebc6a715262147237a6f35ddae7d /net
parent2e0052e4cf78e3e205e92d82ee572ed726e315d6 (diff)
Bluetooth: mgmt: Make Set Link Security callable while powered off
This patch makes it possible to change the Link Security setting while powered off and have it automatically enabled when powering on a device. To track the desired state once powered on a new HCI_LINK_SECURITY flag is added. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Acked-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_event.c6
-rw-r--r--net/bluetooth/mgmt.c33
2 files changed, 34 insertions, 5 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 2a5d05c05e35..5fb1ee516d3a 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -594,6 +594,12 @@ static void hci_setup(struct hci_dev *hdev)
594 sizeof(cp), &cp); 594 sizeof(cp), &cp);
595 } 595 }
596 596
597 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
598 u8 enable = 1;
599 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE,
600 sizeof(enable), &enable);
601 }
602
597 if (hdev->features[4] & LMP_LE) 603 if (hdev->features[4] & LMP_LE)
598 hci_set_le_support(hdev); 604 hci_set_le_support(hdev);
599} 605}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index e8f890d7256a..69d4e1a699a3 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -410,7 +410,7 @@ static u32 get_current_settings(struct hci_dev *hdev)
410 if (hdev->host_features[0] & LMP_HOST_LE) 410 if (hdev->host_features[0] & LMP_HOST_LE)
411 settings |= MGMT_SETTING_LE; 411 settings |= MGMT_SETTING_LE;
412 412
413 if (test_bit(HCI_AUTH, &hdev->flags)) 413 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags))
414 settings |= MGMT_SETTING_LINK_SECURITY; 414 settings |= MGMT_SETTING_LINK_SECURITY;
415 415
416 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) 416 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
@@ -1067,8 +1067,21 @@ static int set_link_security(struct sock *sk, u16 index, void *data, u16 len)
1067 hci_dev_lock(hdev); 1067 hci_dev_lock(hdev);
1068 1068
1069 if (!hdev_is_powered(hdev)) { 1069 if (!hdev_is_powered(hdev)) {
1070 err = cmd_status(sk, index, MGMT_OP_SET_LINK_SECURITY, 1070 bool changed = false;
1071 MGMT_STATUS_NOT_POWERED); 1071
1072 if (!!cp->val != test_bit(HCI_LINK_SECURITY,
1073 &hdev->dev_flags)) {
1074 change_bit(HCI_LINK_SECURITY, &hdev->dev_flags);
1075 changed = true;
1076 }
1077
1078 err = send_settings_rsp(sk, MGMT_OP_SET_LINK_SECURITY, hdev);
1079 if (err < 0)
1080 goto failed;
1081
1082 if (changed)
1083 err = new_settings(hdev, sk);
1084
1072 goto failed; 1085 goto failed;
1073 } 1086 }
1074 1087
@@ -3338,7 +3351,8 @@ int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
3338int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status) 3351int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
3339{ 3352{
3340 struct cmd_lookup match = { NULL, hdev }; 3353 struct cmd_lookup match = { NULL, hdev };
3341 int err; 3354 bool changed = false;
3355 int err = 0;
3342 3356
3343 if (status) { 3357 if (status) {
3344 u8 mgmt_err = mgmt_status(status); 3358 u8 mgmt_err = mgmt_status(status);
@@ -3347,10 +3361,19 @@ int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
3347 return 0; 3361 return 0;
3348 } 3362 }
3349 3363
3364 if (test_bit(HCI_AUTH, &hdev->flags)) {
3365 if (!test_and_set_bit(HCI_LINK_SECURITY, &hdev->dev_flags))
3366 changed = true;
3367 } else {
3368 if (test_and_clear_bit(HCI_LINK_SECURITY, &hdev->dev_flags))
3369 changed = true;
3370 }
3371
3350 mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp, 3372 mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp,
3351 &match); 3373 &match);
3352 3374
3353 err = new_settings(hdev, match.sk); 3375 if (changed)
3376 err = new_settings(hdev, match.sk);
3354 3377
3355 if (match.sk) 3378 if (match.sk)
3356 sock_put(match.sk); 3379 sock_put(match.sk);