diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2012-01-17 14:48:47 -0500 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2012-02-13 10:01:28 -0500 |
commit | b644ba33699711630099efc58a4efc225560aceb (patch) | |
tree | 405fdec148d9d10186acf0e0d121b987eb208f19 /net/bluetooth/hci_event.c | |
parent | a0c808b373e89aecc3ecae4cbdcdeff68aa12e3e (diff) |
Bluetooth: Update device_connected and device_found events to latest API
This patch updates mgmt_ev_device_connected and mgmt_ev_device found to
include an EIR-encoded remote name and class whenever possible. With
this addition the mgmt_ev_remote_name event becomes unnecessary and can
be removed. Since the connected event doesn't map to hci_conn_complete
anymore a HCI_CONN_MGMT_CONNECTED flag is added to track when mgmt has
been notified about a connection.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r-- | net/bluetooth/hci_event.c | 78 |
1 files changed, 56 insertions, 22 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index f6c13153a5e7..f0b08ab734d7 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -1286,11 +1286,36 @@ static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e | |||
1286 | return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); | 1286 | return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); |
1287 | } | 1287 | } |
1288 | 1288 | ||
1289 | static void hci_resolve_next_name(struct hci_dev *hdev, bdaddr_t *bdaddr) | 1289 | static bool hci_resolve_next_name(struct hci_dev *hdev) |
1290 | { | 1290 | { |
1291 | struct discovery_state *discov = &hdev->discovery; | 1291 | struct discovery_state *discov = &hdev->discovery; |
1292 | struct inquiry_entry *e; | 1292 | struct inquiry_entry *e; |
1293 | 1293 | ||
1294 | if (list_empty(&discov->resolve)) | ||
1295 | return false; | ||
1296 | |||
1297 | e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); | ||
1298 | if (hci_resolve_name(hdev, e) == 0) { | ||
1299 | e->name_state = NAME_PENDING; | ||
1300 | return true; | ||
1301 | } | ||
1302 | |||
1303 | return false; | ||
1304 | } | ||
1305 | |||
1306 | static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, | ||
1307 | bdaddr_t *bdaddr, u8 *name, u8 name_len) | ||
1308 | { | ||
1309 | struct discovery_state *discov = &hdev->discovery; | ||
1310 | struct inquiry_entry *e; | ||
1311 | |||
1312 | if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) | ||
1313 | mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, | ||
1314 | name, name_len, conn->dev_class); | ||
1315 | |||
1316 | if (discov->state == DISCOVERY_STOPPED) | ||
1317 | return; | ||
1318 | |||
1294 | if (discov->state == DISCOVERY_STOPPING) | 1319 | if (discov->state == DISCOVERY_STOPPING) |
1295 | goto discov_complete; | 1320 | goto discov_complete; |
1296 | 1321 | ||
@@ -1301,16 +1326,13 @@ static void hci_resolve_next_name(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
1301 | if (e) { | 1326 | if (e) { |
1302 | e->name_state = NAME_KNOWN; | 1327 | e->name_state = NAME_KNOWN; |
1303 | list_del(&e->list); | 1328 | list_del(&e->list); |
1329 | if (name) | ||
1330 | mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, | ||
1331 | e->data.rssi, name, name_len); | ||
1304 | } | 1332 | } |
1305 | 1333 | ||
1306 | if (list_empty(&discov->resolve)) | 1334 | if (hci_resolve_next_name(hdev)) |
1307 | goto discov_complete; | ||
1308 | |||
1309 | e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); | ||
1310 | if (hci_resolve_name(hdev, e) == 0) { | ||
1311 | e->name_state = NAME_PENDING; | ||
1312 | return; | 1335 | return; |
1313 | } | ||
1314 | 1336 | ||
1315 | discov_complete: | 1337 | discov_complete: |
1316 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | 1338 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); |
@@ -1334,10 +1356,11 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) | |||
1334 | 1356 | ||
1335 | hci_dev_lock(hdev); | 1357 | hci_dev_lock(hdev); |
1336 | 1358 | ||
1359 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); | ||
1360 | |||
1337 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) | 1361 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) |
1338 | hci_resolve_next_name(hdev, &cp->bdaddr); | 1362 | hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0); |
1339 | 1363 | ||
1340 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); | ||
1341 | if (!conn) | 1364 | if (!conn) |
1342 | goto unlock; | 1365 | goto unlock; |
1343 | 1366 | ||
@@ -1643,8 +1666,6 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1643 | conn->state = BT_CONFIG; | 1666 | conn->state = BT_CONFIG; |
1644 | hci_conn_hold(conn); | 1667 | hci_conn_hold(conn); |
1645 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 1668 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
1646 | mgmt_device_connected(hdev, &ev->bdaddr, conn->type, | ||
1647 | conn->dst_type); | ||
1648 | } else | 1669 | } else |
1649 | conn->state = BT_CONNECTED; | 1670 | conn->state = BT_CONNECTED; |
1650 | 1671 | ||
@@ -1785,7 +1806,8 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
1785 | if (ev->status == 0) | 1806 | if (ev->status == 0) |
1786 | conn->state = BT_CLOSED; | 1807 | conn->state = BT_CLOSED; |
1787 | 1808 | ||
1788 | if (conn->type == ACL_LINK || conn->type == LE_LINK) { | 1809 | if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) && |
1810 | (conn->type == ACL_LINK || conn->type == LE_LINK)) { | ||
1789 | if (ev->status != 0) | 1811 | if (ev->status != 0) |
1790 | mgmt_disconnect_failed(hdev, &conn->dst, ev->status); | 1812 | mgmt_disconnect_failed(hdev, &conn->dst, ev->status); |
1791 | else | 1813 | else |
@@ -1878,14 +1900,18 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb | |||
1878 | 1900 | ||
1879 | hci_dev_lock(hdev); | 1901 | hci_dev_lock(hdev); |
1880 | 1902 | ||
1881 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) { | 1903 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); |
1882 | if (ev->status == 0) | ||
1883 | mgmt_remote_name(hdev, &ev->bdaddr, ev->name); | ||
1884 | 1904 | ||
1885 | hci_resolve_next_name(hdev, &ev->bdaddr); | 1905 | if (!test_bit(HCI_MGMT, &hdev->dev_flags)) |
1886 | } | 1906 | goto check_auth; |
1887 | 1907 | ||
1888 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | 1908 | if (ev->status == 0) |
1909 | hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name, | ||
1910 | strnlen(ev->name, HCI_MAX_NAME_LENGTH)); | ||
1911 | else | ||
1912 | hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0); | ||
1913 | |||
1914 | check_auth: | ||
1889 | if (!conn) | 1915 | if (!conn) |
1890 | goto unlock; | 1916 | goto unlock; |
1891 | 1917 | ||
@@ -1994,7 +2020,10 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff | |||
1994 | bacpy(&cp.bdaddr, &conn->dst); | 2020 | bacpy(&cp.bdaddr, &conn->dst); |
1995 | cp.pscan_rep_mode = 0x02; | 2021 | cp.pscan_rep_mode = 0x02; |
1996 | hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); | 2022 | hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); |
1997 | } | 2023 | } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) |
2024 | mgmt_device_connected(hdev, &conn->dst, conn->type, | ||
2025 | conn->dst_type, NULL, 0, | ||
2026 | conn->dev_class); | ||
1998 | 2027 | ||
1999 | if (!hci_outgoing_auth_needed(hdev, conn)) { | 2028 | if (!hci_outgoing_auth_needed(hdev, conn)) { |
2000 | conn->state = BT_CONNECTED; | 2029 | conn->state = BT_CONNECTED; |
@@ -2763,7 +2792,10 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b | |||
2763 | bacpy(&cp.bdaddr, &conn->dst); | 2792 | bacpy(&cp.bdaddr, &conn->dst); |
2764 | cp.pscan_rep_mode = 0x02; | 2793 | cp.pscan_rep_mode = 0x02; |
2765 | hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); | 2794 | hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); |
2766 | } | 2795 | } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) |
2796 | mgmt_device_connected(hdev, &conn->dst, conn->type, | ||
2797 | conn->dst_type, NULL, 0, | ||
2798 | conn->dev_class); | ||
2767 | 2799 | ||
2768 | if (!hci_outgoing_auth_needed(hdev, conn)) { | 2800 | if (!hci_outgoing_auth_needed(hdev, conn)) { |
2769 | conn->state = BT_CONNECTED; | 2801 | conn->state = BT_CONNECTED; |
@@ -3164,7 +3196,9 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
3164 | goto unlock; | 3196 | goto unlock; |
3165 | } | 3197 | } |
3166 | 3198 | ||
3167 | mgmt_device_connected(hdev, &ev->bdaddr, conn->type, conn->dst_type); | 3199 | if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) |
3200 | mgmt_device_connected(hdev, &ev->bdaddr, conn->type, | ||
3201 | conn->dst_type, NULL, 0, 0); | ||
3168 | 3202 | ||
3169 | conn->sec_level = BT_SECURITY_LOW; | 3203 | conn->sec_level = BT_SECURITY_LOW; |
3170 | conn->handle = __le16_to_cpu(ev->handle); | 3204 | conn->handle = __le16_to_cpu(ev->handle); |