summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2011-01-20 12:34:39 +0200
committerGustavo F. Padovan <padovan@profusion.mobi>2011-02-08 01:40:07 -0200
commitf7520543ab40341edbc2aeee7fef68218be19a0a (patch)
tree6f116b5215a134bab6b9615f97767eba040f0683
parent55ed8ca10f3530de8edbbf138acb50992bf5005b (diff)
downloadlinux-f7520543ab40341edbc2aeee7fef68218be19a0a.tar.gz
linux-f7520543ab40341edbc2aeee7fef68218be19a0a.tar.bz2
linux-f7520543ab40341edbc2aeee7fef68218be19a0a.zip
Bluetooth: Add connected/disconnected management events
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>
-rw-r--r--include/net/bluetooth/hci_core.h2
-rw-r--r--include/net/bluetooth/mgmt.h12
-rw-r--r--net/bluetooth/hci_event.c16
-rw-r--r--net/bluetooth/mgmt.c20
4 files changed, 45 insertions, 5 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 009fa63a9048..746f8dc8aad1 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -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)
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 56b500a2f68c..6719e9a36613 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -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;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 80ffd3a901fc..46ddb029912b 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -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);
}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index bdb0e85f182e..7cf1968157d8 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -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);
+}