diff options
-rw-r--r-- | include/net/bluetooth/mgmt.h | 5 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 27 |
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 { | |||
412 | struct mgmt_ev_device_unblocked { | 412 | struct 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 | ||
417 | struct 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 | ||
1076 | static 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 | |||
1076 | static int unpair_device(struct sock *sk, u16 index, void *data, u16 len) | 1088 | static 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 | ||
2630 | static void unpair_device_rsp(struct pending_cmd *cmd, void *data) | 2644 | static 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 | ||