diff options
Diffstat (limited to 'net/bluetooth/mgmt.c')
| -rw-r--r-- | net/bluetooth/mgmt.c | 617 |
1 files changed, 449 insertions, 168 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 693ce8bcd06e..9ec5390c85eb 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <net/bluetooth/l2cap.h> | 32 | #include <net/bluetooth/l2cap.h> |
| 33 | #include <net/bluetooth/mgmt.h> | 33 | #include <net/bluetooth/mgmt.h> |
| 34 | 34 | ||
| 35 | #include "hci_request.h" | ||
| 35 | #include "smp.h" | 36 | #include "smp.h" |
| 36 | 37 | ||
| 37 | #define MGMT_VERSION 1 | 38 | #define MGMT_VERSION 1 |
| @@ -130,6 +131,9 @@ static const u16 mgmt_events[] = { | |||
| 130 | 131 | ||
| 131 | #define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000) | 132 | #define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000) |
| 132 | 133 | ||
| 134 | #define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \ | ||
| 135 | "\x00\x00\x00\x00\x00\x00\x00\x00" | ||
| 136 | |||
| 133 | struct pending_cmd { | 137 | struct pending_cmd { |
| 134 | struct list_head list; | 138 | struct list_head list; |
| 135 | u16 opcode; | 139 | u16 opcode; |
| @@ -138,7 +142,7 @@ struct pending_cmd { | |||
| 138 | size_t param_len; | 142 | size_t param_len; |
| 139 | struct sock *sk; | 143 | struct sock *sk; |
| 140 | void *user_data; | 144 | void *user_data; |
| 141 | void (*cmd_complete)(struct pending_cmd *cmd, u8 status); | 145 | int (*cmd_complete)(struct pending_cmd *cmd, u8 status); |
| 142 | }; | 146 | }; |
| 143 | 147 | ||
| 144 | /* HCI to MGMT error code conversion table */ | 148 | /* HCI to MGMT error code conversion table */ |
| @@ -569,8 +573,7 @@ static u32 get_supported_settings(struct hci_dev *hdev) | |||
| 569 | settings |= MGMT_SETTING_HS; | 573 | settings |= MGMT_SETTING_HS; |
| 570 | } | 574 | } |
| 571 | 575 | ||
| 572 | if (lmp_sc_capable(hdev) || | 576 | if (lmp_sc_capable(hdev)) |
| 573 | test_bit(HCI_FORCE_SC, &hdev->dbg_flags)) | ||
| 574 | settings |= MGMT_SETTING_SECURE_CONN; | 577 | settings |= MGMT_SETTING_SECURE_CONN; |
| 575 | } | 578 | } |
| 576 | 579 | ||
| @@ -1251,7 +1254,7 @@ static int send_settings_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev) | |||
| 1251 | sizeof(settings)); | 1254 | sizeof(settings)); |
| 1252 | } | 1255 | } |
| 1253 | 1256 | ||
| 1254 | static void clean_up_hci_complete(struct hci_dev *hdev, u8 status) | 1257 | static void clean_up_hci_complete(struct hci_dev *hdev, u8 status, u16 opcode) |
| 1255 | { | 1258 | { |
| 1256 | BT_DBG("%s status 0x%02x", hdev->name, status); | 1259 | BT_DBG("%s status 0x%02x", hdev->name, status); |
| 1257 | 1260 | ||
| @@ -1486,16 +1489,16 @@ static void cmd_complete_rsp(struct pending_cmd *cmd, void *data) | |||
| 1486 | cmd_status_rsp(cmd, data); | 1489 | cmd_status_rsp(cmd, data); |
| 1487 | } | 1490 | } |
| 1488 | 1491 | ||
| 1489 | static void generic_cmd_complete(struct pending_cmd *cmd, u8 status) | 1492 | static int generic_cmd_complete(struct pending_cmd *cmd, u8 status) |
| 1490 | { | 1493 | { |
| 1491 | cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, cmd->param, | 1494 | return cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, |
| 1492 | cmd->param_len); | 1495 | cmd->param, cmd->param_len); |
| 1493 | } | 1496 | } |
| 1494 | 1497 | ||
| 1495 | static void addr_cmd_complete(struct pending_cmd *cmd, u8 status) | 1498 | static int addr_cmd_complete(struct pending_cmd *cmd, u8 status) |
| 1496 | { | 1499 | { |
| 1497 | cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, cmd->param, | 1500 | return cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, cmd->param, |
| 1498 | sizeof(struct mgmt_addr_info)); | 1501 | sizeof(struct mgmt_addr_info)); |
| 1499 | } | 1502 | } |
| 1500 | 1503 | ||
| 1501 | static u8 mgmt_bredr_support(struct hci_dev *hdev) | 1504 | static u8 mgmt_bredr_support(struct hci_dev *hdev) |
| @@ -1518,7 +1521,8 @@ static u8 mgmt_le_support(struct hci_dev *hdev) | |||
| 1518 | return MGMT_STATUS_SUCCESS; | 1521 | return MGMT_STATUS_SUCCESS; |
| 1519 | } | 1522 | } |
| 1520 | 1523 | ||
| 1521 | static void set_discoverable_complete(struct hci_dev *hdev, u8 status) | 1524 | static void set_discoverable_complete(struct hci_dev *hdev, u8 status, |
| 1525 | u16 opcode) | ||
| 1522 | { | 1526 | { |
| 1523 | struct pending_cmd *cmd; | 1527 | struct pending_cmd *cmd; |
| 1524 | struct mgmt_mode *cp; | 1528 | struct mgmt_mode *cp; |
| @@ -1566,7 +1570,7 @@ static void set_discoverable_complete(struct hci_dev *hdev, u8 status) | |||
| 1566 | * entries. | 1570 | * entries. |
| 1567 | */ | 1571 | */ |
| 1568 | hci_req_init(&req, hdev); | 1572 | hci_req_init(&req, hdev); |
| 1569 | hci_update_page_scan(hdev, &req); | 1573 | __hci_update_page_scan(&req); |
| 1570 | update_class(&req); | 1574 | update_class(&req); |
| 1571 | hci_req_run(&req, NULL); | 1575 | hci_req_run(&req, NULL); |
| 1572 | 1576 | ||
| @@ -1777,7 +1781,8 @@ static void write_fast_connectable(struct hci_request *req, bool enable) | |||
| 1777 | hci_req_add(req, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type); | 1781 | hci_req_add(req, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type); |
| 1778 | } | 1782 | } |
| 1779 | 1783 | ||
| 1780 | static void set_connectable_complete(struct hci_dev *hdev, u8 status) | 1784 | static void set_connectable_complete(struct hci_dev *hdev, u8 status, |
| 1785 | u16 opcode) | ||
| 1781 | { | 1786 | { |
| 1782 | struct pending_cmd *cmd; | 1787 | struct pending_cmd *cmd; |
| 1783 | struct mgmt_mode *cp; | 1788 | struct mgmt_mode *cp; |
| @@ -1813,7 +1818,7 @@ static void set_connectable_complete(struct hci_dev *hdev, u8 status) | |||
| 1813 | 1818 | ||
| 1814 | if (conn_changed || discov_changed) { | 1819 | if (conn_changed || discov_changed) { |
| 1815 | new_settings(hdev, cmd->sk); | 1820 | new_settings(hdev, cmd->sk); |
| 1816 | hci_update_page_scan(hdev, NULL); | 1821 | hci_update_page_scan(hdev); |
| 1817 | if (discov_changed) | 1822 | if (discov_changed) |
| 1818 | mgmt_update_adv_data(hdev); | 1823 | mgmt_update_adv_data(hdev); |
| 1819 | hci_update_background_scan(hdev); | 1824 | hci_update_background_scan(hdev); |
| @@ -1847,7 +1852,7 @@ static int set_connectable_update_settings(struct hci_dev *hdev, | |||
| 1847 | return err; | 1852 | return err; |
| 1848 | 1853 | ||
| 1849 | if (changed) { | 1854 | if (changed) { |
| 1850 | hci_update_page_scan(hdev, NULL); | 1855 | hci_update_page_scan(hdev); |
| 1851 | hci_update_background_scan(hdev); | 1856 | hci_update_background_scan(hdev); |
| 1852 | return new_settings(hdev, sk); | 1857 | return new_settings(hdev, sk); |
| 1853 | } | 1858 | } |
| @@ -2195,7 +2200,7 @@ unlock: | |||
| 2195 | return err; | 2200 | return err; |
| 2196 | } | 2201 | } |
| 2197 | 2202 | ||
| 2198 | static void le_enable_complete(struct hci_dev *hdev, u8 status) | 2203 | static void le_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode) |
| 2199 | { | 2204 | { |
| 2200 | struct cmd_lookup match = { NULL, hdev }; | 2205 | struct cmd_lookup match = { NULL, hdev }; |
| 2201 | 2206 | ||
| @@ -2227,9 +2232,8 @@ static void le_enable_complete(struct hci_dev *hdev, u8 status) | |||
| 2227 | hci_req_init(&req, hdev); | 2232 | hci_req_init(&req, hdev); |
| 2228 | update_adv_data(&req); | 2233 | update_adv_data(&req); |
| 2229 | update_scan_rsp_data(&req); | 2234 | update_scan_rsp_data(&req); |
| 2235 | __hci_update_background_scan(&req); | ||
| 2230 | hci_req_run(&req, NULL); | 2236 | hci_req_run(&req, NULL); |
| 2231 | |||
| 2232 | hci_update_background_scan(hdev); | ||
| 2233 | } | 2237 | } |
| 2234 | 2238 | ||
| 2235 | unlock: | 2239 | unlock: |
| @@ -2386,7 +2390,7 @@ unlock: | |||
| 2386 | hci_dev_unlock(hdev); | 2390 | hci_dev_unlock(hdev); |
| 2387 | } | 2391 | } |
| 2388 | 2392 | ||
| 2389 | static void add_uuid_complete(struct hci_dev *hdev, u8 status) | 2393 | static void add_uuid_complete(struct hci_dev *hdev, u8 status, u16 opcode) |
| 2390 | { | 2394 | { |
| 2391 | BT_DBG("status 0x%02x", status); | 2395 | BT_DBG("status 0x%02x", status); |
| 2392 | 2396 | ||
| @@ -2465,7 +2469,7 @@ static bool enable_service_cache(struct hci_dev *hdev) | |||
| 2465 | return false; | 2469 | return false; |
| 2466 | } | 2470 | } |
| 2467 | 2471 | ||
| 2468 | static void remove_uuid_complete(struct hci_dev *hdev, u8 status) | 2472 | static void remove_uuid_complete(struct hci_dev *hdev, u8 status, u16 opcode) |
| 2469 | { | 2473 | { |
| 2470 | BT_DBG("status 0x%02x", status); | 2474 | BT_DBG("status 0x%02x", status); |
| 2471 | 2475 | ||
| @@ -2550,7 +2554,7 @@ unlock: | |||
| 2550 | return err; | 2554 | return err; |
| 2551 | } | 2555 | } |
| 2552 | 2556 | ||
| 2553 | static void set_class_complete(struct hci_dev *hdev, u8 status) | 2557 | static void set_class_complete(struct hci_dev *hdev, u8 status, u16 opcode) |
| 2554 | { | 2558 | { |
| 2555 | BT_DBG("status 0x%02x", status); | 2559 | BT_DBG("status 0x%02x", status); |
| 2556 | 2560 | ||
| @@ -3098,16 +3102,17 @@ static struct pending_cmd *find_pairing(struct hci_conn *conn) | |||
| 3098 | return NULL; | 3102 | return NULL; |
| 3099 | } | 3103 | } |
| 3100 | 3104 | ||
| 3101 | static void pairing_complete(struct pending_cmd *cmd, u8 status) | 3105 | static int pairing_complete(struct pending_cmd *cmd, u8 status) |
| 3102 | { | 3106 | { |
| 3103 | struct mgmt_rp_pair_device rp; | 3107 | struct mgmt_rp_pair_device rp; |
| 3104 | struct hci_conn *conn = cmd->user_data; | 3108 | struct hci_conn *conn = cmd->user_data; |
| 3109 | int err; | ||
| 3105 | 3110 | ||
| 3106 | bacpy(&rp.addr.bdaddr, &conn->dst); | 3111 | bacpy(&rp.addr.bdaddr, &conn->dst); |
| 3107 | rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type); | 3112 | rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type); |
| 3108 | 3113 | ||
| 3109 | cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, status, | 3114 | err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, status, |
| 3110 | &rp, sizeof(rp)); | 3115 | &rp, sizeof(rp)); |
| 3111 | 3116 | ||
| 3112 | /* So we don't get further callbacks for this connection */ | 3117 | /* So we don't get further callbacks for this connection */ |
| 3113 | conn->connect_cfm_cb = NULL; | 3118 | conn->connect_cfm_cb = NULL; |
| @@ -3122,6 +3127,8 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status) | |||
| 3122 | clear_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags); | 3127 | clear_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags); |
| 3123 | 3128 | ||
| 3124 | hci_conn_put(conn); | 3129 | hci_conn_put(conn); |
| 3130 | |||
| 3131 | return err; | ||
| 3125 | } | 3132 | } |
| 3126 | 3133 | ||
| 3127 | void mgmt_smp_complete(struct hci_conn *conn, bool complete) | 3134 | void mgmt_smp_complete(struct hci_conn *conn, bool complete) |
| @@ -3481,7 +3488,7 @@ static void update_name(struct hci_request *req) | |||
| 3481 | hci_req_add(req, HCI_OP_WRITE_LOCAL_NAME, sizeof(cp), &cp); | 3488 | hci_req_add(req, HCI_OP_WRITE_LOCAL_NAME, sizeof(cp), &cp); |
| 3482 | } | 3489 | } |
| 3483 | 3490 | ||
| 3484 | static void set_name_complete(struct hci_dev *hdev, u8 status) | 3491 | static void set_name_complete(struct hci_dev *hdev, u8 status, u16 opcode) |
| 3485 | { | 3492 | { |
| 3486 | struct mgmt_cp_set_local_name *cp; | 3493 | struct mgmt_cp_set_local_name *cp; |
| 3487 | struct pending_cmd *cmd; | 3494 | struct pending_cmd *cmd; |
| @@ -3629,10 +3636,16 @@ unlock: | |||
| 3629 | static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, | 3636 | static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, |
| 3630 | void *data, u16 len) | 3637 | void *data, u16 len) |
| 3631 | { | 3638 | { |
| 3639 | struct mgmt_addr_info *addr = data; | ||
| 3632 | int err; | 3640 | int err; |
| 3633 | 3641 | ||
| 3634 | BT_DBG("%s ", hdev->name); | 3642 | BT_DBG("%s ", hdev->name); |
| 3635 | 3643 | ||
| 3644 | if (!bdaddr_type_is_valid(addr->type)) | ||
| 3645 | return cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, | ||
| 3646 | MGMT_STATUS_INVALID_PARAMS, addr, | ||
| 3647 | sizeof(*addr)); | ||
| 3648 | |||
| 3636 | hci_dev_lock(hdev); | 3649 | hci_dev_lock(hdev); |
| 3637 | 3650 | ||
| 3638 | if (len == MGMT_ADD_REMOTE_OOB_DATA_SIZE) { | 3651 | if (len == MGMT_ADD_REMOTE_OOB_DATA_SIZE) { |
| @@ -3659,28 +3672,53 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, | |||
| 3659 | status, &cp->addr, sizeof(cp->addr)); | 3672 | status, &cp->addr, sizeof(cp->addr)); |
| 3660 | } else if (len == MGMT_ADD_REMOTE_OOB_EXT_DATA_SIZE) { | 3673 | } else if (len == MGMT_ADD_REMOTE_OOB_EXT_DATA_SIZE) { |
| 3661 | struct mgmt_cp_add_remote_oob_ext_data *cp = data; | 3674 | struct mgmt_cp_add_remote_oob_ext_data *cp = data; |
| 3662 | u8 *rand192, *hash192; | 3675 | u8 *rand192, *hash192, *rand256, *hash256; |
| 3663 | u8 status; | 3676 | u8 status; |
| 3664 | 3677 | ||
| 3665 | if (cp->addr.type != BDADDR_BREDR) { | ||
| 3666 | err = cmd_complete(sk, hdev->id, | ||
| 3667 | MGMT_OP_ADD_REMOTE_OOB_DATA, | ||
| 3668 | MGMT_STATUS_INVALID_PARAMS, | ||
| 3669 | &cp->addr, sizeof(cp->addr)); | ||
| 3670 | goto unlock; | ||
| 3671 | } | ||
| 3672 | |||
| 3673 | if (bdaddr_type_is_le(cp->addr.type)) { | 3678 | if (bdaddr_type_is_le(cp->addr.type)) { |
| 3679 | /* Enforce zero-valued 192-bit parameters as | ||
| 3680 | * long as legacy SMP OOB isn't implemented. | ||
| 3681 | */ | ||
| 3682 | if (memcmp(cp->rand192, ZERO_KEY, 16) || | ||
| 3683 | memcmp(cp->hash192, ZERO_KEY, 16)) { | ||
| 3684 | err = cmd_complete(sk, hdev->id, | ||
| 3685 | MGMT_OP_ADD_REMOTE_OOB_DATA, | ||
| 3686 | MGMT_STATUS_INVALID_PARAMS, | ||
| 3687 | addr, sizeof(*addr)); | ||
| 3688 | goto unlock; | ||
| 3689 | } | ||
| 3690 | |||
| 3674 | rand192 = NULL; | 3691 | rand192 = NULL; |
| 3675 | hash192 = NULL; | 3692 | hash192 = NULL; |
| 3676 | } else { | 3693 | } else { |
| 3677 | rand192 = cp->rand192; | 3694 | /* In case one of the P-192 values is set to zero, |
| 3678 | hash192 = cp->hash192; | 3695 | * then just disable OOB data for P-192. |
| 3696 | */ | ||
| 3697 | if (!memcmp(cp->rand192, ZERO_KEY, 16) || | ||
| 3698 | !memcmp(cp->hash192, ZERO_KEY, 16)) { | ||
| 3699 | rand192 = NULL; | ||
| 3700 | hash192 = NULL; | ||
| 3701 | } else { | ||
| 3702 | rand192 = cp->rand192; | ||
| 3703 | hash192 = cp->hash192; | ||
| 3704 | } | ||
| 3705 | } | ||
| 3706 | |||
| 3707 | /* In case one of the P-256 values is set to zero, then just | ||
| 3708 | * disable OOB data for P-256. | ||
| 3709 | */ | ||
| 3710 | if (!memcmp(cp->rand256, ZERO_KEY, 16) || | ||
| 3711 | !memcmp(cp->hash256, ZERO_KEY, 16)) { | ||
| 3712 | rand256 = NULL; | ||
| 3713 | hash256 = NULL; | ||
| 3714 | } else { | ||
| 3715 | rand256 = cp->rand256; | ||
| 3716 | hash256 = cp->hash256; | ||
| 3679 | } | 3717 | } |
| 3680 | 3718 | ||
| 3681 | err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr, | 3719 | err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr, |
| 3682 | cp->addr.type, hash192, rand192, | 3720 | cp->addr.type, hash192, rand192, |
| 3683 | cp->hash256, cp->rand256); | 3721 | hash256, rand256); |
| 3684 | if (err < 0) | 3722 | if (err < 0) |
| 3685 | status = MGMT_STATUS_FAILED; | 3723 | status = MGMT_STATUS_FAILED; |
| 3686 | else | 3724 | else |
| @@ -3832,7 +3870,8 @@ static bool trigger_discovery(struct hci_request *req, u8 *status) | |||
| 3832 | return true; | 3870 | return true; |
| 3833 | } | 3871 | } |
| 3834 | 3872 | ||
| 3835 | static void start_discovery_complete(struct hci_dev *hdev, u8 status) | 3873 | static void start_discovery_complete(struct hci_dev *hdev, u8 status, |
| 3874 | u16 opcode) | ||
| 3836 | { | 3875 | { |
| 3837 | struct pending_cmd *cmd; | 3876 | struct pending_cmd *cmd; |
| 3838 | unsigned long timeout; | 3877 | unsigned long timeout; |
| @@ -3857,6 +3896,9 @@ static void start_discovery_complete(struct hci_dev *hdev, u8 status) | |||
| 3857 | 3896 | ||
| 3858 | hci_discovery_set_state(hdev, DISCOVERY_FINDING); | 3897 | hci_discovery_set_state(hdev, DISCOVERY_FINDING); |
| 3859 | 3898 | ||
| 3899 | /* If the scan involves LE scan, pick proper timeout to schedule | ||
| 3900 | * hdev->le_scan_disable that will stop it. | ||
| 3901 | */ | ||
| 3860 | switch (hdev->discovery.type) { | 3902 | switch (hdev->discovery.type) { |
| 3861 | case DISCOV_TYPE_LE: | 3903 | case DISCOV_TYPE_LE: |
| 3862 | timeout = msecs_to_jiffies(DISCOV_LE_TIMEOUT); | 3904 | timeout = msecs_to_jiffies(DISCOV_LE_TIMEOUT); |
| @@ -3873,9 +3915,23 @@ static void start_discovery_complete(struct hci_dev *hdev, u8 status) | |||
| 3873 | break; | 3915 | break; |
| 3874 | } | 3916 | } |
| 3875 | 3917 | ||
| 3876 | if (timeout) | 3918 | if (timeout) { |
| 3919 | /* When service discovery is used and the controller has | ||
| 3920 | * a strict duplicate filter, it is important to remember | ||
| 3921 | * the start and duration of the scan. This is required | ||
| 3922 | * for restarting scanning during the discovery phase. | ||
| 3923 | */ | ||
| 3924 | if (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, | ||
| 3925 | &hdev->quirks) && | ||
| 3926 | (hdev->discovery.uuid_count > 0 || | ||
| 3927 | hdev->discovery.rssi != HCI_RSSI_INVALID)) { | ||
| 3928 | hdev->discovery.scan_start = jiffies; | ||
| 3929 | hdev->discovery.scan_duration = timeout; | ||
| 3930 | } | ||
| 3931 | |||
| 3877 | queue_delayed_work(hdev->workqueue, | 3932 | queue_delayed_work(hdev->workqueue, |
| 3878 | &hdev->le_scan_disable, timeout); | 3933 | &hdev->le_scan_disable, timeout); |
| 3934 | } | ||
| 3879 | 3935 | ||
| 3880 | unlock: | 3936 | unlock: |
| 3881 | hci_dev_unlock(hdev); | 3937 | hci_dev_unlock(hdev); |
| @@ -3947,9 +4003,10 @@ failed: | |||
| 3947 | return err; | 4003 | return err; |
| 3948 | } | 4004 | } |
| 3949 | 4005 | ||
| 3950 | static void service_discovery_cmd_complete(struct pending_cmd *cmd, u8 status) | 4006 | static int service_discovery_cmd_complete(struct pending_cmd *cmd, u8 status) |
| 3951 | { | 4007 | { |
| 3952 | cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, cmd->param, 1); | 4008 | return cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, |
| 4009 | cmd->param, 1); | ||
| 3953 | } | 4010 | } |
| 3954 | 4011 | ||
| 3955 | static int start_service_discovery(struct sock *sk, struct hci_dev *hdev, | 4012 | static int start_service_discovery(struct sock *sk, struct hci_dev *hdev, |
| @@ -4060,7 +4117,7 @@ failed: | |||
| 4060 | return err; | 4117 | return err; |
| 4061 | } | 4118 | } |
| 4062 | 4119 | ||
| 4063 | static void stop_discovery_complete(struct hci_dev *hdev, u8 status) | 4120 | static void stop_discovery_complete(struct hci_dev *hdev, u8 status, u16 opcode) |
| 4064 | { | 4121 | { |
| 4065 | struct pending_cmd *cmd; | 4122 | struct pending_cmd *cmd; |
| 4066 | 4123 | ||
| @@ -4286,7 +4343,8 @@ static int set_device_id(struct sock *sk, struct hci_dev *hdev, void *data, | |||
| 4286 | return err; | 4343 | return err; |
| 4287 | } | 4344 | } |
| 4288 | 4345 | ||
| 4289 | static void set_advertising_complete(struct hci_dev *hdev, u8 status) | 4346 | static void set_advertising_complete(struct hci_dev *hdev, u8 status, |
| 4347 | u16 opcode) | ||
| 4290 | { | 4348 | { |
| 4291 | struct cmd_lookup match = { NULL, hdev }; | 4349 | struct cmd_lookup match = { NULL, hdev }; |
| 4292 | 4350 | ||
| @@ -4493,7 +4551,8 @@ static int set_scan_params(struct sock *sk, struct hci_dev *hdev, | |||
| 4493 | return err; | 4551 | return err; |
| 4494 | } | 4552 | } |
| 4495 | 4553 | ||
| 4496 | static void fast_connectable_complete(struct hci_dev *hdev, u8 status) | 4554 | static void fast_connectable_complete(struct hci_dev *hdev, u8 status, |
| 4555 | u16 opcode) | ||
| 4497 | { | 4556 | { |
| 4498 | struct pending_cmd *cmd; | 4557 | struct pending_cmd *cmd; |
| 4499 | 4558 | ||
| @@ -4591,7 +4650,7 @@ unlock: | |||
| 4591 | return err; | 4650 | return err; |
| 4592 | } | 4651 | } |
| 4593 | 4652 | ||
| 4594 | static void set_bredr_complete(struct hci_dev *hdev, u8 status) | 4653 | static void set_bredr_complete(struct hci_dev *hdev, u8 status, u16 opcode) |
| 4595 | { | 4654 | { |
| 4596 | struct pending_cmd *cmd; | 4655 | struct pending_cmd *cmd; |
| 4597 | 4656 | ||
| @@ -4675,6 +4734,28 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) | |||
| 4675 | err = cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR, | 4734 | err = cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR, |
| 4676 | MGMT_STATUS_REJECTED); | 4735 | MGMT_STATUS_REJECTED); |
| 4677 | goto unlock; | 4736 | goto unlock; |
| 4737 | } else { | ||
| 4738 | /* When configuring a dual-mode controller to operate | ||
| 4739 | * with LE only and using a static address, then switching | ||
| 4740 | * BR/EDR back on is not allowed. | ||
| 4741 | * | ||
| 4742 | * Dual-mode controllers shall operate with the public | ||
| 4743 | * address as its identity address for BR/EDR and LE. So | ||
| 4744 | * reject the attempt to create an invalid configuration. | ||
| 4745 | * | ||
| 4746 | * The same restrictions applies when secure connections | ||
| 4747 | * has been enabled. For BR/EDR this is a controller feature | ||
| 4748 | * while for LE it is a host stack feature. This means that | ||
| 4749 | * switching BR/EDR back on when secure connections has been | ||
| 4750 | * enabled is not a supported transaction. | ||
| 4751 | */ | ||
| 4752 | if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags) && | ||
| 4753 | (bacmp(&hdev->static_addr, BDADDR_ANY) || | ||
| 4754 | test_bit(HCI_SC_ENABLED, &hdev->dev_flags))) { | ||
| 4755 | err = cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR, | ||
| 4756 | MGMT_STATUS_REJECTED); | ||
| 4757 | goto unlock; | ||
| 4758 | } | ||
| 4678 | } | 4759 | } |
| 4679 | 4760 | ||
| 4680 | if (mgmt_pending_find(MGMT_OP_SET_BREDR, hdev)) { | 4761 | if (mgmt_pending_find(MGMT_OP_SET_BREDR, hdev)) { |
| @@ -4697,7 +4778,7 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) | |||
| 4697 | hci_req_init(&req, hdev); | 4778 | hci_req_init(&req, hdev); |
| 4698 | 4779 | ||
| 4699 | write_fast_connectable(&req, false); | 4780 | write_fast_connectable(&req, false); |
| 4700 | hci_update_page_scan(hdev, &req); | 4781 | __hci_update_page_scan(&req); |
| 4701 | 4782 | ||
| 4702 | /* Since only the advertising data flags will change, there | 4783 | /* Since only the advertising data flags will change, there |
| 4703 | * is no need to update the scan response data. | 4784 | * is no need to update the scan response data. |
| @@ -4713,30 +4794,80 @@ unlock: | |||
| 4713 | return err; | 4794 | return err; |
| 4714 | } | 4795 | } |
| 4715 | 4796 | ||
| 4797 | static void sc_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode) | ||
| 4798 | { | ||
| 4799 | struct pending_cmd *cmd; | ||
| 4800 | struct mgmt_mode *cp; | ||
| 4801 | |||
| 4802 | BT_DBG("%s status %u", hdev->name, status); | ||
| 4803 | |||
| 4804 | hci_dev_lock(hdev); | ||
| 4805 | |||
| 4806 | cmd = mgmt_pending_find(MGMT_OP_SET_SECURE_CONN, hdev); | ||
| 4807 | if (!cmd) | ||
| 4808 | goto unlock; | ||
| 4809 | |||
| 4810 | if (status) { | ||
| 4811 | cmd_status(cmd->sk, cmd->index, cmd->opcode, | ||
| 4812 | mgmt_status(status)); | ||
| 4813 | goto remove; | ||
| 4814 | } | ||
| 4815 | |||
| 4816 | cp = cmd->param; | ||
| 4817 | |||
| 4818 | switch (cp->val) { | ||
| 4819 | case 0x00: | ||
| 4820 | clear_bit(HCI_SC_ENABLED, &hdev->dev_flags); | ||
| 4821 | clear_bit(HCI_SC_ONLY, &hdev->dev_flags); | ||
| 4822 | break; | ||
| 4823 | case 0x01: | ||
| 4824 | set_bit(HCI_SC_ENABLED, &hdev->dev_flags); | ||
| 4825 | clear_bit(HCI_SC_ONLY, &hdev->dev_flags); | ||
| 4826 | break; | ||
| 4827 | case 0x02: | ||
| 4828 | set_bit(HCI_SC_ENABLED, &hdev->dev_flags); | ||
| 4829 | set_bit(HCI_SC_ONLY, &hdev->dev_flags); | ||
| 4830 | break; | ||
| 4831 | } | ||
| 4832 | |||
| 4833 | send_settings_rsp(cmd->sk, MGMT_OP_SET_SECURE_CONN, hdev); | ||
| 4834 | new_settings(hdev, cmd->sk); | ||
| 4835 | |||
| 4836 | remove: | ||
| 4837 | mgmt_pending_remove(cmd); | ||
| 4838 | unlock: | ||
| 4839 | hci_dev_unlock(hdev); | ||
| 4840 | } | ||
| 4841 | |||
| 4716 | static int set_secure_conn(struct sock *sk, struct hci_dev *hdev, | 4842 | static int set_secure_conn(struct sock *sk, struct hci_dev *hdev, |
| 4717 | void *data, u16 len) | 4843 | void *data, u16 len) |
| 4718 | { | 4844 | { |
| 4719 | struct mgmt_mode *cp = data; | 4845 | struct mgmt_mode *cp = data; |
| 4720 | struct pending_cmd *cmd; | 4846 | struct pending_cmd *cmd; |
| 4847 | struct hci_request req; | ||
| 4721 | u8 val; | 4848 | u8 val; |
| 4722 | int err; | 4849 | int err; |
| 4723 | 4850 | ||
| 4724 | BT_DBG("request for %s", hdev->name); | 4851 | BT_DBG("request for %s", hdev->name); |
| 4725 | 4852 | ||
| 4726 | if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags) && | 4853 | if (!lmp_sc_capable(hdev) && |
| 4727 | !lmp_sc_capable(hdev) && !test_bit(HCI_FORCE_SC, &hdev->dbg_flags)) | 4854 | !test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) |
| 4728 | return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, | 4855 | return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, |
| 4729 | MGMT_STATUS_NOT_SUPPORTED); | 4856 | MGMT_STATUS_NOT_SUPPORTED); |
| 4730 | 4857 | ||
| 4858 | if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags) && | ||
| 4859 | lmp_sc_capable(hdev) && | ||
| 4860 | !test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) | ||
| 4861 | return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, | ||
| 4862 | MGMT_STATUS_REJECTED); | ||
| 4863 | |||
| 4731 | if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02) | 4864 | if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02) |
| 4732 | return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, | 4865 | return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, |
| 4733 | MGMT_STATUS_INVALID_PARAMS); | 4866 | MGMT_STATUS_INVALID_PARAMS); |
| 4734 | 4867 | ||
| 4735 | hci_dev_lock(hdev); | 4868 | hci_dev_lock(hdev); |
| 4736 | 4869 | ||
| 4737 | if (!hdev_is_powered(hdev) || | 4870 | if (!hdev_is_powered(hdev) || !lmp_sc_capable(hdev) || |
| 4738 | (!lmp_sc_capable(hdev) && | ||
| 4739 | !test_bit(HCI_FORCE_SC, &hdev->dbg_flags)) || | ||
| 4740 | !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { | 4871 | !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { |
| 4741 | bool changed; | 4872 | bool changed; |
| 4742 | 4873 | ||
| @@ -4783,17 +4914,14 @@ static int set_secure_conn(struct sock *sk, struct hci_dev *hdev, | |||
| 4783 | goto failed; | 4914 | goto failed; |
| 4784 | } | 4915 | } |
| 4785 | 4916 | ||
| 4786 | err = hci_send_cmd(hdev, HCI_OP_WRITE_SC_SUPPORT, 1, &val); | 4917 | hci_req_init(&req, hdev); |
| 4918 | hci_req_add(&req, HCI_OP_WRITE_SC_SUPPORT, 1, &val); | ||
| 4919 | err = hci_req_run(&req, sc_enable_complete); | ||
| 4787 | if (err < 0) { | 4920 | if (err < 0) { |
| 4788 | mgmt_pending_remove(cmd); | 4921 | mgmt_pending_remove(cmd); |
| 4789 | goto failed; | 4922 | goto failed; |
| 4790 | } | 4923 | } |
| 4791 | 4924 | ||
| 4792 | if (cp->val == 0x02) | ||
| 4793 | set_bit(HCI_SC_ONLY, &hdev->dev_flags); | ||
| 4794 | else | ||
| 4795 | clear_bit(HCI_SC_ONLY, &hdev->dev_flags); | ||
| 4796 | |||
| 4797 | failed: | 4925 | failed: |
| 4798 | hci_dev_unlock(hdev); | 4926 | hci_dev_unlock(hdev); |
| 4799 | return err; | 4927 | return err; |
| @@ -5091,10 +5219,11 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, | |||
| 5091 | return err; | 5219 | return err; |
| 5092 | } | 5220 | } |
| 5093 | 5221 | ||
| 5094 | static void conn_info_cmd_complete(struct pending_cmd *cmd, u8 status) | 5222 | static int conn_info_cmd_complete(struct pending_cmd *cmd, u8 status) |
| 5095 | { | 5223 | { |
| 5096 | struct hci_conn *conn = cmd->user_data; | 5224 | struct hci_conn *conn = cmd->user_data; |
| 5097 | struct mgmt_rp_get_conn_info rp; | 5225 | struct mgmt_rp_get_conn_info rp; |
| 5226 | int err; | ||
| 5098 | 5227 | ||
| 5099 | memcpy(&rp.addr, cmd->param, sizeof(rp.addr)); | 5228 | memcpy(&rp.addr, cmd->param, sizeof(rp.addr)); |
| 5100 | 5229 | ||
| @@ -5108,14 +5237,17 @@ static void conn_info_cmd_complete(struct pending_cmd *cmd, u8 status) | |||
| 5108 | rp.max_tx_power = HCI_TX_POWER_INVALID; | 5237 | rp.max_tx_power = HCI_TX_POWER_INVALID; |
| 5109 | } | 5238 | } |
| 5110 | 5239 | ||
| 5111 | cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, status, | 5240 | err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, status, |
| 5112 | &rp, sizeof(rp)); | 5241 | &rp, sizeof(rp)); |
| 5113 | 5242 | ||
| 5114 | hci_conn_drop(conn); | 5243 | hci_conn_drop(conn); |
| 5115 | hci_conn_put(conn); | 5244 | hci_conn_put(conn); |
| 5245 | |||
| 5246 | return err; | ||
| 5116 | } | 5247 | } |
| 5117 | 5248 | ||
| 5118 | static void conn_info_refresh_complete(struct hci_dev *hdev, u8 hci_status) | 5249 | static void conn_info_refresh_complete(struct hci_dev *hdev, u8 hci_status, |
| 5250 | u16 opcode) | ||
| 5119 | { | 5251 | { |
| 5120 | struct hci_cp_read_rssi *cp; | 5252 | struct hci_cp_read_rssi *cp; |
| 5121 | struct pending_cmd *cmd; | 5253 | struct pending_cmd *cmd; |
| @@ -5286,11 +5418,12 @@ unlock: | |||
| 5286 | return err; | 5418 | return err; |
| 5287 | } | 5419 | } |
| 5288 | 5420 | ||
| 5289 | static void clock_info_cmd_complete(struct pending_cmd *cmd, u8 status) | 5421 | static int clock_info_cmd_complete(struct pending_cmd *cmd, u8 status) |
| 5290 | { | 5422 | { |
| 5291 | struct hci_conn *conn = cmd->user_data; | 5423 | struct hci_conn *conn = cmd->user_data; |
| 5292 | struct mgmt_rp_get_clock_info rp; | 5424 | struct mgmt_rp_get_clock_info rp; |
| 5293 | struct hci_dev *hdev; | 5425 | struct hci_dev *hdev; |
| 5426 | int err; | ||
| 5294 | 5427 | ||
| 5295 | memset(&rp, 0, sizeof(rp)); | 5428 | memset(&rp, 0, sizeof(rp)); |
| 5296 | memcpy(&rp.addr, &cmd->param, sizeof(rp.addr)); | 5429 | memcpy(&rp.addr, &cmd->param, sizeof(rp.addr)); |
| @@ -5310,15 +5443,18 @@ static void clock_info_cmd_complete(struct pending_cmd *cmd, u8 status) | |||
| 5310 | } | 5443 | } |
| 5311 | 5444 | ||
| 5312 | complete: | 5445 | complete: |
| 5313 | cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, &rp, sizeof(rp)); | 5446 | err = cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, &rp, |
| 5447 | sizeof(rp)); | ||
| 5314 | 5448 | ||
| 5315 | if (conn) { | 5449 | if (conn) { |
| 5316 | hci_conn_drop(conn); | 5450 | hci_conn_drop(conn); |
| 5317 | hci_conn_put(conn); | 5451 | hci_conn_put(conn); |
| 5318 | } | 5452 | } |
| 5453 | |||
| 5454 | return err; | ||
| 5319 | } | 5455 | } |
| 5320 | 5456 | ||
| 5321 | static void get_clock_info_complete(struct hci_dev *hdev, u8 status) | 5457 | static void get_clock_info_complete(struct hci_dev *hdev, u8 status, u16 opcode) |
| 5322 | { | 5458 | { |
| 5323 | struct hci_cp_read_clock *hci_cp; | 5459 | struct hci_cp_read_clock *hci_cp; |
| 5324 | struct pending_cmd *cmd; | 5460 | struct pending_cmd *cmd; |
| @@ -5425,6 +5561,65 @@ unlock: | |||
| 5425 | return err; | 5561 | return err; |
| 5426 | } | 5562 | } |
| 5427 | 5563 | ||
| 5564 | static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type) | ||
| 5565 | { | ||
| 5566 | struct hci_conn *conn; | ||
| 5567 | |||
| 5568 | conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, addr); | ||
| 5569 | if (!conn) | ||
| 5570 | return false; | ||
| 5571 | |||
| 5572 | if (conn->dst_type != type) | ||
| 5573 | return false; | ||
| 5574 | |||
| 5575 | if (conn->state != BT_CONNECTED) | ||
| 5576 | return false; | ||
| 5577 | |||
| 5578 | return true; | ||
| 5579 | } | ||
| 5580 | |||
| 5581 | /* This function requires the caller holds hdev->lock */ | ||
| 5582 | static int hci_conn_params_set(struct hci_request *req, bdaddr_t *addr, | ||
| 5583 | u8 addr_type, u8 auto_connect) | ||
| 5584 | { | ||
| 5585 | struct hci_dev *hdev = req->hdev; | ||
| 5586 | struct hci_conn_params *params; | ||
| 5587 | |||
| 5588 | params = hci_conn_params_add(hdev, addr, addr_type); | ||
| 5589 | if (!params) | ||
| 5590 | return -EIO; | ||
| 5591 | |||
| 5592 | if (params->auto_connect == auto_connect) | ||
| 5593 | return 0; | ||
| 5594 | |||
| 5595 | list_del_init(¶ms->action); | ||
| 5596 | |||
| 5597 | switch (auto_connect) { | ||
| 5598 | case HCI_AUTO_CONN_DISABLED: | ||
| 5599 | case HCI_AUTO_CONN_LINK_LOSS: | ||
| 5600 | __hci_update_background_scan(req); | ||
| 5601 | break; | ||
| 5602 | case HCI_AUTO_CONN_REPORT: | ||
| 5603 | list_add(¶ms->action, &hdev->pend_le_reports); | ||
| 5604 | __hci_update_background_scan(req); | ||
| 5605 | break; | ||
| 5606 | case HCI_AUTO_CONN_DIRECT: | ||
| 5607 | case HCI_AUTO_CONN_ALWAYS: | ||
| 5608 | if (!is_connected(hdev, addr, addr_type)) { | ||
| 5609 | list_add(¶ms->action, &hdev->pend_le_conns); | ||
| 5610 | __hci_update_background_scan(req); | ||
| 5611 | } | ||
| 5612 | break; | ||
| 5613 | } | ||
| 5614 | |||
| 5615 | params->auto_connect = auto_connect; | ||
| 5616 | |||
| 5617 | BT_DBG("addr %pMR (type %u) auto_connect %u", addr, addr_type, | ||
| 5618 | auto_connect); | ||
| 5619 | |||
| 5620 | return 0; | ||
| 5621 | } | ||
| 5622 | |||
| 5428 | static void device_added(struct sock *sk, struct hci_dev *hdev, | 5623 | static void device_added(struct sock *sk, struct hci_dev *hdev, |
| 5429 | bdaddr_t *bdaddr, u8 type, u8 action) | 5624 | bdaddr_t *bdaddr, u8 type, u8 action) |
| 5430 | { | 5625 | { |
| @@ -5437,10 +5632,31 @@ static void device_added(struct sock *sk, struct hci_dev *hdev, | |||
| 5437 | mgmt_event(MGMT_EV_DEVICE_ADDED, hdev, &ev, sizeof(ev), sk); | 5632 | mgmt_event(MGMT_EV_DEVICE_ADDED, hdev, &ev, sizeof(ev), sk); |
| 5438 | } | 5633 | } |
| 5439 | 5634 | ||
| 5635 | static void add_device_complete(struct hci_dev *hdev, u8 status, u16 opcode) | ||
| 5636 | { | ||
| 5637 | struct pending_cmd *cmd; | ||
| 5638 | |||
| 5639 | BT_DBG("status 0x%02x", status); | ||
| 5640 | |||
| 5641 | hci_dev_lock(hdev); | ||
| 5642 | |||
| 5643 | cmd = mgmt_pending_find(MGMT_OP_ADD_DEVICE, hdev); | ||
| 5644 | if (!cmd) | ||
| 5645 | goto unlock; | ||
| 5646 | |||
| 5647 | cmd->cmd_complete(cmd, mgmt_status(status)); | ||
| 5648 | mgmt_pending_remove(cmd); | ||
| 5649 | |||
| 5650 | unlock: | ||
| 5651 | hci_dev_unlock(hdev); | ||
| 5652 | } | ||
| 5653 | |||
| 5440 | static int add_device(struct sock *sk, struct hci_dev *hdev, | 5654 | static int add_device(struct sock *sk, struct hci_dev *hdev, |
| 5441 | void *data, u16 len) | 5655 | void *data, u16 len) |
| 5442 | { | 5656 | { |
| 5443 | struct mgmt_cp_add_device *cp = data; | 5657 | struct mgmt_cp_add_device *cp = data; |
| 5658 | struct pending_cmd *cmd; | ||
| 5659 | struct hci_request req; | ||
| 5444 | u8 auto_conn, addr_type; | 5660 | u8 auto_conn, addr_type; |
| 5445 | int err; | 5661 | int err; |
| 5446 | 5662 | ||
| @@ -5457,14 +5673,24 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, | |||
| 5457 | MGMT_STATUS_INVALID_PARAMS, | 5673 | MGMT_STATUS_INVALID_PARAMS, |
| 5458 | &cp->addr, sizeof(cp->addr)); | 5674 | &cp->addr, sizeof(cp->addr)); |
| 5459 | 5675 | ||
| 5676 | hci_req_init(&req, hdev); | ||
| 5677 | |||
| 5460 | hci_dev_lock(hdev); | 5678 | hci_dev_lock(hdev); |
| 5461 | 5679 | ||
| 5680 | cmd = mgmt_pending_add(sk, MGMT_OP_ADD_DEVICE, hdev, data, len); | ||
| 5681 | if (!cmd) { | ||
| 5682 | err = -ENOMEM; | ||
| 5683 | goto unlock; | ||
| 5684 | } | ||
| 5685 | |||
| 5686 | cmd->cmd_complete = addr_cmd_complete; | ||
| 5687 | |||
| 5462 | if (cp->addr.type == BDADDR_BREDR) { | 5688 | if (cp->addr.type == BDADDR_BREDR) { |
| 5463 | /* Only incoming connections action is supported for now */ | 5689 | /* Only incoming connections action is supported for now */ |
| 5464 | if (cp->action != 0x01) { | 5690 | if (cp->action != 0x01) { |
| 5465 | err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE, | 5691 | err = cmd->cmd_complete(cmd, |
| 5466 | MGMT_STATUS_INVALID_PARAMS, | 5692 | MGMT_STATUS_INVALID_PARAMS); |
| 5467 | &cp->addr, sizeof(cp->addr)); | 5693 | mgmt_pending_remove(cmd); |
| 5468 | goto unlock; | 5694 | goto unlock; |
| 5469 | } | 5695 | } |
| 5470 | 5696 | ||
| @@ -5473,7 +5699,7 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, | |||
| 5473 | if (err) | 5699 | if (err) |
| 5474 | goto unlock; | 5700 | goto unlock; |
| 5475 | 5701 | ||
| 5476 | hci_update_page_scan(hdev, NULL); | 5702 | __hci_update_page_scan(&req); |
| 5477 | 5703 | ||
| 5478 | goto added; | 5704 | goto added; |
| 5479 | } | 5705 | } |
| @@ -5493,19 +5719,25 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, | |||
| 5493 | /* If the connection parameters don't exist for this device, | 5719 | /* If the connection parameters don't exist for this device, |
| 5494 | * they will be created and configured with defaults. | 5720 | * they will be created and configured with defaults. |
| 5495 | */ | 5721 | */ |
| 5496 | if (hci_conn_params_set(hdev, &cp->addr.bdaddr, addr_type, | 5722 | if (hci_conn_params_set(&req, &cp->addr.bdaddr, addr_type, |
| 5497 | auto_conn) < 0) { | 5723 | auto_conn) < 0) { |
| 5498 | err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE, | 5724 | err = cmd->cmd_complete(cmd, MGMT_STATUS_FAILED); |
| 5499 | MGMT_STATUS_FAILED, | 5725 | mgmt_pending_remove(cmd); |
| 5500 | &cp->addr, sizeof(cp->addr)); | ||
| 5501 | goto unlock; | 5726 | goto unlock; |
| 5502 | } | 5727 | } |
| 5503 | 5728 | ||
| 5504 | added: | 5729 | added: |
| 5505 | device_added(sk, hdev, &cp->addr.bdaddr, cp->addr.type, cp->action); | 5730 | device_added(sk, hdev, &cp->addr.bdaddr, cp->addr.type, cp->action); |
| 5506 | 5731 | ||
| 5507 | err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE, | 5732 | err = hci_req_run(&req, add_device_complete); |
| 5508 | MGMT_STATUS_SUCCESS, &cp->addr, sizeof(cp->addr)); | 5733 | if (err < 0) { |
| 5734 | /* ENODATA means no HCI commands were needed (e.g. if | ||
| 5735 | * the adapter is powered off). | ||
| 5736 | */ | ||
| 5737 | if (err == -ENODATA) | ||
| 5738 | err = cmd->cmd_complete(cmd, MGMT_STATUS_SUCCESS); | ||
| 5739 | mgmt_pending_remove(cmd); | ||
| 5740 | } | ||
| 5509 | 5741 | ||
| 5510 | unlock: | 5742 | unlock: |
| 5511 | hci_dev_unlock(hdev); | 5743 | hci_dev_unlock(hdev); |
| @@ -5523,24 +5755,55 @@ static void device_removed(struct sock *sk, struct hci_dev *hdev, | |||
| 5523 | mgmt_event(MGMT_EV_DEVICE_REMOVED, hdev, &ev, sizeof(ev), sk); | 5755 | mgmt_event(MGMT_EV_DEVICE_REMOVED, hdev, &ev, sizeof(ev), sk); |
| 5524 | } | 5756 | } |
| 5525 | 5757 | ||
| 5758 | static void remove_device_complete(struct hci_dev *hdev, u8 status, u16 opcode) | ||
| 5759 | { | ||
| 5760 | struct pending_cmd *cmd; | ||
| 5761 | |||
| 5762 | BT_DBG("status 0x%02x", status); | ||
| 5763 | |||
| 5764 | hci_dev_lock(hdev); | ||
| 5765 | |||
| 5766 | cmd = mgmt_pending_find(MGMT_OP_REMOVE_DEVICE, hdev); | ||
| 5767 | if (!cmd) | ||
| 5768 | goto unlock; | ||
| 5769 | |||
| 5770 | cmd->cmd_complete(cmd, mgmt_status(status)); | ||
| 5771 | mgmt_pending_remove(cmd); | ||
| 5772 | |||
| 5773 | unlock: | ||
| 5774 | hci_dev_unlock(hdev); | ||
| 5775 | } | ||
| 5776 | |||
| 5526 | static int remove_device(struct sock *sk, struct hci_dev *hdev, | 5777 | static int remove_device(struct sock *sk, struct hci_dev *hdev, |
| 5527 | void *data, u16 len) | 5778 | void *data, u16 len) |
| 5528 | { | 5779 | { |
| 5529 | struct mgmt_cp_remove_device *cp = data; | 5780 | struct mgmt_cp_remove_device *cp = data; |
| 5781 | struct pending_cmd *cmd; | ||
| 5782 | struct hci_request req; | ||
| 5530 | int err; | 5783 | int err; |
| 5531 | 5784 | ||
| 5532 | BT_DBG("%s", hdev->name); | 5785 | BT_DBG("%s", hdev->name); |
| 5533 | 5786 | ||
| 5787 | hci_req_init(&req, hdev); | ||
| 5788 | |||
| 5534 | hci_dev_lock(hdev); | 5789 | hci_dev_lock(hdev); |
| 5535 | 5790 | ||
| 5791 | cmd = mgmt_pending_add(sk, MGMT_OP_REMOVE_DEVICE, hdev, data, len); | ||
| 5792 | if (!cmd) { | ||
| 5793 | err = -ENOMEM; | ||
| 5794 | goto unlock; | ||
| 5795 | } | ||
| 5796 | |||
| 5797 | cmd->cmd_complete = addr_cmd_complete; | ||
| 5798 | |||
| 5536 | if (bacmp(&cp->addr.bdaddr, BDADDR_ANY)) { | 5799 | if (bacmp(&cp->addr.bdaddr, BDADDR_ANY)) { |
| 5537 | struct hci_conn_params *params; | 5800 | struct hci_conn_params *params; |
| 5538 | u8 addr_type; | 5801 | u8 addr_type; |
| 5539 | 5802 | ||
| 5540 | if (!bdaddr_type_is_valid(cp->addr.type)) { | 5803 | if (!bdaddr_type_is_valid(cp->addr.type)) { |
| 5541 | err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_DEVICE, | 5804 | err = cmd->cmd_complete(cmd, |
| 5542 | MGMT_STATUS_INVALID_PARAMS, | 5805 | MGMT_STATUS_INVALID_PARAMS); |
| 5543 | &cp->addr, sizeof(cp->addr)); | 5806 | mgmt_pending_remove(cmd); |
| 5544 | goto unlock; | 5807 | goto unlock; |
| 5545 | } | 5808 | } |
| 5546 | 5809 | ||
| @@ -5549,14 +5812,13 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev, | |||
| 5549 | &cp->addr.bdaddr, | 5812 | &cp->addr.bdaddr, |
| 5550 | cp->addr.type); | 5813 | cp->addr.type); |
| 5551 | if (err) { | 5814 | if (err) { |
| 5552 | err = cmd_complete(sk, hdev->id, | 5815 | err = cmd->cmd_complete(cmd, |
| 5553 | MGMT_OP_REMOVE_DEVICE, | 5816 | MGMT_STATUS_INVALID_PARAMS); |
| 5554 | MGMT_STATUS_INVALID_PARAMS, | 5817 | mgmt_pending_remove(cmd); |
| 5555 | &cp->addr, sizeof(cp->addr)); | ||
| 5556 | goto unlock; | 5818 | goto unlock; |
| 5557 | } | 5819 | } |
| 5558 | 5820 | ||
| 5559 | hci_update_page_scan(hdev, NULL); | 5821 | __hci_update_page_scan(&req); |
| 5560 | 5822 | ||
| 5561 | device_removed(sk, hdev, &cp->addr.bdaddr, | 5823 | device_removed(sk, hdev, &cp->addr.bdaddr, |
| 5562 | cp->addr.type); | 5824 | cp->addr.type); |
| @@ -5571,23 +5833,23 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev, | |||
| 5571 | params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr, | 5833 | params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr, |
| 5572 | addr_type); | 5834 | addr_type); |
| 5573 | if (!params) { | 5835 | if (!params) { |
| 5574 | err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_DEVICE, | 5836 | err = cmd->cmd_complete(cmd, |
| 5575 | MGMT_STATUS_INVALID_PARAMS, | 5837 | MGMT_STATUS_INVALID_PARAMS); |
| 5576 | &cp->addr, sizeof(cp->addr)); | 5838 | mgmt_pending_remove(cmd); |
| 5577 | goto unlock; | 5839 | goto unlock; |
| 5578 | } | 5840 | } |
| 5579 | 5841 | ||
| 5580 | if (params->auto_connect == HCI_AUTO_CONN_DISABLED) { | 5842 | if (params->auto_connect == HCI_AUTO_CONN_DISABLED) { |
| 5581 | err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_DEVICE, | 5843 | err = cmd->cmd_complete(cmd, |
| 5582 | MGMT_STATUS_INVALID_PARAMS, | 5844 | MGMT_STATUS_INVALID_PARAMS); |
| 5583 | &cp->addr, sizeof(cp->addr)); | 5845 | mgmt_pending_remove(cmd); |
| 5584 | goto unlock; | 5846 | goto unlock; |
| 5585 | } | 5847 | } |
| 5586 | 5848 | ||
| 5587 | list_del(¶ms->action); | 5849 | list_del(¶ms->action); |
| 5588 | list_del(¶ms->list); | 5850 | list_del(¶ms->list); |
| 5589 | kfree(params); | 5851 | kfree(params); |
| 5590 | hci_update_background_scan(hdev); | 5852 | __hci_update_background_scan(&req); |
| 5591 | 5853 | ||
| 5592 | device_removed(sk, hdev, &cp->addr.bdaddr, cp->addr.type); | 5854 | device_removed(sk, hdev, &cp->addr.bdaddr, cp->addr.type); |
| 5593 | } else { | 5855 | } else { |
| @@ -5595,9 +5857,9 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev, | |||
| 5595 | struct bdaddr_list *b, *btmp; | 5857 | struct bdaddr_list *b, *btmp; |
| 5596 | 5858 | ||
| 5597 | if (cp->addr.type) { | 5859 | if (cp->addr.type) { |
| 5598 | err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_DEVICE, | 5860 | err = cmd->cmd_complete(cmd, |
| 5599 | MGMT_STATUS_INVALID_PARAMS, | 5861 | MGMT_STATUS_INVALID_PARAMS); |
| 5600 | &cp->addr, sizeof(cp->addr)); | 5862 | mgmt_pending_remove(cmd); |
| 5601 | goto unlock; | 5863 | goto unlock; |
| 5602 | } | 5864 | } |
| 5603 | 5865 | ||
| @@ -5607,7 +5869,7 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev, | |||
| 5607 | kfree(b); | 5869 | kfree(b); |
| 5608 | } | 5870 | } |
| 5609 | 5871 | ||
| 5610 | hci_update_page_scan(hdev, NULL); | 5872 | __hci_update_page_scan(&req); |
| 5611 | 5873 | ||
| 5612 | list_for_each_entry_safe(p, tmp, &hdev->le_conn_params, list) { | 5874 | list_for_each_entry_safe(p, tmp, &hdev->le_conn_params, list) { |
| 5613 | if (p->auto_connect == HCI_AUTO_CONN_DISABLED) | 5875 | if (p->auto_connect == HCI_AUTO_CONN_DISABLED) |
| @@ -5620,12 +5882,19 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev, | |||
| 5620 | 5882 | ||
| 5621 | BT_DBG("All LE connection parameters were removed"); | 5883 | BT_DBG("All LE connection parameters were removed"); |
| 5622 | 5884 | ||
| 5623 | hci_update_background_scan(hdev); | 5885 | __hci_update_background_scan(&req); |
| 5624 | } | 5886 | } |
| 5625 | 5887 | ||
| 5626 | complete: | 5888 | complete: |
| 5627 | err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_DEVICE, | 5889 | err = hci_req_run(&req, remove_device_complete); |
| 5628 | MGMT_STATUS_SUCCESS, &cp->addr, sizeof(cp->addr)); | 5890 | if (err < 0) { |
| 5891 | /* ENODATA means no HCI commands were needed (e.g. if | ||
| 5892 | * the adapter is powered off). | ||
| 5893 | */ | ||
| 5894 | if (err == -ENODATA) | ||
| 5895 | err = cmd->cmd_complete(cmd, MGMT_STATUS_SUCCESS); | ||
| 5896 | mgmt_pending_remove(cmd); | ||
| 5897 | } | ||
| 5629 | 5898 | ||
| 5630 | unlock: | 5899 | unlock: |
| 5631 | hci_dev_unlock(hdev); | 5900 | hci_dev_unlock(hdev); |
| @@ -6037,8 +6306,9 @@ void mgmt_index_removed(struct hci_dev *hdev) | |||
| 6037 | } | 6306 | } |
| 6038 | 6307 | ||
| 6039 | /* This function requires the caller holds hdev->lock */ | 6308 | /* This function requires the caller holds hdev->lock */ |
| 6040 | static void restart_le_actions(struct hci_dev *hdev) | 6309 | static void restart_le_actions(struct hci_request *req) |
| 6041 | { | 6310 | { |
| 6311 | struct hci_dev *hdev = req->hdev; | ||
| 6042 | struct hci_conn_params *p; | 6312 | struct hci_conn_params *p; |
| 6043 | 6313 | ||
| 6044 | list_for_each_entry(p, &hdev->le_conn_params, list) { | 6314 | list_for_each_entry(p, &hdev->le_conn_params, list) { |
| @@ -6060,18 +6330,25 @@ static void restart_le_actions(struct hci_dev *hdev) | |||
| 6060 | } | 6330 | } |
| 6061 | } | 6331 | } |
| 6062 | 6332 | ||
| 6063 | hci_update_background_scan(hdev); | 6333 | __hci_update_background_scan(req); |
| 6064 | } | 6334 | } |
| 6065 | 6335 | ||
| 6066 | static void powered_complete(struct hci_dev *hdev, u8 status) | 6336 | static void powered_complete(struct hci_dev *hdev, u8 status, u16 opcode) |
| 6067 | { | 6337 | { |
| 6068 | struct cmd_lookup match = { NULL, hdev }; | 6338 | struct cmd_lookup match = { NULL, hdev }; |
| 6069 | 6339 | ||
| 6070 | BT_DBG("status 0x%02x", status); | 6340 | BT_DBG("status 0x%02x", status); |
| 6071 | 6341 | ||
| 6072 | hci_dev_lock(hdev); | 6342 | if (!status) { |
| 6343 | /* Register the available SMP channels (BR/EDR and LE) only | ||
| 6344 | * when successfully powering on the controller. This late | ||
| 6345 | * registration is required so that LE SMP can clearly | ||
| 6346 | * decide if the public address or static address is used. | ||
| 6347 | */ | ||
| 6348 | smp_register(hdev); | ||
| 6349 | } | ||
| 6073 | 6350 | ||
| 6074 | restart_le_actions(hdev); | 6351 | hci_dev_lock(hdev); |
| 6075 | 6352 | ||
| 6076 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); | 6353 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); |
| 6077 | 6354 | ||
| @@ -6092,14 +6369,16 @@ static int powered_update_hci(struct hci_dev *hdev) | |||
| 6092 | 6369 | ||
| 6093 | if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && | 6370 | if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && |
| 6094 | !lmp_host_ssp_capable(hdev)) { | 6371 | !lmp_host_ssp_capable(hdev)) { |
| 6095 | u8 ssp = 1; | 6372 | u8 mode = 0x01; |
| 6096 | 6373 | ||
| 6097 | hci_req_add(&req, HCI_OP_WRITE_SSP_MODE, 1, &ssp); | 6374 | hci_req_add(&req, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode); |
| 6098 | } | 6375 | |
| 6376 | if (bredr_sc_enabled(hdev) && !lmp_host_sc_capable(hdev)) { | ||
| 6377 | u8 support = 0x01; | ||
| 6099 | 6378 | ||
| 6100 | if (bredr_sc_enabled(hdev) && !lmp_host_sc_capable(hdev)) { | 6379 | hci_req_add(&req, HCI_OP_WRITE_SC_SUPPORT, |
| 6101 | u8 sc = 0x01; | 6380 | sizeof(support), &support); |
| 6102 | hci_req_add(&req, HCI_OP_WRITE_SC_SUPPORT, sizeof(sc), &sc); | 6381 | } |
| 6103 | } | 6382 | } |
| 6104 | 6383 | ||
| 6105 | if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags) && | 6384 | if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags) && |
| @@ -6130,6 +6409,8 @@ static int powered_update_hci(struct hci_dev *hdev) | |||
| 6130 | 6409 | ||
| 6131 | if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) | 6410 | if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) |
| 6132 | enable_advertising(&req); | 6411 | enable_advertising(&req); |
| 6412 | |||
| 6413 | restart_le_actions(&req); | ||
| 6133 | } | 6414 | } |
| 6134 | 6415 | ||
| 6135 | link_sec = test_bit(HCI_LINK_SECURITY, &hdev->dev_flags); | 6416 | link_sec = test_bit(HCI_LINK_SECURITY, &hdev->dev_flags); |
| @@ -6139,7 +6420,7 @@ static int powered_update_hci(struct hci_dev *hdev) | |||
| 6139 | 6420 | ||
| 6140 | if (lmp_bredr_capable(hdev)) { | 6421 | if (lmp_bredr_capable(hdev)) { |
| 6141 | write_fast_connectable(&req, false); | 6422 | write_fast_connectable(&req, false); |
| 6142 | hci_update_page_scan(hdev, &req); | 6423 | __hci_update_page_scan(&req); |
| 6143 | update_class(&req); | 6424 | update_class(&req); |
| 6144 | update_name(&req); | 6425 | update_name(&req); |
| 6145 | update_eir(&req); | 6426 | update_eir(&req); |
| @@ -6817,43 +7098,6 @@ void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status) | |||
| 6817 | hci_req_run(&req, NULL); | 7098 | hci_req_run(&req, NULL); |
| 6818 | } | 7099 | } |
| 6819 | 7100 | ||
| 6820 | void mgmt_sc_enable_complete(struct hci_dev *hdev, u8 enable, u8 status) | ||
| 6821 | { | ||
| 6822 | struct cmd_lookup match = { NULL, hdev }; | ||
| 6823 | bool changed = false; | ||
| 6824 | |||
| 6825 | if (status) { | ||
| 6826 | u8 mgmt_err = mgmt_status(status); | ||
| 6827 | |||
| 6828 | if (enable) { | ||
| 6829 | if (test_and_clear_bit(HCI_SC_ENABLED, | ||
| 6830 | &hdev->dev_flags)) | ||
| 6831 | new_settings(hdev, NULL); | ||
| 6832 | clear_bit(HCI_SC_ONLY, &hdev->dev_flags); | ||
| 6833 | } | ||
| 6834 | |||
| 6835 | mgmt_pending_foreach(MGMT_OP_SET_SECURE_CONN, hdev, | ||
| 6836 | cmd_status_rsp, &mgmt_err); | ||
| 6837 | return; | ||
| 6838 | } | ||
| 6839 | |||
| 6840 | if (enable) { | ||
| 6841 | changed = !test_and_set_bit(HCI_SC_ENABLED, &hdev->dev_flags); | ||
| 6842 | } else { | ||
| 6843 | changed = test_and_clear_bit(HCI_SC_ENABLED, &hdev->dev_flags); | ||
| 6844 | clear_bit(HCI_SC_ONLY, &hdev->dev_flags); | ||
| 6845 | } | ||
| 6846 | |||
| 6847 | mgmt_pending_foreach(MGMT_OP_SET_SECURE_CONN, hdev, | ||
| 6848 | settings_rsp, &match); | ||
| 6849 | |||
| 6850 | if (changed) | ||
| 6851 | new_settings(hdev, match.sk); | ||
| 6852 | |||
| 6853 | if (match.sk) | ||
| 6854 | sock_put(match.sk); | ||
| 6855 | } | ||
| 6856 | |||
| 6857 | static void sk_lookup(struct pending_cmd *cmd, void *data) | 7101 | static void sk_lookup(struct pending_cmd *cmd, void *data) |
| 6858 | { | 7102 | { |
| 6859 | struct cmd_lookup *match = data; | 7103 | struct cmd_lookup *match = data; |
| @@ -6924,28 +7168,21 @@ void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, | |||
| 6924 | cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, | 7168 | cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, |
| 6925 | mgmt_status(status)); | 7169 | mgmt_status(status)); |
| 6926 | } else { | 7170 | } else { |
| 6927 | if (bredr_sc_enabled(hdev) && hash256 && rand256) { | 7171 | struct mgmt_rp_read_local_oob_data rp; |
| 6928 | struct mgmt_rp_read_local_oob_ext_data rp; | 7172 | size_t rp_size = sizeof(rp); |
| 6929 | 7173 | ||
| 6930 | memcpy(rp.hash192, hash192, sizeof(rp.hash192)); | 7174 | memcpy(rp.hash192, hash192, sizeof(rp.hash192)); |
| 6931 | memcpy(rp.rand192, rand192, sizeof(rp.rand192)); | 7175 | memcpy(rp.rand192, rand192, sizeof(rp.rand192)); |
| 6932 | 7176 | ||
| 7177 | if (bredr_sc_enabled(hdev) && hash256 && rand256) { | ||
| 6933 | memcpy(rp.hash256, hash256, sizeof(rp.hash256)); | 7178 | memcpy(rp.hash256, hash256, sizeof(rp.hash256)); |
| 6934 | memcpy(rp.rand256, rand256, sizeof(rp.rand256)); | 7179 | memcpy(rp.rand256, rand256, sizeof(rp.rand256)); |
| 6935 | |||
| 6936 | cmd_complete(cmd->sk, hdev->id, | ||
| 6937 | MGMT_OP_READ_LOCAL_OOB_DATA, 0, | ||
| 6938 | &rp, sizeof(rp)); | ||
| 6939 | } else { | 7180 | } else { |
| 6940 | struct mgmt_rp_read_local_oob_data rp; | 7181 | rp_size -= sizeof(rp.hash256) + sizeof(rp.rand256); |
| 6941 | |||
| 6942 | memcpy(rp.hash, hash192, sizeof(rp.hash)); | ||
| 6943 | memcpy(rp.rand, rand192, sizeof(rp.rand)); | ||
| 6944 | |||
| 6945 | cmd_complete(cmd->sk, hdev->id, | ||
| 6946 | MGMT_OP_READ_LOCAL_OOB_DATA, 0, | ||
| 6947 | &rp, sizeof(rp)); | ||
| 6948 | } | 7182 | } |
| 7183 | |||
| 7184 | cmd_complete(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, 0, | ||
| 7185 | &rp, rp_size); | ||
| 6949 | } | 7186 | } |
| 6950 | 7187 | ||
| 6951 | mgmt_pending_remove(cmd); | 7188 | mgmt_pending_remove(cmd); |
| @@ -7018,6 +7255,21 @@ static bool eir_has_uuids(u8 *eir, u16 eir_len, u16 uuid_count, u8 (*uuids)[16]) | |||
| 7018 | return false; | 7255 | return false; |
| 7019 | } | 7256 | } |
| 7020 | 7257 | ||
| 7258 | static void restart_le_scan(struct hci_dev *hdev) | ||
| 7259 | { | ||
| 7260 | /* If controller is not scanning we are done. */ | ||
| 7261 | if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags)) | ||
| 7262 | return; | ||
| 7263 | |||
| 7264 | if (time_after(jiffies + DISCOV_LE_RESTART_DELAY, | ||
| 7265 | hdev->discovery.scan_start + | ||
| 7266 | hdev->discovery.scan_duration)) | ||
| 7267 | return; | ||
| 7268 | |||
| 7269 | queue_delayed_work(hdev->workqueue, &hdev->le_scan_restart, | ||
| 7270 | DISCOV_LE_RESTART_DELAY); | ||
| 7271 | } | ||
| 7272 | |||
| 7021 | void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | 7273 | void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, |
| 7022 | u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, | 7274 | u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, |
| 7023 | u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len) | 7275 | u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len) |
| @@ -7040,14 +7292,18 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
| 7040 | 7292 | ||
| 7041 | /* When using service discovery with a RSSI threshold, then check | 7293 | /* When using service discovery with a RSSI threshold, then check |
| 7042 | * if such a RSSI threshold is specified. If a RSSI threshold has | 7294 | * if such a RSSI threshold is specified. If a RSSI threshold has |
| 7043 | * been specified, then all results with a RSSI smaller than the | 7295 | * been specified, and HCI_QUIRK_STRICT_DUPLICATE_FILTER is not set, |
| 7044 | * RSSI threshold will be dropped. | 7296 | * then all results with a RSSI smaller than the RSSI threshold will be |
| 7297 | * dropped. If the quirk is set, let it through for further processing, | ||
| 7298 | * as we might need to restart the scan. | ||
| 7045 | * | 7299 | * |
| 7046 | * For BR/EDR devices (pre 1.2) providing no RSSI during inquiry, | 7300 | * For BR/EDR devices (pre 1.2) providing no RSSI during inquiry, |
| 7047 | * the results are also dropped. | 7301 | * the results are also dropped. |
| 7048 | */ | 7302 | */ |
| 7049 | if (hdev->discovery.rssi != HCI_RSSI_INVALID && | 7303 | if (hdev->discovery.rssi != HCI_RSSI_INVALID && |
| 7050 | (rssi < hdev->discovery.rssi || rssi == HCI_RSSI_INVALID)) | 7304 | (rssi == HCI_RSSI_INVALID || |
| 7305 | (rssi < hdev->discovery.rssi && | ||
| 7306 | !test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks)))) | ||
| 7051 | return; | 7307 | return; |
| 7052 | 7308 | ||
| 7053 | /* Make sure that the buffer is big enough. The 5 extra bytes | 7309 | /* Make sure that the buffer is big enough. The 5 extra bytes |
| @@ -7066,7 +7322,8 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
| 7066 | * However when using service discovery, the value 127 will be | 7322 | * However when using service discovery, the value 127 will be |
| 7067 | * returned when the RSSI is not available. | 7323 | * returned when the RSSI is not available. |
| 7068 | */ | 7324 | */ |
| 7069 | if (rssi == HCI_RSSI_INVALID && !hdev->discovery.report_invalid_rssi) | 7325 | if (rssi == HCI_RSSI_INVALID && !hdev->discovery.report_invalid_rssi && |
| 7326 | link_type == ACL_LINK) | ||
| 7070 | rssi = 0; | 7327 | rssi = 0; |
| 7071 | 7328 | ||
| 7072 | bacpy(&ev->addr.bdaddr, bdaddr); | 7329 | bacpy(&ev->addr.bdaddr, bdaddr); |
| @@ -7081,12 +7338,20 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
| 7081 | * kept and checking possible scan response data | 7338 | * kept and checking possible scan response data |
| 7082 | * will be skipped. | 7339 | * will be skipped. |
| 7083 | */ | 7340 | */ |
| 7084 | if (hdev->discovery.uuid_count > 0) | 7341 | if (hdev->discovery.uuid_count > 0) { |
| 7085 | match = eir_has_uuids(eir, eir_len, | 7342 | match = eir_has_uuids(eir, eir_len, |
| 7086 | hdev->discovery.uuid_count, | 7343 | hdev->discovery.uuid_count, |
| 7087 | hdev->discovery.uuids); | 7344 | hdev->discovery.uuids); |
| 7088 | else | 7345 | /* If duplicate filtering does not report RSSI changes, |
| 7346 | * then restart scanning to ensure updated result with | ||
| 7347 | * updated RSSI values. | ||
| 7348 | */ | ||
| 7349 | if (match && test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, | ||
| 7350 | &hdev->quirks)) | ||
| 7351 | restart_le_scan(hdev); | ||
| 7352 | } else { | ||
| 7089 | match = true; | 7353 | match = true; |
| 7354 | } | ||
| 7090 | 7355 | ||
| 7091 | if (!match && !scan_rsp_len) | 7356 | if (!match && !scan_rsp_len) |
| 7092 | return; | 7357 | return; |
| @@ -7119,6 +7384,14 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
| 7119 | hdev->discovery.uuid_count, | 7384 | hdev->discovery.uuid_count, |
| 7120 | hdev->discovery.uuids)) | 7385 | hdev->discovery.uuids)) |
| 7121 | return; | 7386 | return; |
| 7387 | |||
| 7388 | /* If duplicate filtering does not report RSSI changes, | ||
| 7389 | * then restart scanning to ensure updated result with | ||
| 7390 | * updated RSSI values. | ||
| 7391 | */ | ||
| 7392 | if (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, | ||
| 7393 | &hdev->quirks)) | ||
| 7394 | restart_le_scan(hdev); | ||
| 7122 | } | 7395 | } |
| 7123 | 7396 | ||
| 7124 | /* Append scan response data to event */ | 7397 | /* Append scan response data to event */ |
| @@ -7132,6 +7405,14 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
| 7132 | return; | 7405 | return; |
| 7133 | } | 7406 | } |
| 7134 | 7407 | ||
| 7408 | /* Validate the reported RSSI value against the RSSI threshold once more | ||
| 7409 | * incase HCI_QUIRK_STRICT_DUPLICATE_FILTER forced a restart of LE | ||
| 7410 | * scanning. | ||
| 7411 | */ | ||
| 7412 | if (hdev->discovery.rssi != HCI_RSSI_INVALID && | ||
| 7413 | rssi < hdev->discovery.rssi) | ||
| 7414 | return; | ||
| 7415 | |||
| 7135 | ev->eir_len = cpu_to_le16(eir_len + scan_rsp_len); | 7416 | ev->eir_len = cpu_to_le16(eir_len + scan_rsp_len); |
| 7136 | ev_size = sizeof(*ev) + eir_len + scan_rsp_len; | 7417 | ev_size = sizeof(*ev) + eir_len + scan_rsp_len; |
| 7137 | 7418 | ||
| @@ -7174,7 +7455,7 @@ void mgmt_discovering(struct hci_dev *hdev, u8 discovering) | |||
| 7174 | mgmt_event(MGMT_EV_DISCOVERING, hdev, &ev, sizeof(ev), NULL); | 7455 | mgmt_event(MGMT_EV_DISCOVERING, hdev, &ev, sizeof(ev), NULL); |
| 7175 | } | 7456 | } |
| 7176 | 7457 | ||
| 7177 | static void adv_enable_complete(struct hci_dev *hdev, u8 status) | 7458 | static void adv_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode) |
| 7178 | { | 7459 | { |
| 7179 | BT_DBG("%s status %u", hdev->name, status); | 7460 | BT_DBG("%s status %u", hdev->name, status); |
| 7180 | } | 7461 | } |
