diff options
-rw-r--r-- | include/net/bluetooth/mgmt.h | 10 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 70 |
2 files changed, 80 insertions, 0 deletions
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 4899286ed4e4..45bea25d737f 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h | |||
@@ -199,6 +199,16 @@ struct mgmt_cp_remove_remote_oob_data { | |||
199 | 199 | ||
200 | #define MGMT_OP_STOP_DISCOVERY 0x001C | 200 | #define MGMT_OP_STOP_DISCOVERY 0x001C |
201 | 201 | ||
202 | #define MGMT_OP_BLOCK_DEVICE 0x001D | ||
203 | struct mgmt_cp_block_device { | ||
204 | bdaddr_t bdaddr; | ||
205 | } __packed; | ||
206 | |||
207 | #define MGMT_OP_UNBLOCK_DEVICE 0x001E | ||
208 | struct mgmt_cp_unblock_device { | ||
209 | bdaddr_t bdaddr; | ||
210 | } __packed; | ||
211 | |||
202 | #define MGMT_EV_CMD_COMPLETE 0x0001 | 212 | #define MGMT_EV_CMD_COMPLETE 0x0001 |
203 | struct mgmt_ev_cmd_complete { | 213 | struct mgmt_ev_cmd_complete { |
204 | __le16 opcode; | 214 | __le16 opcode; |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index d19208903be4..64c0418a6221 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -1666,6 +1666,70 @@ failed: | |||
1666 | return err; | 1666 | return err; |
1667 | } | 1667 | } |
1668 | 1668 | ||
1669 | static int block_device(struct sock *sk, u16 index, unsigned char *data, | ||
1670 | u16 len) | ||
1671 | { | ||
1672 | struct hci_dev *hdev; | ||
1673 | struct mgmt_cp_block_device *cp; | ||
1674 | int err; | ||
1675 | |||
1676 | BT_DBG("hci%u", index); | ||
1677 | |||
1678 | cp = (void *) data; | ||
1679 | |||
1680 | if (len != sizeof(*cp)) | ||
1681 | return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE, | ||
1682 | EINVAL); | ||
1683 | |||
1684 | hdev = hci_dev_get(index); | ||
1685 | if (!hdev) | ||
1686 | return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE, | ||
1687 | ENODEV); | ||
1688 | |||
1689 | err = hci_blacklist_add(hdev, &cp->bdaddr); | ||
1690 | |||
1691 | if (err < 0) | ||
1692 | err = cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE, -err); | ||
1693 | else | ||
1694 | err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE, | ||
1695 | NULL, 0); | ||
1696 | hci_dev_put(hdev); | ||
1697 | |||
1698 | return err; | ||
1699 | } | ||
1700 | |||
1701 | static int unblock_device(struct sock *sk, u16 index, unsigned char *data, | ||
1702 | u16 len) | ||
1703 | { | ||
1704 | struct hci_dev *hdev; | ||
1705 | struct mgmt_cp_unblock_device *cp; | ||
1706 | int err; | ||
1707 | |||
1708 | BT_DBG("hci%u", index); | ||
1709 | |||
1710 | cp = (void *) data; | ||
1711 | |||
1712 | if (len != sizeof(*cp)) | ||
1713 | return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE, | ||
1714 | EINVAL); | ||
1715 | |||
1716 | hdev = hci_dev_get(index); | ||
1717 | if (!hdev) | ||
1718 | return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE, | ||
1719 | ENODEV); | ||
1720 | |||
1721 | err = hci_blacklist_del(hdev, &cp->bdaddr); | ||
1722 | |||
1723 | if (err < 0) | ||
1724 | err = cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE, -err); | ||
1725 | else | ||
1726 | err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE, | ||
1727 | NULL, 0); | ||
1728 | hci_dev_put(hdev); | ||
1729 | |||
1730 | return err; | ||
1731 | } | ||
1732 | |||
1669 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | 1733 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) |
1670 | { | 1734 | { |
1671 | unsigned char *buf; | 1735 | unsigned char *buf; |
@@ -1780,6 +1844,12 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | |||
1780 | case MGMT_OP_STOP_DISCOVERY: | 1844 | case MGMT_OP_STOP_DISCOVERY: |
1781 | err = stop_discovery(sk, index); | 1845 | err = stop_discovery(sk, index); |
1782 | break; | 1846 | break; |
1847 | case MGMT_OP_BLOCK_DEVICE: | ||
1848 | err = block_device(sk, index, buf + sizeof(*hdr), len); | ||
1849 | break; | ||
1850 | case MGMT_OP_UNBLOCK_DEVICE: | ||
1851 | err = unblock_device(sk, index, buf + sizeof(*hdr), len); | ||
1852 | break; | ||
1783 | default: | 1853 | default: |
1784 | BT_DBG("Unknown op %u", opcode); | 1854 | BT_DBG("Unknown op %u", opcode); |
1785 | err = cmd_status(sk, index, opcode, 0x01); | 1855 | err = cmd_status(sk, index, opcode, 0x01); |