aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2012-01-17 14:48:47 -0500
committerJohan Hedberg <johan.hedberg@intel.com>2012-02-13 10:01:28 -0500
commitb644ba33699711630099efc58a4efc225560aceb (patch)
tree405fdec148d9d10186acf0e0d121b987eb208f19
parenta0c808b373e89aecc3ecae4cbdcdeff68aa12e3e (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>
-rw-r--r--include/net/bluetooth/hci_core.h7
-rw-r--r--include/net/bluetooth/mgmt.h17
-rw-r--r--net/bluetooth/hci_event.c78
-rw-r--r--net/bluetooth/mgmt.c56
4 files changed, 110 insertions, 48 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 520da44940e..18af5427fd0 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -409,6 +409,7 @@ enum {
409 HCI_CONN_MODE_CHANGE_PEND, 409 HCI_CONN_MODE_CHANGE_PEND,
410 HCI_CONN_SCO_SETUP_PEND, 410 HCI_CONN_SCO_SETUP_PEND,
411 HCI_CONN_LE_SMP_PEND, 411 HCI_CONN_LE_SMP_PEND,
412 HCI_CONN_MGMT_CONNECTED,
412}; 413};
413 414
414static inline void hci_conn_hash_init(struct hci_dev *hdev) 415static inline void hci_conn_hash_init(struct hci_dev *hdev)
@@ -933,7 +934,8 @@ int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status);
933int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, 934int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
934 u8 persistent); 935 u8 persistent);
935int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 936int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
936 u8 addr_type); 937 u8 addr_type, u8 *name, u8 name_len,
938 u8 *dev_class);
937int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, 939int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
938 u8 link_type, u8 addr_type); 940 u8 link_type, u8 addr_type);
939int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status); 941int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status);
@@ -962,7 +964,8 @@ int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
962int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 964int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
963 u8 addr_type, u8 *dev_class, s8 rssi, 965 u8 addr_type, u8 *dev_class, s8 rssi,
964 u8 cfm_name, u8 *eir, u16 eir_len); 966 u8 cfm_name, u8 *eir, u16 eir_len);
965int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *name); 967int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
968 u8 addr_type, s8 rssi, u8 *name, u8 name_len);
966int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status); 969int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status);
967int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status); 970int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status);
968int mgmt_discovering(struct hci_dev *hdev, u8 discovering); 971int mgmt_discovering(struct hci_dev *hdev, u8 discovering);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index bdace523b91..6f37983c877 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -329,6 +329,11 @@ struct mgmt_ev_new_link_key {
329} __packed; 329} __packed;
330 330
331#define MGMT_EV_DEVICE_CONNECTED 0x000A 331#define MGMT_EV_DEVICE_CONNECTED 0x000A
332struct mgmt_ev_device_connected {
333 struct mgmt_addr_info addr;
334 __le16 eir_len;
335 __u8 eir[0];
336} __packed;
332 337
333#define MGMT_EV_DEVICE_DISCONNECTED 0x000B 338#define MGMT_EV_DEVICE_DISCONNECTED 0x000B
334 339
@@ -371,20 +376,14 @@ struct mgmt_ev_device_found {
371 __u8 eir[0]; 376 __u8 eir[0];
372} __packed; 377} __packed;
373 378
374#define MGMT_EV_REMOTE_NAME 0x0012 379#define MGMT_EV_DISCOVERING 0x0012
375struct mgmt_ev_remote_name {
376 bdaddr_t bdaddr;
377 __u8 name[MGMT_MAX_NAME_LENGTH];
378} __packed;
379
380#define MGMT_EV_DISCOVERING 0x0013
381 380
382#define MGMT_EV_DEVICE_BLOCKED 0x0014 381#define MGMT_EV_DEVICE_BLOCKED 0x0013
383struct mgmt_ev_device_blocked { 382struct mgmt_ev_device_blocked {
384 bdaddr_t bdaddr; 383 bdaddr_t bdaddr;
385} __packed; 384} __packed;
386 385
387#define MGMT_EV_DEVICE_UNBLOCKED 0x0015 386#define MGMT_EV_DEVICE_UNBLOCKED 0x0014
388struct mgmt_ev_device_unblocked { 387struct mgmt_ev_device_unblocked {
389 bdaddr_t bdaddr; 388 bdaddr_t bdaddr;
390} __packed; 389} __packed;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index f6c13153a5e..f0b08ab734d 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
1289static void hci_resolve_next_name(struct hci_dev *hdev, bdaddr_t *bdaddr) 1289static 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
1306static 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
1315discov_complete: 1337discov_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
1914check_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);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index bec64c98b6a..ae9283d47e6 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1244,7 +1244,6 @@ static int get_connections(struct sock *sk, u16 index)
1244 struct mgmt_rp_get_connections *rp; 1244 struct mgmt_rp_get_connections *rp;
1245 struct hci_dev *hdev; 1245 struct hci_dev *hdev;
1246 struct hci_conn *c; 1246 struct hci_conn *c;
1247 struct list_head *p;
1248 size_t rp_len; 1247 size_t rp_len;
1249 u16 count; 1248 u16 count;
1250 int i, err; 1249 int i, err;
@@ -1259,8 +1258,9 @@ static int get_connections(struct sock *sk, u16 index)
1259 hci_dev_lock(hdev); 1258 hci_dev_lock(hdev);
1260 1259
1261 count = 0; 1260 count = 0;
1262 list_for_each(p, &hdev->conn_hash.list) { 1261 list_for_each_entry(c, &hdev->conn_hash.list, list) {
1263 count++; 1262 if (test_bit(HCI_CONN_MGMT_CONNECTED, &c->flags))
1263 count++;
1264 } 1264 }
1265 1265
1266 rp_len = sizeof(*rp) + (count * sizeof(struct mgmt_addr_info)); 1266 rp_len = sizeof(*rp) + (count * sizeof(struct mgmt_addr_info));
@@ -1274,6 +1274,8 @@ static int get_connections(struct sock *sk, u16 index)
1274 1274
1275 i = 0; 1275 i = 0;
1276 list_for_each_entry(c, &hdev->conn_hash.list, list) { 1276 list_for_each_entry(c, &hdev->conn_hash.list, list) {
1277 if (!test_bit(HCI_CONN_MGMT_CONNECTED, &c->flags))
1278 continue;
1277 bacpy(&rp->addr[i].bdaddr, &c->dst); 1279 bacpy(&rp->addr[i].bdaddr, &c->dst);
1278 rp->addr[i].type = link_to_mgmt(c->type, c->dst_type); 1280 rp->addr[i].type = link_to_mgmt(c->type, c->dst_type);
1279 if (rp->addr[i].type == MGMT_ADDR_INVALID) 1281 if (rp->addr[i].type == MGMT_ADDR_INVALID)
@@ -2465,15 +2467,28 @@ int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
2465} 2467}
2466 2468
2467int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 2469int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
2468 u8 addr_type) 2470 u8 addr_type, u8 *name, u8 name_len,
2471 u8 *dev_class)
2469{ 2472{
2470 struct mgmt_addr_info ev; 2473 char buf[512];
2474 struct mgmt_ev_device_connected *ev = (void *) buf;
2475 u16 eir_len = 0;
2471 2476
2472 bacpy(&ev.bdaddr, bdaddr); 2477 bacpy(&ev->addr.bdaddr, bdaddr);
2473 ev.type = link_to_mgmt(link_type, addr_type); 2478 ev->addr.type = link_to_mgmt(link_type, addr_type);
2474 2479
2475 return mgmt_event(MGMT_EV_DEVICE_CONNECTED, hdev, &ev, sizeof(ev), 2480 if (name_len > 0)
2476 NULL); 2481 eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE,
2482 name, name_len);
2483
2484 if (dev_class && memcmp(dev_class, "\0\0\0", 3) != 0)
2485 eir_len = eir_append_data(&ev->eir[eir_len], eir_len,
2486 EIR_CLASS_OF_DEV, dev_class, 3);
2487
2488 put_unaligned_le16(eir_len, &ev->eir_len);
2489
2490 return mgmt_event(MGMT_EV_DEVICE_CONNECTED, hdev, buf,
2491 sizeof(*ev) + eir_len, NULL);
2477} 2492}
2478 2493
2479static void disconnect_rsp(struct pending_cmd *cmd, void *data) 2494static void disconnect_rsp(struct pending_cmd *cmd, void *data)
@@ -2813,16 +2828,27 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
2813 return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, ev_size, NULL); 2828 return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, ev_size, NULL);
2814} 2829}
2815 2830
2816int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *name) 2831int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
2832 u8 addr_type, s8 rssi, u8 *name, u8 name_len)
2817{ 2833{
2818 struct mgmt_ev_remote_name ev; 2834 struct mgmt_ev_device_found *ev;
2835 char buf[sizeof(*ev) + HCI_MAX_NAME_LENGTH + 2];
2836 u16 eir_len;
2819 2837
2820 memset(&ev, 0, sizeof(ev)); 2838 ev = (struct mgmt_ev_device_found *) buf;
2821 2839
2822 bacpy(&ev.bdaddr, bdaddr); 2840 memset(buf, 0, sizeof(buf));
2823 memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); 2841
2842 bacpy(&ev->addr.bdaddr, bdaddr);
2843 ev->addr.type = link_to_mgmt(link_type, addr_type);
2844 ev->rssi = rssi;
2845
2846 eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, name,
2847 name_len);
2848
2849 put_unaligned_le16(eir_len, &ev->eir_len);
2824 2850
2825 return mgmt_event(MGMT_EV_REMOTE_NAME, hdev, &ev, sizeof(ev), NULL); 2851 return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, &ev, sizeof(ev), NULL);
2826} 2852}
2827 2853
2828int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status) 2854int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status)