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.
Unified · Split
| @@ -662,6 +662,8 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb); · 661 unmodified lines | |||
| 662 | 662 | ||
| 663 | /* Management interface */ | 663 | /* Management interface */ |
| 664 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); | 664 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); |
| 665 | int mgmt_index_added(u16 index); | ||
| 666 | int 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) |
| @@ -75,3 +75,13 @@ struct mgmt_ev_controller_error { · 74 unmodified lines | |||
| 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 | ||
| 80 | struct mgmt_ev_index_added { | ||
| 81 | __le16 index; | ||
| 82 | } __packed; | ||
| 83 | |||
| 84 | #define MGMT_EV_INDEX_REMOVED 0x0005 | ||
| 85 | struct mgmt_ev_index_removed { | ||
| 86 | __le16 index; | ||
| 87 | } __packed; | ||
| @@ -960,6 +960,7 @@ int hci_register_dev(struct hci_dev *hdev) · 959 unmodified lines | |||
| 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) · 23 unmodified lines | |||
| 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) { |
| @@ -265,3 +265,44 @@ done: · 264 unmodified lines | |||
| 265 | kfree(buf); | 265 | kfree(buf); |
| 266 | return err; | 266 | return err; |
| 267 | } | 267 | } |
| 268 | |||
| 269 | static 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 | |||
| 292 | int 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 | |||
| 301 | int 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 | } | ||