Bluetooth: Add connected/disconnected management events
authorJohan Hedberg <johan.hedberg@nokia.com>
Thu, 20 Jan 2011 10:34:39 +0000 (12:34 +0200)
committerGustavo F. Padovan <padovan@profusion.mobi>
Tue, 8 Feb 2011 03:40:07 +0000 (01:40 -0200)
This patch adds connected and disconnected managment events to track the
connection status to remote devices. The events map directly to
successful connection complete and disconnection complete HCI events for
ACL links.

Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
include/net/bluetooth/hci_core.h
include/net/bluetooth/mgmt.h
net/bluetooth/hci_event.c
net/bluetooth/mgmt.c

index 009fa63a90484cd2b8b0879305ff623518181c62..746f8dc8aad1d4f758f2c17392c3de6c5353ff7c 100644 (file)
@@ -714,6 +714,8 @@ int mgmt_powered(u16 index, u8 powered);
 int mgmt_discoverable(u16 index, u8 discoverable);
 int mgmt_connectable(u16 index, u8 connectable);
 int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type);
+int mgmt_connected(u16 index, bdaddr_t *bdaddr);
+int mgmt_disconnected(u16 index, bdaddr_t *bdaddr);
 
 /* HCI info for socket */
 #define hci_pi(sk) ((struct hci_pinfo *) sk)
index 56b500a2f68c5471e8c7467695cde0c1c02f7aaa..6719e9a36613857fc6bfffeed0c5f73ad8afe0dc 100644 (file)
@@ -162,3 +162,15 @@ struct mgmt_ev_new_key {
        struct mgmt_key_info key;
        __u8 old_key_type;
 } __packed;
+
+#define MGMT_EV_CONNECTED              0x000B
+struct mgmt_ev_connected {
+       __le16 index;
+       bdaddr_t bdaddr;
+} __packed;
+
+#define MGMT_EV_DISCONNECTED           0x000C
+struct mgmt_ev_disconnected {
+       __le16 index;
+       bdaddr_t bdaddr;
+} __packed;
index 80ffd3a901fc031edf0c96f2960ca1d001a8a897..46ddb029912b86ca0b38e64e6352622cc82423c8 100644 (file)
@@ -1137,6 +1137,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
                        conn->state = BT_CONFIG;
                        hci_conn_hold(conn);
                        conn->disc_timeout = HCI_DISCONN_TIMEOUT;
+                       mgmt_connected(hdev->id, &ev->bdaddr);
                } else
                        conn->state = BT_CONNECTED;
 
@@ -1269,13 +1270,18 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
        hci_dev_lock(hdev);
 
        conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
-       if (conn) {
-               conn->state = BT_CLOSED;
+       if (!conn)
+               goto unlock;
 
-               hci_proto_disconn_cfm(conn, ev->reason);
-               hci_conn_del(conn);
-       }
+       conn->state = BT_CLOSED;
+
+       if (conn->type == ACL_LINK)
+               mgmt_disconnected(hdev->id, &conn->dst);
 
+       hci_proto_disconn_cfm(conn, ev->reason);
+       hci_conn_del(conn);
+
+unlock:
        hci_dev_unlock(hdev);
 }
 
index bdb0e85f182e8a09dfeaffdc2a451cadacdc9604..7cf1968157d878378ac47d246fbfb4e7c8430c0d 100644 (file)
@@ -1090,3 +1090,23 @@ int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type)
 
        return mgmt_event(MGMT_EV_NEW_KEY, &ev, sizeof(ev), NULL);
 }
+
+int mgmt_connected(u16 index, bdaddr_t *bdaddr)
+{
+       struct mgmt_ev_connected ev;
+
+       put_unaligned_le16(index, &ev.index);
+       bacpy(&ev.bdaddr, bdaddr);
+
+       return mgmt_event(MGMT_EV_CONNECTED, &ev, sizeof(ev), NULL);
+}
+
+int mgmt_disconnected(u16 index, bdaddr_t *bdaddr)
+{
+       struct mgmt_ev_disconnected ev;
+
+       put_unaligned_le16(index, &ev.index);
+       bacpy(&ev.bdaddr, bdaddr);
+
+       return mgmt_event(MGMT_EV_DISCONNECTED, &ev, sizeof(ev), NULL);
+}