aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r--net/bluetooth/mgmt.c100
1 files changed, 68 insertions, 32 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 158a87bb0c0..142764aec2a 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -222,7 +222,7 @@ static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status)
222 222
223 hdr = (void *) skb_put(skb, sizeof(*hdr)); 223 hdr = (void *) skb_put(skb, sizeof(*hdr));
224 224
225 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS); 225 hdr->opcode = __constant_cpu_to_le16(MGMT_EV_CMD_STATUS);
226 hdr->index = cpu_to_le16(index); 226 hdr->index = cpu_to_le16(index);
227 hdr->len = cpu_to_le16(sizeof(*ev)); 227 hdr->len = cpu_to_le16(sizeof(*ev));
228 228
@@ -253,7 +253,7 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status,
253 253
254 hdr = (void *) skb_put(skb, sizeof(*hdr)); 254 hdr = (void *) skb_put(skb, sizeof(*hdr));
255 255
256 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE); 256 hdr->opcode = __constant_cpu_to_le16(MGMT_EV_CMD_COMPLETE);
257 hdr->index = cpu_to_le16(index); 257 hdr->index = cpu_to_le16(index);
258 hdr->len = cpu_to_le16(sizeof(*ev) + rp_len); 258 hdr->len = cpu_to_le16(sizeof(*ev) + rp_len);
259 259
@@ -377,15 +377,15 @@ static u32 get_supported_settings(struct hci_dev *hdev)
377 u32 settings = 0; 377 u32 settings = 0;
378 378
379 settings |= MGMT_SETTING_POWERED; 379 settings |= MGMT_SETTING_POWERED;
380 settings |= MGMT_SETTING_CONNECTABLE;
381 settings |= MGMT_SETTING_FAST_CONNECTABLE;
382 settings |= MGMT_SETTING_DISCOVERABLE;
383 settings |= MGMT_SETTING_PAIRABLE; 380 settings |= MGMT_SETTING_PAIRABLE;
384 381
385 if (lmp_ssp_capable(hdev)) 382 if (lmp_ssp_capable(hdev))
386 settings |= MGMT_SETTING_SSP; 383 settings |= MGMT_SETTING_SSP;
387 384
388 if (lmp_bredr_capable(hdev)) { 385 if (lmp_bredr_capable(hdev)) {
386 settings |= MGMT_SETTING_CONNECTABLE;
387 settings |= MGMT_SETTING_FAST_CONNECTABLE;
388 settings |= MGMT_SETTING_DISCOVERABLE;
389 settings |= MGMT_SETTING_BREDR; 389 settings |= MGMT_SETTING_BREDR;
390 settings |= MGMT_SETTING_LINK_SECURITY; 390 settings |= MGMT_SETTING_LINK_SECURITY;
391 } 391 }
@@ -485,7 +485,7 @@ static void create_eir(struct hci_dev *hdev, u8 *data)
485 ptr += (name_len + 2); 485 ptr += (name_len + 2);
486 } 486 }
487 487
488 if (hdev->inq_tx_power) { 488 if (hdev->inq_tx_power != HCI_TX_POWER_INVALID) {
489 ptr[0] = 2; 489 ptr[0] = 2;
490 ptr[1] = EIR_TX_POWER; 490 ptr[1] = EIR_TX_POWER;
491 ptr[2] = (u8) hdev->inq_tx_power; 491 ptr[2] = (u8) hdev->inq_tx_power;
@@ -566,7 +566,7 @@ static int update_eir(struct hci_dev *hdev)
566 if (!hdev_is_powered(hdev)) 566 if (!hdev_is_powered(hdev))
567 return 0; 567 return 0;
568 568
569 if (!(hdev->features[6] & LMP_EXT_INQ)) 569 if (!lmp_ext_inq_capable(hdev))
570 return 0; 570 return 0;
571 571
572 if (!test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) 572 if (!test_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
@@ -833,7 +833,7 @@ static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len,
833 if (hdev) 833 if (hdev)
834 hdr->index = cpu_to_le16(hdev->id); 834 hdr->index = cpu_to_le16(hdev->id);
835 else 835 else
836 hdr->index = cpu_to_le16(MGMT_INDEX_NONE); 836 hdr->index = __constant_cpu_to_le16(MGMT_INDEX_NONE);
837 hdr->len = cpu_to_le16(data_len); 837 hdr->len = cpu_to_le16(data_len);
838 838
839 if (data) 839 if (data)
@@ -868,6 +868,10 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
868 868
869 BT_DBG("request for %s", hdev->name); 869 BT_DBG("request for %s", hdev->name);
870 870
871 if (!lmp_bredr_capable(hdev))
872 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
873 MGMT_STATUS_NOT_SUPPORTED);
874
871 timeout = __le16_to_cpu(cp->timeout); 875 timeout = __le16_to_cpu(cp->timeout);
872 if (!cp->val && timeout > 0) 876 if (!cp->val && timeout > 0)
873 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, 877 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
@@ -963,6 +967,10 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
963 967
964 BT_DBG("request for %s", hdev->name); 968 BT_DBG("request for %s", hdev->name);
965 969
970 if (!lmp_bredr_capable(hdev))
971 return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE,
972 MGMT_STATUS_NOT_SUPPORTED);
973
966 hci_dev_lock(hdev); 974 hci_dev_lock(hdev);
967 975
968 if (!hdev_is_powered(hdev)) { 976 if (!hdev_is_powered(hdev)) {
@@ -1061,6 +1069,10 @@ static int set_link_security(struct sock *sk, struct hci_dev *hdev, void *data,
1061 1069
1062 BT_DBG("request for %s", hdev->name); 1070 BT_DBG("request for %s", hdev->name);
1063 1071
1072 if (!lmp_bredr_capable(hdev))
1073 return cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY,
1074 MGMT_STATUS_NOT_SUPPORTED);
1075
1064 hci_dev_lock(hdev); 1076 hci_dev_lock(hdev);
1065 1077
1066 if (!hdev_is_powered(hdev)) { 1078 if (!hdev_is_powered(hdev)) {
@@ -1214,7 +1226,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1214 } 1226 }
1215 1227
1216 val = !!cp->val; 1228 val = !!cp->val;
1217 enabled = !!(hdev->host_features[0] & LMP_HOST_LE); 1229 enabled = !!lmp_host_le_capable(hdev);
1218 1230
1219 if (!hdev_is_powered(hdev) || val == enabled) { 1231 if (!hdev_is_powered(hdev) || val == enabled) {
1220 bool changed = false; 1232 bool changed = false;
@@ -1250,7 +1262,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1250 1262
1251 if (val) { 1263 if (val) {
1252 hci_cp.le = val; 1264 hci_cp.le = val;
1253 hci_cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); 1265 hci_cp.simul = !!lmp_le_br_capable(hdev);
1254 } 1266 }
1255 1267
1256 err = hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp), 1268 err = hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp),
@@ -2596,6 +2608,10 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev,
2596 2608
2597 BT_DBG("%s", hdev->name); 2609 BT_DBG("%s", hdev->name);
2598 2610
2611 if (!lmp_bredr_capable(hdev))
2612 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
2613 MGMT_STATUS_NOT_SUPPORTED);
2614
2599 if (!hdev_is_powered(hdev)) 2615 if (!hdev_is_powered(hdev))
2600 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, 2616 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
2601 MGMT_STATUS_NOT_POWERED); 2617 MGMT_STATUS_NOT_POWERED);
@@ -2873,6 +2889,21 @@ static void settings_rsp(struct pending_cmd *cmd, void *data)
2873 mgmt_pending_free(cmd); 2889 mgmt_pending_free(cmd);
2874} 2890}
2875 2891
2892static int set_bredr_scan(struct hci_dev *hdev)
2893{
2894 u8 scan = 0;
2895
2896 if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
2897 scan |= SCAN_PAGE;
2898 if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
2899 scan |= SCAN_INQUIRY;
2900
2901 if (!scan)
2902 return 0;
2903
2904 return hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
2905}
2906
2876int mgmt_powered(struct hci_dev *hdev, u8 powered) 2907int mgmt_powered(struct hci_dev *hdev, u8 powered)
2877{ 2908{
2878 struct cmd_lookup match = { NULL, hdev }; 2909 struct cmd_lookup match = { NULL, hdev };
@@ -2884,17 +2915,8 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered)
2884 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); 2915 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
2885 2916
2886 if (powered) { 2917 if (powered) {
2887 u8 scan = 0; 2918 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) &&
2888 2919 !lmp_host_ssp_capable(hdev)) {
2889 if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
2890 scan |= SCAN_PAGE;
2891 if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
2892 scan |= SCAN_INQUIRY;
2893
2894 if (scan)
2895 hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
2896
2897 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
2898 u8 ssp = 1; 2920 u8 ssp = 1;
2899 2921
2900 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, 1, &ssp); 2922 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, 1, &ssp);
@@ -2904,15 +2926,24 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered)
2904 struct hci_cp_write_le_host_supported cp; 2926 struct hci_cp_write_le_host_supported cp;
2905 2927
2906 cp.le = 1; 2928 cp.le = 1;
2907 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); 2929 cp.simul = !!lmp_le_br_capable(hdev);
2908 2930
2909 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, 2931 /* Check first if we already have the right
2910 sizeof(cp), &cp); 2932 * host state (host features set)
2933 */
2934 if (cp.le != !!lmp_host_le_capable(hdev) ||
2935 cp.simul != !!lmp_host_le_br_capable(hdev))
2936 hci_send_cmd(hdev,
2937 HCI_OP_WRITE_LE_HOST_SUPPORTED,
2938 sizeof(cp), &cp);
2911 } 2939 }
2912 2940
2913 update_class(hdev); 2941 if (lmp_bredr_capable(hdev)) {
2914 update_name(hdev, hdev->dev_name); 2942 set_bredr_scan(hdev);
2915 update_eir(hdev); 2943 update_class(hdev);
2944 update_name(hdev, hdev->dev_name);
2945 update_eir(hdev);
2946 }
2916 } else { 2947 } else {
2917 u8 status = MGMT_STATUS_NOT_POWERED; 2948 u8 status = MGMT_STATUS_NOT_POWERED;
2918 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); 2949 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
@@ -3361,7 +3392,7 @@ static int clear_eir(struct hci_dev *hdev)
3361{ 3392{
3362 struct hci_cp_write_eir cp; 3393 struct hci_cp_write_eir cp;
3363 3394
3364 if (!(hdev->features[6] & LMP_EXT_INQ)) 3395 if (!lmp_ext_inq_capable(hdev))
3365 return 0; 3396 return 0;
3366 3397
3367 memset(hdev->eir, 0, sizeof(hdev->eir)); 3398 memset(hdev->eir, 0, sizeof(hdev->eir));
@@ -3493,7 +3524,12 @@ send_event:
3493 err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, 3524 err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev,
3494 sizeof(ev), cmd ? cmd->sk : NULL); 3525 sizeof(ev), cmd ? cmd->sk : NULL);
3495 3526
3496 update_eir(hdev); 3527 /* EIR is taken care of separately when powering on the
3528 * adapter so only update them here if this is a name change
3529 * unrelated to power on.
3530 */
3531 if (!test_bit(HCI_INIT, &hdev->flags))
3532 update_eir(hdev);
3497 3533
3498failed: 3534failed:
3499 if (cmd) 3535 if (cmd)
@@ -3588,9 +3624,9 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
3588 ev->addr.type = link_to_bdaddr(link_type, addr_type); 3624 ev->addr.type = link_to_bdaddr(link_type, addr_type);
3589 ev->rssi = rssi; 3625 ev->rssi = rssi;
3590 if (cfm_name) 3626 if (cfm_name)
3591 ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME); 3627 ev->flags |= __constant_cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME);
3592 if (!ssp) 3628 if (!ssp)
3593 ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_LEGACY_PAIRING); 3629 ev->flags |= __constant_cpu_to_le32(MGMT_DEV_FOUND_LEGACY_PAIRING);
3594 3630
3595 if (eir_len > 0) 3631 if (eir_len > 0)
3596 memcpy(ev->eir, eir, eir_len); 3632 memcpy(ev->eir, eir, eir_len);