aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2010-12-13 14:07:07 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2010-12-22 19:58:00 -0500
commitc71e97bfaadfa727669fcfcf12301744fd169091 (patch)
tree0a0a04dee5ec1aa16ef1a6e67a78a0d5a03c14c2
parentf7b64e69c7c75c8e9f2d5e23edec8de1ce883bcc (diff)
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>
-rw-r--r--include/net/bluetooth/hci_core.h2
-rw-r--r--include/net/bluetooth/mgmt.h10
-rw-r--r--net/bluetooth/hci_core.c2
-rw-r--r--net/bluetooth/mgmt.c41
4 files changed, 55 insertions, 0 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 1992fac7e921..3786ee83604e 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -662,6 +662,8 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
662 662
663/* Management interface */ 663/* Management interface */
664int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); 664int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
665int mgmt_index_added(u16 index);
666int mgmt_index_removed(u16 index);
665 667
666/* HCI info for socket */ 668/* HCI info for socket */
667#define hci_pi(sk) ((struct hci_pinfo *) sk) 669#define hci_pi(sk) ((struct hci_pinfo *) sk)
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 70985aacc14b..ca29c1367ffd 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -75,3 +75,13 @@ struct mgmt_ev_controller_error {
75 __le16 index; 75 __le16 index;
76 __u8 error_code; 76 __u8 error_code;
77} __packed; 77} __packed;
78
79#define MGMT_EV_INDEX_ADDED 0x0004
80struct mgmt_ev_index_added {
81 __le16 index;
82} __packed;
83
84#define MGMT_EV_INDEX_REMOVED 0x0005
85struct mgmt_ev_index_removed {
86 __le16 index;
87} __packed;
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)
960 } 960 }
961 } 961 }
962 962
963 mgmt_index_added(hdev->id);
963 hci_notify(hdev, HCI_DEV_REG); 964 hci_notify(hdev, HCI_DEV_REG);
964 965
965 return id; 966 return id;
@@ -989,6 +990,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
989 for (i = 0; i < NUM_REASSEMBLY; i++) 990 for (i = 0; i < NUM_REASSEMBLY; i++)
990 kfree_skb(hdev->reassembly[i]); 991 kfree_skb(hdev->reassembly[i]);
991 992
993 mgmt_index_removed(hdev->id);
992 hci_notify(hdev, HCI_DEV_UNREG); 994 hci_notify(hdev, HCI_DEV_UNREG);
993 995
994 if (hdev->rfkill) { 996 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:
265 kfree(buf); 265 kfree(buf);
266 return err; 266 return err;
267} 267}
268
269static int mgmt_event(u16 event, void *data, u16 data_len)
270{
271 struct sk_buff *skb;
272 struct mgmt_hdr *hdr;
273
274 skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC);
275 if (!skb)
276 return -ENOMEM;
277
278 bt_cb(skb)->channel = HCI_CHANNEL_CONTROL;
279
280 hdr = (void *) skb_put(skb, sizeof(*hdr));
281 hdr->opcode = cpu_to_le16(event);
282 hdr->len = cpu_to_le16(data_len);
283
284 memcpy(skb_put(skb, data_len), data, data_len);
285
286 hci_send_to_sock(NULL, skb);
287 kfree_skb(skb);
288
289 return 0;
290}
291
292int mgmt_index_added(u16 index)
293{
294 struct mgmt_ev_index_added ev;
295
296 put_unaligned_le16(index, &ev.index);
297
298 return mgmt_event(MGMT_EV_INDEX_ADDED, &ev, sizeof(ev));
299}
300
301int mgmt_index_removed(u16 index)
302{
303 struct mgmt_ev_index_added ev;
304
305 put_unaligned_le16(index, &ev.index);
306
307 return mgmt_event(MGMT_EV_INDEX_REMOVED, &ev, sizeof(ev));
308}