aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_event.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2011-01-17 07:41:05 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2011-02-07 22:40:07 -0500
commit55ed8ca10f3530de8edbbf138acb50992bf5005b (patch)
tree3145b2b995758b2cb64493fc8ec29e63d0e9f0b4 /net/bluetooth/hci_event.c
parent1aff6f09491f454d4cd9f405c783fa5e9d3168a0 (diff)
Bluetooth: Implement link key handling for the management interface
This patch adds a management commands to feed the kernel with all stored link keys as well as remove specific ones or all of them. Once the load_keys command has been called the kernel takes over link key replies. A new_key event is also added to inform userspace of newly created link keys that should be stored permanently. Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r--net/bluetooth/hci_event.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index c69ee44d5bd7..80ffd3a901fc 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1810,13 +1810,60 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff
1810 1810
1811static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 1811static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1812{ 1812{
1813 struct hci_ev_link_key_req *ev = (void *) skb->data;
1814 struct hci_cp_link_key_reply cp;
1815 struct hci_conn *conn;
1816 struct link_key *key;
1817
1813 BT_DBG("%s", hdev->name); 1818 BT_DBG("%s", hdev->name);
1819
1820 if (!test_bit(HCI_LINK_KEYS, &hdev->flags))
1821 return;
1822
1823 hci_dev_lock(hdev);
1824
1825 key = hci_find_link_key(hdev, &ev->bdaddr);
1826 if (!key) {
1827 BT_DBG("%s link key not found for %s", hdev->name,
1828 batostr(&ev->bdaddr));
1829 goto not_found;
1830 }
1831
1832 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
1833 batostr(&ev->bdaddr));
1834
1835 if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) && key->type == 0x03) {
1836 BT_DBG("%s ignoring debug key", hdev->name);
1837 goto not_found;
1838 }
1839
1840 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1841
1842 if (key->type == 0x04 && conn && conn->auth_type != 0xff &&
1843 (conn->auth_type & 0x01)) {
1844 BT_DBG("%s ignoring unauthenticated key", hdev->name);
1845 goto not_found;
1846 }
1847
1848 bacpy(&cp.bdaddr, &ev->bdaddr);
1849 memcpy(cp.link_key, key->val, 16);
1850
1851 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
1852
1853 hci_dev_unlock(hdev);
1854
1855 return;
1856
1857not_found:
1858 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
1859 hci_dev_unlock(hdev);
1814} 1860}
1815 1861
1816static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 1862static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
1817{ 1863{
1818 struct hci_ev_link_key_notify *ev = (void *) skb->data; 1864 struct hci_ev_link_key_notify *ev = (void *) skb->data;
1819 struct hci_conn *conn; 1865 struct hci_conn *conn;
1866 u8 pin_len = 0;
1820 1867
1821 BT_DBG("%s", hdev->name); 1868 BT_DBG("%s", hdev->name);
1822 1869
@@ -1829,6 +1876,10 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff
1829 hci_conn_put(conn); 1876 hci_conn_put(conn);
1830 } 1877 }
1831 1878
1879 if (test_bit(HCI_LINK_KEYS, &hdev->flags))
1880 hci_add_link_key(hdev, 1, &ev->bdaddr, ev->link_key,
1881 ev->key_type, pin_len);
1882
1832 hci_dev_unlock(hdev); 1883 hci_dev_unlock(hdev);
1833} 1884}
1834 1885