diff options
author | Antti Julku <antti.julku@nokia.com> | 2011-06-22 06:11:56 -0400 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-09-21 11:58:12 -0400 |
commit | f6422ec624a19ba144b4b5cdbbc5ee41cc6f6400 (patch) | |
tree | 7b6e370bc46750718a7222b9c63f34da0072071d | |
parent | cfafccf730d363accacbd165542095ce6f7d2de8 (diff) |
Bluetooth: Add mgmt command for fast connectable mode
Add command to management interface for enabling/disabling the
fast connectable mode.
Signed-off-by: Antti Julku <antti.julku@nokia.com>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
-rw-r--r-- | include/net/bluetooth/hci.h | 10 | ||||
-rw-r--r-- | include/net/bluetooth/mgmt.h | 5 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 60 |
3 files changed, 75 insertions, 0 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index be30aabe7b88..aaf79af72432 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -716,6 +716,16 @@ struct hci_rp_read_bd_addr { | |||
716 | bdaddr_t bdaddr; | 716 | bdaddr_t bdaddr; |
717 | } __packed; | 717 | } __packed; |
718 | 718 | ||
719 | #define HCI_OP_WRITE_PAGE_SCAN_ACTIVITY 0x0c1c | ||
720 | struct hci_cp_write_page_scan_activity { | ||
721 | __le16 interval; | ||
722 | __le16 window; | ||
723 | } __packed; | ||
724 | |||
725 | #define HCI_OP_WRITE_PAGE_SCAN_TYPE 0x0c47 | ||
726 | #define PAGE_SCAN_TYPE_STANDARD 0x00 | ||
727 | #define PAGE_SCAN_TYPE_INTERLACED 0x01 | ||
728 | |||
719 | #define HCI_OP_LE_SET_EVENT_MASK 0x2001 | 729 | #define HCI_OP_LE_SET_EVENT_MASK 0x2001 |
720 | struct hci_cp_le_set_event_mask { | 730 | struct hci_cp_le_set_event_mask { |
721 | __u8 mask[8]; | 731 | __u8 mask[8]; |
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 1c914ddc6d7a..48522e6386bf 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h | |||
@@ -211,6 +211,11 @@ struct mgmt_cp_unblock_device { | |||
211 | bdaddr_t bdaddr; | 211 | bdaddr_t bdaddr; |
212 | } __packed; | 212 | } __packed; |
213 | 213 | ||
214 | #define MGMT_OP_SET_FAST_CONNECTABLE 0x001F | ||
215 | struct mgmt_cp_set_fast_connectable { | ||
216 | __u8 enable; | ||
217 | } __packed; | ||
218 | |||
214 | #define MGMT_EV_CMD_COMPLETE 0x0001 | 219 | #define MGMT_EV_CMD_COMPLETE 0x0001 |
215 | struct mgmt_ev_cmd_complete { | 220 | struct mgmt_ev_cmd_complete { |
216 | __le16 opcode; | 221 | __le16 opcode; |
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); |