diff options
-rw-r--r-- | include/net/bluetooth/hci_core.h | 2 | ||||
-rw-r--r-- | include/net/bluetooth/mgmt.h | 12 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 16 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 20 |
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); +} |