aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/mgmt.h5
-rw-r--r--net/bluetooth/mgmt.c27
2 files changed, 26 insertions, 6 deletions
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 17bbf8bf04ae..5b5edeed59e2 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -412,3 +412,8 @@ struct mgmt_ev_device_blocked {
412struct mgmt_ev_device_unblocked { 412struct mgmt_ev_device_unblocked {
413 struct mgmt_addr_info addr; 413 struct mgmt_addr_info addr;
414} __packed; 414} __packed;
415
416#define MGMT_EV_DEVICE_UNPAIRED 0x0016
417struct mgmt_ev_device_unpaired {
418 struct mgmt_addr_info addr;
419} __packed;
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