aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r--net/bluetooth/mgmt.c95
1 files changed, 89 insertions, 6 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index c304688252b8..2481d257ed98 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -945,7 +945,7 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
945 for (i = 0; i < key_count; i++) { 945 for (i = 0; i < key_count; i++) {
946 struct mgmt_key_info *key = &cp->keys[i]; 946 struct mgmt_key_info *key = &cp->keys[i];
947 947
948 hci_add_link_key(hdev, 0, &key->bdaddr, key->val, key->type, 948 hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type,
949 key->pin_len); 949 key->pin_len);
950 } 950 }
951 951
@@ -1569,6 +1569,75 @@ static int remove_remote_oob_data(struct sock *sk, u16 index,
1569 return err; 1569 return err;
1570} 1570}
1571 1571
1572static int start_discovery(struct sock *sk, u16 index)
1573{
1574 u8 lap[3] = { 0x33, 0x8b, 0x9e };
1575 struct hci_cp_inquiry cp;
1576 struct pending_cmd *cmd;
1577 struct hci_dev *hdev;
1578 int err;
1579
1580 BT_DBG("hci%u", index);
1581
1582 hdev = hci_dev_get(index);
1583 if (!hdev)
1584 return cmd_status(sk, index, MGMT_OP_START_DISCOVERY, ENODEV);
1585
1586 hci_dev_lock_bh(hdev);
1587
1588 cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, index, NULL, 0);
1589 if (!cmd) {
1590 err = -ENOMEM;
1591 goto failed;
1592 }
1593
1594 memset(&cp, 0, sizeof(cp));
1595 memcpy(&cp.lap, lap, 3);
1596 cp.length = 0x08;
1597 cp.num_rsp = 0x00;
1598
1599 err = hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
1600 if (err < 0)
1601 mgmt_pending_remove(cmd);
1602
1603failed:
1604 hci_dev_unlock_bh(hdev);
1605 hci_dev_put(hdev);
1606
1607 return err;
1608}
1609
1610static int stop_discovery(struct sock *sk, u16 index)
1611{
1612 struct hci_dev *hdev;
1613 struct pending_cmd *cmd;
1614 int err;
1615
1616 BT_DBG("hci%u", index);
1617
1618 hdev = hci_dev_get(index);
1619 if (!hdev)
1620 return cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY, ENODEV);
1621
1622 hci_dev_lock_bh(hdev);
1623
1624 cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, index, NULL, 0);
1625 if (!cmd) {
1626 err = -ENOMEM;
1627 goto failed;
1628 }
1629
1630 err = hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
1631 if (err < 0)
1632 mgmt_pending_remove(cmd);
1633
1634failed:
1635 hci_dev_unlock_bh(hdev);
1636 hci_dev_put(hdev);
1637
1638 return err;
1639}
1640
1572int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) 1641int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
1573{ 1642{
1574 unsigned char *buf; 1643 unsigned char *buf;
@@ -1677,7 +1746,12 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
1677 err = remove_remote_oob_data(sk, index, buf + sizeof(*hdr), 1746 err = remove_remote_oob_data(sk, index, buf + sizeof(*hdr),
1678 len); 1747 len);
1679 break; 1748 break;
1680 1749 case MGMT_OP_START_DISCOVERY:
1750 err = start_discovery(sk, index);
1751 break;
1752 case MGMT_OP_STOP_DISCOVERY:
1753 err = stop_discovery(sk, index);
1754 break;
1681 default: 1755 default:
1682 BT_DBG("Unknown op %u", opcode); 1756 BT_DBG("Unknown op %u", opcode);
1683 err = cmd_status(sk, index, opcode, 0x01); 1757 err = cmd_status(sk, index, opcode, 0x01);
@@ -1784,17 +1858,17 @@ int mgmt_connectable(u16 index, u8 connectable)
1784 return ret; 1858 return ret;
1785} 1859}
1786 1860
1787int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type) 1861int mgmt_new_key(u16 index, struct link_key *key, u8 persistent)
1788{ 1862{
1789 struct mgmt_ev_new_key ev; 1863 struct mgmt_ev_new_key ev;
1790 1864
1791 memset(&ev, 0, sizeof(ev)); 1865 memset(&ev, 0, sizeof(ev));
1792 1866
1867 ev.store_hint = persistent;
1793 bacpy(&ev.key.bdaddr, &key->bdaddr); 1868 bacpy(&ev.key.bdaddr, &key->bdaddr);
1794 ev.key.type = key->type; 1869 ev.key.type = key->type;
1795 memcpy(ev.key.val, key->val, 16); 1870 memcpy(ev.key.val, key->val, 16);
1796 ev.key.pin_len = key->pin_len; 1871 ev.key.pin_len = key->pin_len;
1797 ev.old_key_type = old_key_type;
1798 1872
1799 return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL); 1873 return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL);
1800} 1874}
@@ -1868,11 +1942,12 @@ int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status)
1868 return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL); 1942 return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL);
1869} 1943}
1870 1944
1871int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr) 1945int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure)
1872{ 1946{
1873 struct mgmt_ev_pin_code_request ev; 1947 struct mgmt_ev_pin_code_request ev;
1874 1948
1875 bacpy(&ev.bdaddr, bdaddr); 1949 bacpy(&ev.bdaddr, bdaddr);
1950 ev.secure = secure;
1876 1951
1877 return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, index, &ev, sizeof(ev), 1952 return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, index, &ev, sizeof(ev),
1878 NULL); 1953 NULL);
@@ -1920,13 +1995,15 @@ int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
1920 return err; 1995 return err;
1921} 1996}
1922 1997
1923int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value) 1998int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value,
1999 u8 confirm_hint)
1924{ 2000{
1925 struct mgmt_ev_user_confirm_request ev; 2001 struct mgmt_ev_user_confirm_request ev;
1926 2002
1927 BT_DBG("hci%u", index); 2003 BT_DBG("hci%u", index);
1928 2004
1929 bacpy(&ev.bdaddr, bdaddr); 2005 bacpy(&ev.bdaddr, bdaddr);
2006 ev.confirm_hint = confirm_hint;
1930 put_unaligned_le32(value, &ev.value); 2007 put_unaligned_le32(value, &ev.value);
1931 2008
1932 return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev), 2009 return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev),
@@ -2075,3 +2152,9 @@ int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name)
2075 2152
2076 return mgmt_event(MGMT_EV_REMOTE_NAME, index, &ev, sizeof(ev), NULL); 2153 return mgmt_event(MGMT_EV_REMOTE_NAME, index, &ev, sizeof(ev), NULL);
2077} 2154}
2155
2156int mgmt_discovering(u16 index, u8 discovering)
2157{
2158 return mgmt_event(MGMT_EV_DISCOVERING, index, &discovering,
2159 sizeof(discovering), NULL);
2160}