aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2012-02-09 10:21:16 -0500
committerJohan Hedberg <johan.hedberg@intel.com>2012-02-13 10:01:37 -0500
commitb1078ad0be344e7bec6e7991f33df17565d24e08 (patch)
tree959a51367996856bcb0be46a7712bde0b2225a8f /net/bluetooth/mgmt.c
parent82eb703efc2ad2ac52cada85a5119bb9dfcea942 (diff)
Bluetooth: Add Device Unpaired mgmt event
This patch add a new Device Unpaired mgmt event. This will be sent to all mgmt sockets except the one that requested unpairing (that socket will get a command complete instead). The event is also reserved for future SMP updates where a remote device will be able to request pairing revocation from us. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Acked-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r--net/bluetooth/mgmt.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 0cf0f4dc8213..a2c2e12516c6 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1073,6 +1073,18 @@ static int load_link_keys(struct sock *sk, u16 index, void *data, u16 len)
1073 return 0; 1073 return 0;
1074} 1074}
1075 1075
1076static int device_unpaired(struct hci_dev *hdev, bdaddr_t *bdaddr,
1077 u8 addr_type, struct sock *skip_sk)
1078{
1079 struct mgmt_ev_device_unpaired ev;
1080
1081 bacpy(&ev.addr.bdaddr, bdaddr);
1082 ev.addr.type = addr_type;
1083
1084 return mgmt_event(MGMT_EV_DEVICE_UNPAIRED, hdev, &ev, sizeof(ev),
1085 skip_sk);
1086}
1087
1076static int unpair_device(struct sock *sk, u16 index, void *data, u16 len) 1088static int unpair_device(struct sock *sk, u16 index, void *data, u16 len)
1077{ 1089{
1078 struct hci_dev *hdev; 1090 struct hci_dev *hdev;
@@ -1111,6 +1123,7 @@ static int unpair_device(struct sock *sk, u16 index, void *data, u16 len)
1111 if (!test_bit(HCI_UP, &hdev->flags) || !cp->disconnect) { 1123 if (!test_bit(HCI_UP, &hdev->flags) || !cp->disconnect) {
1112 err = cmd_complete(sk, index, MGMT_OP_UNPAIR_DEVICE, &rp, 1124 err = cmd_complete(sk, index, MGMT_OP_UNPAIR_DEVICE, &rp,
1113 sizeof(rp)); 1125 sizeof(rp));
1126 device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, sk);
1114 goto unlock; 1127 goto unlock;
1115 } 1128 }
1116 1129
@@ -1124,6 +1137,7 @@ static int unpair_device(struct sock *sk, u16 index, void *data, u16 len)
1124 if (!conn) { 1137 if (!conn) {
1125 err = cmd_complete(sk, index, MGMT_OP_UNPAIR_DEVICE, &rp, 1138 err = cmd_complete(sk, index, MGMT_OP_UNPAIR_DEVICE, &rp,
1126 sizeof(rp)); 1139 sizeof(rp));
1140 device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, sk);
1127 goto unlock; 1141 goto unlock;
1128 } 1142 }
1129 1143
@@ -2629,18 +2643,17 @@ static void disconnect_rsp(struct pending_cmd *cmd, void *data)
2629 2643
2630static void unpair_device_rsp(struct pending_cmd *cmd, void *data) 2644static void unpair_device_rsp(struct pending_cmd *cmd, void *data)
2631{ 2645{
2632 u8 *status = data; 2646 struct hci_dev *hdev = data;
2633 struct mgmt_cp_unpair_device *cp = cmd->param; 2647 struct mgmt_cp_unpair_device *cp = cmd->param;
2634 struct mgmt_rp_unpair_device rp; 2648 struct mgmt_rp_unpair_device rp;
2635 2649
2636 memset(&rp, 0, sizeof(rp)); 2650 memset(&rp, 0, sizeof(rp));
2637 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr); 2651 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
2638 rp.addr.type = cp->addr.type; 2652 rp.addr.type = cp->addr.type;
2639 if (status != NULL)
2640 rp.status = *status;
2641 2653
2642 cmd_complete(cmd->sk, cmd->index, MGMT_OP_UNPAIR_DEVICE, &rp, 2654 device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, cmd->sk);
2643 sizeof(rp)); 2655
2656 cmd_complete(cmd->sk, cmd->index, cmd->opcode, &rp, sizeof(rp));
2644 2657
2645 mgmt_pending_remove(cmd); 2658 mgmt_pending_remove(cmd);
2646} 2659}
@@ -2664,7 +2677,7 @@ int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
2664 sock_put(sk); 2677 sock_put(sk);
2665 2678
2666 mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp, 2679 mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp,
2667 NULL); 2680 hdev);
2668 2681
2669 return err; 2682 return err;
2670} 2683}
@@ -2689,6 +2702,8 @@ int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
2689 2702
2690 mgmt_pending_remove(cmd); 2703 mgmt_pending_remove(cmd);
2691 2704
2705 mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp,
2706 hdev);
2692 return err; 2707 return err;
2693} 2708}
2694 2709