summaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r--net/bluetooth/mgmt.c105
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
3786static 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
3841remove:
3842 mgmt_pending_remove(cmd);
3843}
3844
3786static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev, 3845static 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
7923void 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
7960static inline bool has_uuid(u8 *uuid, u16 uuid_count, u8 (*uuids)[16]) 7985static inline bool has_uuid(u8 *uuid, u16 uuid_count, u8 (*uuids)[16])
7961{ 7986{
7962 int i; 7987 int i;