Bluetooth: Add support for management powered event
Johan Hedberg [Thu, 16 Dec 2010 08:00:37 +0000 (10:00 +0200)]
This patch adds support for the powered event that's used to indicate to
userspace when the powered state of a local adapter changes.

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_core.c
net/bluetooth/mgmt.c

index 75c4f20..32e11b3 100644 (file)
@@ -673,6 +673,7 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
 int mgmt_index_added(u16 index);
 int mgmt_index_removed(u16 index);
+int mgmt_powered(u16 index, u8 powered);
 
 /* HCI info for socket */
 #define hci_pi(sk) ((struct hci_pinfo *) sk)
index ca29c13..0ac1520 100644 (file)
@@ -85,3 +85,9 @@ struct mgmt_ev_index_added {
 struct mgmt_ev_index_removed {
        __le16 index;
 } __packed;
+
+#define MGMT_EV_POWERED                        0x0006
+struct mgmt_ev_powered {
+       __le16 index;
+       __u8 powered;
+} __packed;
index b22ce9f..c5a78e7 100644 (file)
@@ -535,6 +535,8 @@ int hci_dev_open(__u16 dev)
                hci_dev_hold(hdev);
                set_bit(HCI_UP, &hdev->flags);
                hci_notify(hdev, HCI_DEV_UP);
+               if (!test_bit(HCI_SETUP, &hdev->flags))
+                       mgmt_powered(hdev->id, 1);
        } else {
                /* Init failed, cleanup */
                tasklet_kill(&hdev->rx_task);
@@ -616,6 +618,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
         * and no tasks are scheduled. */
        hdev->close(hdev);
 
+       mgmt_powered(hdev->id, 0);
+
        /* Clear flags */
        hdev->flags = 0;
 
index d479e24..f746e19 100644 (file)
@@ -316,3 +316,13 @@ int mgmt_index_removed(u16 index)
 
        return mgmt_event(MGMT_EV_INDEX_REMOVED, &ev, sizeof(ev));
 }
+
+int mgmt_powered(u16 index, u8 powered)
+{
+       struct mgmt_ev_powered ev;
+
+       put_unaligned_le16(index, &ev.index);
+       ev.powered = powered;
+
+       return mgmt_event(MGMT_EV_POWERED, &ev, sizeof(ev));
+}