Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Antti Julku and committed by
Gustavo F. Padovan
f6422ec6 cfafccf7

+75
+10
include/net/bluetooth/hci.h
··· 716 716 bdaddr_t bdaddr; 717 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 729 #define HCI_OP_LE_SET_EVENT_MASK 0x2001 720 730 struct hci_cp_le_set_event_mask { 721 731 __u8 mask[8];
+5
include/net/bluetooth/mgmt.h
··· 211 211 bdaddr_t bdaddr; 212 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 219 #define MGMT_EV_CMD_COMPLETE 0x0001 215 220 struct mgmt_ev_cmd_complete { 216 221 __le16 opcode;
+60
net/bluetooth/mgmt.c
··· 1760 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 1819 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) 1764 1820 { 1765 1821 unsigned char *buf; ··· 1935 1879 break; 1936 1880 case MGMT_OP_UNBLOCK_DEVICE: 1937 1881 err = unblock_device(sk, index, buf + sizeof(*hdr), len); 1882 + break; 1883 + case MGMT_OP_SET_FAST_CONNECTABLE: 1884 + err = set_fast_connectable(sk, index, buf + sizeof(*hdr), 1885 + len); 1938 1886 break; 1939 1887 default: 1940 1888 BT_DBG("Unknown op %u", opcode);