diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2010-12-13 21:07:07 +0200 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2010-12-22 22:58:00 -0200 |
commit | c71e97bfaadfa727669fcfcf12301744fd169091 (patch) | |
tree | 0a0a04dee5ec1aa16ef1a6e67a78a0d5a03c14c2 /net/bluetooth | |
parent | f7b64e69c7c75c8e9f2d5e23edec8de1ce883bcc (diff) | |
download | linux-c71e97bfaadfa727669fcfcf12301744fd169091.tar.gz linux-c71e97bfaadfa727669fcfcf12301744fd169091.tar.bz2 linux-c71e97bfaadfa727669fcfcf12301744fd169091.zip |
Bluetooth: Add management events for controller addition & removal
This patch adds Bluetooth Management interface events for controller
addition and removal. The events correspond to the existing HCI_DEV_REG
and HCI_DEV_UNREG stack internal events.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/hci_core.c | 2 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 41 |
2 files changed, 43 insertions, 0 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 51c61f75a797..1a4ec97d5ac4 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -960,6 +960,7 @@ int hci_register_dev(struct hci_dev *hdev) } } + mgmt_index_added(hdev->id); hci_notify(hdev, HCI_DEV_REG); return id; @@ -989,6 +990,7 @@ int hci_unregister_dev(struct hci_dev *hdev) for (i = 0; i < NUM_REASSEMBLY; i++) kfree_skb(hdev->reassembly[i]); + mgmt_index_removed(hdev->id); hci_notify(hdev, HCI_DEV_UNREG); if (hdev->rfkill) { diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index d6c5a32de0b6..f827fd908380 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -265,3 +265,44 @@ done: kfree(buf); return err; } + +static int mgmt_event(u16 event, void *data, u16 data_len) +{ + struct sk_buff *skb; + struct mgmt_hdr *hdr; + + skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC); + if (!skb) + return -ENOMEM; + + bt_cb(skb)->channel = HCI_CHANNEL_CONTROL; + + hdr = (void *) skb_put(skb, sizeof(*hdr)); + hdr->opcode = cpu_to_le16(event); + hdr->len = cpu_to_le16(data_len); + + memcpy(skb_put(skb, data_len), data, data_len); + + hci_send_to_sock(NULL, skb); + kfree_skb(skb); + + return 0; +} + +int mgmt_index_added(u16 index) +{ + struct mgmt_ev_index_added ev; + + put_unaligned_le16(index, &ev.index); + + return mgmt_event(MGMT_EV_INDEX_ADDED, &ev, sizeof(ev)); +} + +int mgmt_index_removed(u16 index) +{ + struct mgmt_ev_index_added ev; + + put_unaligned_le16(index, &ev.index); + + return mgmt_event(MGMT_EV_INDEX_REMOVED, &ev, sizeof(ev)); +} |