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 | 663 | /* Management interface */ |
| 664 | 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 | 668 | /* HCI info for socket */ |
| 667 | 669 | #define hci_pi(sk) ((struct hci_pinfo *) sk) |
| @@ -75,3 +75,13 @@ struct mgmt_ev_controller_error { · 74 unmodified lines | ||
| 75 | 75 | __le16 index; |
| 76 | 76 | __u8 error_code; |
| 77 | 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 | 964 | hci_notify(hdev, HCI_DEV_REG); |
| 964 | 965 | |
| 965 | 966 | return id; |
| @@ -989,6 +990,7 @@ int hci_unregister_dev(struct hci_dev *hdev) · 23 unmodified lines | ||
| 989 | 990 | for (i = 0; i < NUM_REASSEMBLY; i++) |
| 990 | 991 | kfree_skb(hdev->reassembly[i]); |
| 991 | 992 | |
| 993 | + mgmt_index_removed(hdev->id); | |
| 992 | 994 | hci_notify(hdev, HCI_DEV_UNREG); |
| 993 | 995 | |
| 994 | 996 | if (hdev->rfkill) { |
| @@ -265,3 +265,44 @@ done: · 264 unmodified lines | ||
| 265 | 265 | kfree(buf); |
| 266 | 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 | +} | |