aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2015-03-14 22:27:55 -0400
committerJohan Hedberg <johan.hedberg@intel.com>2015-03-15 03:47:51 -0400
commitf920733885546af2fd8d4b3dd5f8a1ac029f6248 (patch)
treecb746a192d0c17278a11acb3a76ce6656d5f9c8d /net/bluetooth
parent17711c62915dd62ab83a5a83a64c0d6105d13b6c (diff)
Bluetooth: Use special function to send filter management index events
For sending Index Added, Index Removed, Unconfigured Index Added and Unconfigured Index Removed managment events the new helper functions allows taking into account if these events are enabled for a certain management socket or not. Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_sock.c10
-rw-r--r--net/bluetooth/mgmt.c64
2 files changed, 60 insertions, 14 deletions
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 174a353a7dcf..00775c4fef83 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -817,6 +817,16 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
817 goto done; 817 goto done;
818 } 818 }
819 819
820 /* At the moment the index and unconfigured index events
821 * are enabled unconditionally. Setting them on each
822 * socket when binding keeps this functionality. They
823 * however might be cleared later and then sending of these
824 * events will be disabled, but that is then intentional.
825 */
826 if (haddr.hci_channel == HCI_CHANNEL_CONTROL) {
827 hci_sock_set_flag(sk, HCI_MGMT_INDEX_EVENTS);
828 hci_sock_set_flag(sk, HCI_MGMT_UNCONF_INDEX_EVENTS);
829 }
820 break; 830 break;
821 } 831 }
822 832
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index c58908652519..6b58c13b2b51 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -250,6 +250,33 @@ static int mgmt_send_event(u16 event, struct hci_dev *hdev,
250 return 0; 250 return 0;
251} 251}
252 252
253static int mgmt_index_event(u16 event, struct hci_dev *hdev,
254 void *data, u16 data_len, int flag)
255{
256 struct sk_buff *skb;
257 struct mgmt_hdr *hdr;
258
259 skb = alloc_skb(sizeof(*hdr) + data_len, GFP_KERNEL);
260 if (!skb)
261 return -ENOMEM;
262
263 hdr = (void *) skb_put(skb, sizeof(*hdr));
264 hdr->opcode = cpu_to_le16(event);
265 hdr->index = cpu_to_le16(hdev->id);
266 hdr->len = cpu_to_le16(data_len);
267
268 if (data)
269 memcpy(skb_put(skb, data_len), data, data_len);
270
271 /* Time stamp */
272 __net_timestamp(skb);
273
274 hci_send_to_flagged_channel(HCI_CHANNEL_CONTROL, skb, flag);
275 kfree_skb(skb);
276
277 return 0;
278}
279
253static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 len, 280static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 len,
254 struct sock *skip_sk) 281 struct sock *skip_sk)
255{ 282{
@@ -6343,34 +6370,43 @@ done:
6343 6370
6344void mgmt_index_added(struct hci_dev *hdev) 6371void mgmt_index_added(struct hci_dev *hdev)
6345{ 6372{
6346 if (hdev->dev_type != HCI_BREDR)
6347 return;
6348 6373
6349 if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 6374 if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
6350 return; 6375 return;
6351 6376
6352 if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 6377 switch (hdev->dev_type) {
6353 mgmt_event(MGMT_EV_UNCONF_INDEX_ADDED, hdev, NULL, 0, NULL); 6378 case HCI_BREDR:
6354 else 6379 if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
6355 mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL); 6380 mgmt_index_event(MGMT_EV_UNCONF_INDEX_ADDED, hdev,
6381 NULL, 0, HCI_MGMT_UNCONF_INDEX_EVENTS);
6382 } else {
6383 mgmt_index_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0,
6384 HCI_MGMT_INDEX_EVENTS);
6385 }
6386 break;
6387 }
6356} 6388}
6357 6389
6358void mgmt_index_removed(struct hci_dev *hdev) 6390void mgmt_index_removed(struct hci_dev *hdev)
6359{ 6391{
6360 u8 status = MGMT_STATUS_INVALID_INDEX; 6392 u8 status = MGMT_STATUS_INVALID_INDEX;
6361 6393
6362 if (hdev->dev_type != HCI_BREDR)
6363 return;
6364
6365 if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 6394 if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
6366 return; 6395 return;
6367 6396
6368 mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status); 6397 switch (hdev->dev_type) {
6398 case HCI_BREDR:
6399 mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status);
6369 6400
6370 if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 6401 if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
6371 mgmt_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0, NULL); 6402 mgmt_index_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev,
6372 else 6403 NULL, 0, HCI_MGMT_UNCONF_INDEX_EVENTS);
6373 mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL); 6404 } else {
6405 mgmt_index_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0,
6406 HCI_MGMT_INDEX_EVENTS);
6407 }
6408 break;
6409 }
6374} 6410}
6375 6411
6376/* This function requires the caller holds hdev->lock */ 6412/* This function requires the caller holds hdev->lock */