diff options
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r-- | net/bluetooth/mgmt.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index dac7d39b810b..545f84dbae85 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -1760,6 +1760,62 @@ static int unblock_device(struct sock *sk, u16 index, unsigned char *data, | |||
1760 | return err; | 1760 | return err; |
1761 | } | 1761 | } |
1762 | 1762 | ||
1763 | static int set_fast_connectable(struct sock *sk, u16 index, | ||
1764 | unsigned char *data, u16 len) | ||
1765 | { | ||
1766 | struct hci_dev *hdev; | ||
1767 | struct mgmt_cp_set_fast_connectable *cp = (void *) data; | ||
1768 | struct hci_cp_write_page_scan_activity acp; | ||
1769 | u8 type; | ||
1770 | int err; | ||
1771 | |||
1772 | BT_DBG("hci%u", index); | ||
1773 | |||
1774 | if (len != sizeof(*cp)) | ||
1775 | return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE, | ||
1776 | EINVAL); | ||
1777 | |||
1778 | hdev = hci_dev_get(index); | ||
1779 | if (!hdev) | ||
1780 | return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE, | ||
1781 | ENODEV); | ||
1782 | |||
1783 | hci_dev_lock(hdev); | ||
1784 | |||
1785 | if (cp->enable) { | ||
1786 | type = PAGE_SCAN_TYPE_INTERLACED; | ||
1787 | acp.interval = 0x0024; /* 22.5 msec page scan interval */ | ||
1788 | } else { | ||
1789 | type = PAGE_SCAN_TYPE_STANDARD; /* default */ | ||
1790 | acp.interval = 0x0800; /* default 1.28 sec page scan */ | ||
1791 | } | ||
1792 | |||
1793 | acp.window = 0x0012; /* default 11.25 msec page scan window */ | ||
1794 | |||
1795 | err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY, | ||
1796 | sizeof(acp), &acp); | ||
1797 | if (err < 0) { | ||
1798 | err = cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE, | ||
1799 | -err); | ||
1800 | goto done; | ||
1801 | } | ||
1802 | |||
1803 | err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type); | ||
1804 | if (err < 0) { | ||
1805 | err = cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE, | ||
1806 | -err); | ||
1807 | goto done; | ||
1808 | } | ||
1809 | |||
1810 | err = cmd_complete(sk, index, MGMT_OP_SET_FAST_CONNECTABLE, | ||
1811 | NULL, 0); | ||
1812 | done: | ||
1813 | hci_dev_unlock(hdev); | ||
1814 | hci_dev_put(hdev); | ||
1815 | |||
1816 | return err; | ||
1817 | } | ||
1818 | |||
1763 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | 1819 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) |
1764 | { | 1820 | { |
1765 | unsigned char *buf; | 1821 | unsigned char *buf; |
@@ -1880,6 +1936,10 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | |||
1880 | case MGMT_OP_UNBLOCK_DEVICE: | 1936 | case MGMT_OP_UNBLOCK_DEVICE: |
1881 | err = unblock_device(sk, index, buf + sizeof(*hdr), len); | 1937 | err = unblock_device(sk, index, buf + sizeof(*hdr), len); |
1882 | break; | 1938 | break; |
1939 | case MGMT_OP_SET_FAST_CONNECTABLE: | ||
1940 | err = set_fast_connectable(sk, index, buf + sizeof(*hdr), | ||
1941 | len); | ||
1942 | break; | ||
1883 | default: | 1943 | default: |
1884 | BT_DBG("Unknown op %u", opcode); | 1944 | BT_DBG("Unknown op %u", opcode); |
1885 | err = cmd_status(sk, index, opcode, 0x01); | 1945 | err = cmd_status(sk, index, opcode, 0x01); |