]> git.openfabrics.org - ~shefty/rdma-dev.git/commitdiff
Bluetooth: mgmt: Implement Cancel Pair Device command
authorJohan Hedberg <johan.hedberg@intel.com>
Thu, 2 Feb 2012 02:02:29 +0000 (04:02 +0200)
committerJohan Hedberg <johan.hedberg@intel.com>
Mon, 13 Feb 2012 15:01:32 +0000 (17:01 +0200)
This patch implements the Cancel Pair Device command for mgmt. It's used
by user space to cancel an ongoing pairing attempt which was triggered
by the Pair Device command.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
include/net/bluetooth/mgmt.h
net/bluetooth/mgmt.c

index 42eb48bb2c3bc5d78d3019c95ebceae0185a9e87..72975fd5398868e1b8c75ca7f6d355a72199e3f1 100644 (file)
@@ -39,6 +39,7 @@
 #define MGMT_STATUS_INVALID_PARAMS     0x0d
 #define MGMT_STATUS_DISCONNECTED       0x0e
 #define MGMT_STATUS_NOT_POWERED                0x0f
+#define MGMT_STATUS_CANCELLED          0x10
 
 struct mgmt_hdr {
        __le16 opcode;
index 89707996d35231c3e06c9610ea9c5219d9531e81..00ab083749eb569c70e2f45e5b691c90e9c72a19 100644 (file)
@@ -1594,6 +1594,54 @@ unlock:
        return err;
 }
 
+static int cancel_pair_device(struct sock *sk, u16 index,
+                                               unsigned char *data, u16 len)
+{
+       struct mgmt_addr_info *addr = (void *) data;
+       struct hci_dev *hdev;
+       struct pending_cmd *cmd;
+       struct hci_conn *conn;
+       int err;
+
+       BT_DBG("");
+
+       if (len != sizeof(*addr))
+               return cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE,
+                                               MGMT_STATUS_INVALID_PARAMS);
+
+       hdev = hci_dev_get(index);
+       if (!hdev)
+               return cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE,
+                                               MGMT_STATUS_INVALID_PARAMS);
+
+       hci_dev_lock(hdev);
+
+       cmd = mgmt_pending_find(MGMT_OP_PAIR_DEVICE, hdev);
+       if (!cmd) {
+               err = cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE,
+                                               MGMT_STATUS_INVALID_PARAMS);
+               goto unlock;
+       }
+
+       conn = cmd->user_data;
+
+       if (bacmp(&addr->bdaddr, &conn->dst) != 0) {
+               err = cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE,
+                                               MGMT_STATUS_INVALID_PARAMS);
+               goto unlock;
+       }
+
+       pairing_complete(cmd, MGMT_STATUS_CANCELLED);
+
+       err = cmd_complete(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE, addr,
+                                                               sizeof(*addr));
+unlock:
+       hci_dev_unlock(hdev);
+       hci_dev_put(hdev);
+
+       return err;
+}
+
 static int user_pairing_resp(struct sock *sk, u16 index, bdaddr_t *bdaddr,
                                        u16 mgmt_op, u16 hci_op, __le32 passkey)
 {
@@ -2271,6 +2319,9 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
        case MGMT_OP_PAIR_DEVICE:
                err = pair_device(sk, index, buf + sizeof(*hdr), len);
                break;
+       case MGMT_OP_CANCEL_PAIR_DEVICE:
+               err = cancel_pair_device(sk, index, buf + sizeof(*hdr), len);
+               break;
        case MGMT_OP_USER_CONFIRM_REPLY:
                err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len);
                break;