aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
authorAntti Julku <antti.julku@nokia.com>2011-08-25 09:48:02 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-09-21 11:59:15 -0400
commit5e762444b0d3e56bbd66f5092434c4a1ba698313 (patch)
treead54379252e2fa923a3001a1c194ef541a87a686 /net/bluetooth/mgmt.c
parentc908df362c20be0eeef506fe62e13d835a4633f9 (diff)
Bluetooth: Add mgmt events for blacklisting
Add management interface events for blocking/unblocking a device. Sender of the block device command gets cmd complete and other mgmt sockets get the event. Event is also sent to mgmt sockets when blocking is done with ioctl, e.g when blocking a device with hciconfig. This makes it possible for bluetoothd to track status of blocked devices when a third party block or unblocks a device. Event sending is handled in mgmt_device_blocked function which gets called from hci_blacklist_add in hci_core.c. A pending command is added in mgmt_block_device, so that it can found when sending the event - the event is not sent to the socket from which the pending command came. Locks were moved out from hci_core.c to hci_sock.c and mgmt.c, because locking is needed also for mgmt_pending_add in mgmt.c. Signed-off-by: Antti Julku <antti.julku@nokia.com> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r--net/bluetooth/mgmt.c62
1 files changed, 56 insertions, 6 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 6493e807634f..579f7261a7fe 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1698,13 +1698,12 @@ static int block_device(struct sock *sk, u16 index, unsigned char *data,
1698 u16 len) 1698 u16 len)
1699{ 1699{
1700 struct hci_dev *hdev; 1700 struct hci_dev *hdev;
1701 struct mgmt_cp_block_device *cp; 1701 struct pending_cmd *cmd;
1702 struct mgmt_cp_block_device *cp = (void *) data;
1702 int err; 1703 int err;
1703 1704
1704 BT_DBG("hci%u", index); 1705 BT_DBG("hci%u", index);
1705 1706
1706 cp = (void *) data;
1707
1708 if (len != sizeof(*cp)) 1707 if (len != sizeof(*cp))
1709 return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE, 1708 return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
1710 EINVAL); 1709 EINVAL);
@@ -1714,6 +1713,14 @@ static int block_device(struct sock *sk, u16 index, unsigned char *data,
1714 return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE, 1713 return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
1715 ENODEV); 1714 ENODEV);
1716 1715
1716 hci_dev_lock_bh(hdev);
1717
1718 cmd = mgmt_pending_add(sk, MGMT_OP_BLOCK_DEVICE, index, NULL, 0);
1719 if (!cmd) {
1720 err = -ENOMEM;
1721 goto failed;
1722 }
1723
1717 err = hci_blacklist_add(hdev, &cp->bdaddr); 1724 err = hci_blacklist_add(hdev, &cp->bdaddr);
1718 1725
1719 if (err < 0) 1726 if (err < 0)
@@ -1721,6 +1728,11 @@ static int block_device(struct sock *sk, u16 index, unsigned char *data,
1721 else 1728 else
1722 err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE, 1729 err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE,
1723 NULL, 0); 1730 NULL, 0);
1731
1732 mgmt_pending_remove(cmd);
1733
1734failed:
1735 hci_dev_unlock_bh(hdev);
1724 hci_dev_put(hdev); 1736 hci_dev_put(hdev);
1725 1737
1726 return err; 1738 return err;
@@ -1730,13 +1742,12 @@ static int unblock_device(struct sock *sk, u16 index, unsigned char *data,
1730 u16 len) 1742 u16 len)
1731{ 1743{
1732 struct hci_dev *hdev; 1744 struct hci_dev *hdev;
1733 struct mgmt_cp_unblock_device *cp; 1745 struct pending_cmd *cmd;
1746 struct mgmt_cp_unblock_device *cp = (void *) data;
1734 int err; 1747 int err;
1735 1748
1736 BT_DBG("hci%u", index); 1749 BT_DBG("hci%u", index);
1737 1750
1738 cp = (void *) data;
1739
1740 if (len != sizeof(*cp)) 1751 if (len != sizeof(*cp))
1741 return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE, 1752 return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
1742 EINVAL); 1753 EINVAL);
@@ -1746,6 +1757,14 @@ static int unblock_device(struct sock *sk, u16 index, unsigned char *data,
1746 return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE, 1757 return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
1747 ENODEV); 1758 ENODEV);
1748 1759
1760 hci_dev_lock_bh(hdev);
1761
1762 cmd = mgmt_pending_add(sk, MGMT_OP_UNBLOCK_DEVICE, index, NULL, 0);
1763 if (!cmd) {
1764 err = -ENOMEM;
1765 goto failed;
1766 }
1767
1749 err = hci_blacklist_del(hdev, &cp->bdaddr); 1768 err = hci_blacklist_del(hdev, &cp->bdaddr);
1750 1769
1751 if (err < 0) 1770 if (err < 0)
@@ -1753,6 +1772,11 @@ static int unblock_device(struct sock *sk, u16 index, unsigned char *data,
1753 else 1772 else
1754 err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE, 1773 err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE,
1755 NULL, 0); 1774 NULL, 0);
1775
1776 mgmt_pending_remove(cmd);
1777
1778failed:
1779 hci_dev_unlock_bh(hdev);
1756 hci_dev_put(hdev); 1780 hci_dev_put(hdev);
1757 1781
1758 return err; 1782 return err;
@@ -2356,3 +2380,29 @@ int mgmt_discovering(u16 index, u8 discovering)
2356 return mgmt_event(MGMT_EV_DISCOVERING, index, &discovering, 2380 return mgmt_event(MGMT_EV_DISCOVERING, index, &discovering,
2357 sizeof(discovering), NULL); 2381 sizeof(discovering), NULL);
2358} 2382}
2383
2384int mgmt_device_blocked(u16 index, bdaddr_t *bdaddr)
2385{
2386 struct pending_cmd *cmd;
2387 struct mgmt_ev_device_blocked ev;
2388
2389 cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, index);
2390
2391 bacpy(&ev.bdaddr, bdaddr);
2392
2393 return mgmt_event(MGMT_EV_DEVICE_BLOCKED, index, &ev, sizeof(ev),
2394 cmd ? cmd->sk : NULL);
2395}
2396
2397int mgmt_device_unblocked(u16 index, bdaddr_t *bdaddr)
2398{
2399 struct pending_cmd *cmd;
2400 struct mgmt_ev_device_unblocked ev;
2401
2402 cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, index);
2403
2404 bacpy(&ev.bdaddr, bdaddr);
2405
2406 return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, index, &ev, sizeof(ev),
2407 cmd ? cmd->sk : NULL);
2408}