diff options
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r-- | net/bluetooth/mgmt.c | 105 |
1 files changed, 65 insertions, 40 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 3048092b1264..bb0c53ac4c66 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -3783,10 +3783,70 @@ failed: | |||
3783 | return err; | 3783 | return err; |
3784 | } | 3784 | } |
3785 | 3785 | ||
3786 | static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status, | ||
3787 | u16 opcode, struct sk_buff *skb) | ||
3788 | { | ||
3789 | struct mgmt_rp_read_local_oob_data mgmt_rp; | ||
3790 | size_t rp_size = sizeof(mgmt_rp); | ||
3791 | struct mgmt_pending_cmd *cmd; | ||
3792 | |||
3793 | BT_DBG("%s status %u", hdev->name, status); | ||
3794 | |||
3795 | cmd = pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev); | ||
3796 | if (!cmd) | ||
3797 | return; | ||
3798 | |||
3799 | if (status || !skb) { | ||
3800 | mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, | ||
3801 | status ? mgmt_status(status) : MGMT_STATUS_FAILED); | ||
3802 | goto remove; | ||
3803 | } | ||
3804 | |||
3805 | memset(&mgmt_rp, 0, sizeof(mgmt_rp)); | ||
3806 | |||
3807 | if (opcode == HCI_OP_READ_LOCAL_OOB_DATA) { | ||
3808 | struct hci_rp_read_local_oob_data *rp = (void *) skb->data; | ||
3809 | |||
3810 | if (skb->len < sizeof(*rp)) { | ||
3811 | mgmt_cmd_status(cmd->sk, hdev->id, | ||
3812 | MGMT_OP_READ_LOCAL_OOB_DATA, | ||
3813 | MGMT_STATUS_FAILED); | ||
3814 | goto remove; | ||
3815 | } | ||
3816 | |||
3817 | memcpy(mgmt_rp.hash192, rp->hash, sizeof(rp->hash)); | ||
3818 | memcpy(mgmt_rp.rand192, rp->rand, sizeof(rp->rand)); | ||
3819 | |||
3820 | rp_size -= sizeof(mgmt_rp.hash256) + sizeof(mgmt_rp.rand256); | ||
3821 | } else { | ||
3822 | struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data; | ||
3823 | |||
3824 | if (skb->len < sizeof(*rp)) { | ||
3825 | mgmt_cmd_status(cmd->sk, hdev->id, | ||
3826 | MGMT_OP_READ_LOCAL_OOB_DATA, | ||
3827 | MGMT_STATUS_FAILED); | ||
3828 | goto remove; | ||
3829 | } | ||
3830 | |||
3831 | memcpy(mgmt_rp.hash192, rp->hash192, sizeof(rp->hash192)); | ||
3832 | memcpy(mgmt_rp.rand192, rp->rand192, sizeof(rp->rand192)); | ||
3833 | |||
3834 | memcpy(mgmt_rp.hash256, rp->hash256, sizeof(rp->hash256)); | ||
3835 | memcpy(mgmt_rp.rand256, rp->rand256, sizeof(rp->rand256)); | ||
3836 | } | ||
3837 | |||
3838 | mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, | ||
3839 | MGMT_STATUS_SUCCESS, &mgmt_rp, rp_size); | ||
3840 | |||
3841 | remove: | ||
3842 | mgmt_pending_remove(cmd); | ||
3843 | } | ||
3844 | |||
3786 | static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev, | 3845 | static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev, |
3787 | void *data, u16 data_len) | 3846 | void *data, u16 data_len) |
3788 | { | 3847 | { |
3789 | struct mgmt_pending_cmd *cmd; | 3848 | struct mgmt_pending_cmd *cmd; |
3849 | struct hci_request req; | ||
3790 | int err; | 3850 | int err; |
3791 | 3851 | ||
3792 | BT_DBG("%s", hdev->name); | 3852 | BT_DBG("%s", hdev->name); |
@@ -3817,12 +3877,14 @@ static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev, | |||
3817 | goto unlock; | 3877 | goto unlock; |
3818 | } | 3878 | } |
3819 | 3879 | ||
3880 | hci_req_init(&req, hdev); | ||
3881 | |||
3820 | if (bredr_sc_enabled(hdev)) | 3882 | if (bredr_sc_enabled(hdev)) |
3821 | err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_EXT_DATA, | 3883 | hci_req_add(&req, HCI_OP_READ_LOCAL_OOB_EXT_DATA, 0, NULL); |
3822 | 0, NULL); | ||
3823 | else | 3884 | else |
3824 | err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL); | 3885 | hci_req_add(&req, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL); |
3825 | 3886 | ||
3887 | err = hci_req_run_skb(&req, read_local_oob_data_complete); | ||
3826 | if (err < 0) | 3888 | if (err < 0) |
3827 | mgmt_pending_remove(cmd); | 3889 | mgmt_pending_remove(cmd); |
3828 | 3890 | ||
@@ -7920,43 +7982,6 @@ void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) | |||
7920 | cmd ? cmd->sk : NULL); | 7982 | cmd ? cmd->sk : NULL); |
7921 | } | 7983 | } |
7922 | 7984 | ||
7923 | void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, | ||
7924 | u8 *rand192, u8 *hash256, u8 *rand256, | ||
7925 | u8 status) | ||
7926 | { | ||
7927 | struct mgmt_pending_cmd *cmd; | ||
7928 | |||
7929 | BT_DBG("%s status %u", hdev->name, status); | ||
7930 | |||
7931 | cmd = pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev); | ||
7932 | if (!cmd) | ||
7933 | return; | ||
7934 | |||
7935 | if (status) { | ||
7936 | mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, | ||
7937 | mgmt_status(status)); | ||
7938 | } else { | ||
7939 | struct mgmt_rp_read_local_oob_data rp; | ||
7940 | size_t rp_size = sizeof(rp); | ||
7941 | |||
7942 | memcpy(rp.hash192, hash192, sizeof(rp.hash192)); | ||
7943 | memcpy(rp.rand192, rand192, sizeof(rp.rand192)); | ||
7944 | |||
7945 | if (bredr_sc_enabled(hdev) && hash256 && rand256) { | ||
7946 | memcpy(rp.hash256, hash256, sizeof(rp.hash256)); | ||
7947 | memcpy(rp.rand256, rand256, sizeof(rp.rand256)); | ||
7948 | } else { | ||
7949 | rp_size -= sizeof(rp.hash256) + sizeof(rp.rand256); | ||
7950 | } | ||
7951 | |||
7952 | mgmt_cmd_complete(cmd->sk, hdev->id, | ||
7953 | MGMT_OP_READ_LOCAL_OOB_DATA, 0, | ||
7954 | &rp, rp_size); | ||
7955 | } | ||
7956 | |||
7957 | mgmt_pending_remove(cmd); | ||
7958 | } | ||
7959 | |||
7960 | static inline bool has_uuid(u8 *uuid, u16 uuid_count, u8 (*uuids)[16]) | 7985 | static inline bool has_uuid(u8 *uuid, u16 uuid_count, u8 (*uuids)[16]) |
7961 | { | 7986 | { |
7962 | int i; | 7987 | int i; |