Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Bluetooth: Send AdvMonitor Dev Found for all matched devices

When an Advertisement Monitor is configured with SamplingPeriod 0xFF,
the controller reports only one adv report along with the MSFT Monitor
Device event.

When an advertiser matches multiple monitors, some controllers send one
adv report for each matched monitor; whereas, some controllers send just
one adv report for all matched monitors.

In such a case, report Adv Monitor Device Found event for each matched
monitor.

Signed-off-by: Manish Mandlik <mmandlik@google.com>
Reviewed-by: Miao-chen Chou <mcchou@chromium.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>

authored by

Manish Mandlik and committed by
Marcel Holtmann
ff39fc1b 37b63c68

+37 -33
+37 -33
net/bluetooth/mgmt.c
··· 9628 9628 NULL); 9629 9629 } 9630 9630 9631 + static void mgmt_send_adv_monitor_device_found(struct hci_dev *hdev, 9632 + struct sk_buff *skb, 9633 + struct sock *skip_sk, 9634 + u16 handle) 9635 + { 9636 + struct sk_buff *advmon_skb; 9637 + size_t advmon_skb_len; 9638 + __le16 *monitor_handle; 9639 + 9640 + if (!skb) 9641 + return; 9642 + 9643 + advmon_skb_len = (sizeof(struct mgmt_ev_adv_monitor_device_found) - 9644 + sizeof(struct mgmt_ev_device_found)) + skb->len; 9645 + advmon_skb = mgmt_alloc_skb(hdev, MGMT_EV_ADV_MONITOR_DEVICE_FOUND, 9646 + advmon_skb_len); 9647 + if (!advmon_skb) 9648 + return; 9649 + 9650 + /* ADV_MONITOR_DEVICE_FOUND is similar to DEVICE_FOUND event except 9651 + * that it also has 'monitor_handle'. Make a copy of DEVICE_FOUND and 9652 + * store monitor_handle of the matched monitor. 9653 + */ 9654 + monitor_handle = skb_put(advmon_skb, sizeof(*monitor_handle)); 9655 + *monitor_handle = cpu_to_le16(handle); 9656 + skb_put_data(advmon_skb, skb->data, skb->len); 9657 + 9658 + mgmt_event_skb(advmon_skb, skip_sk); 9659 + } 9660 + 9631 9661 static void mgmt_adv_monitor_device_found(struct hci_dev *hdev, 9632 9662 bdaddr_t *bdaddr, bool report_device, 9633 9663 struct sk_buff *skb, 9634 9664 struct sock *skip_sk) 9635 9665 { 9636 - struct sk_buff *advmon_skb; 9637 - size_t advmon_skb_len; 9638 - __le16 *monitor_handle; 9639 9666 struct monitored_device *dev, *tmp; 9640 9667 bool matched = false; 9641 - bool notify = false; 9668 + bool notified = false; 9642 9669 9643 9670 /* We have received the Advertisement Report because: 9644 9671 * 1. the kernel has initiated active discovery ··· 9687 9660 return; 9688 9661 } 9689 9662 9690 - advmon_skb_len = (sizeof(struct mgmt_ev_adv_monitor_device_found) - 9691 - sizeof(struct mgmt_ev_device_found)) + skb->len; 9692 - advmon_skb = mgmt_alloc_skb(hdev, MGMT_EV_ADV_MONITOR_DEVICE_FOUND, 9693 - advmon_skb_len); 9694 - if (!advmon_skb) { 9695 - if (report_device) 9696 - mgmt_event_skb(skb, skip_sk); 9697 - else 9698 - kfree_skb(skb); 9699 - return; 9700 - } 9701 - 9702 - /* ADV_MONITOR_DEVICE_FOUND is similar to DEVICE_FOUND event except 9703 - * that it also has 'monitor_handle'. Make a copy of DEVICE_FOUND and 9704 - * store monitor_handle of the matched monitor. 9705 - */ 9706 - monitor_handle = skb_put(advmon_skb, sizeof(*monitor_handle)); 9707 - skb_put_data(advmon_skb, skb->data, skb->len); 9708 - 9709 9663 hdev->advmon_pend_notify = false; 9710 9664 9711 9665 list_for_each_entry_safe(dev, tmp, &hdev->monitored_devices, list) { ··· 9694 9686 matched = true; 9695 9687 9696 9688 if (!dev->notified) { 9697 - *monitor_handle = cpu_to_le16(dev->handle); 9698 - notify = true; 9689 + mgmt_send_adv_monitor_device_found(hdev, skb, 9690 + skip_sk, 9691 + dev->handle); 9692 + notified = true; 9699 9693 dev->notified = true; 9700 9694 } 9701 9695 } ··· 9707 9697 } 9708 9698 9709 9699 if (!report_device && 9710 - ((matched && !notify) || !msft_monitor_supported(hdev))) { 9700 + ((matched && !notified) || !msft_monitor_supported(hdev))) { 9711 9701 /* Handle 0 indicates that we are not active scanning and this 9712 9702 * is a subsequent advertisement report for an already matched 9713 9703 * Advertisement Monitor or the controller offloading support 9714 9704 * is not available. 9715 9705 */ 9716 - *monitor_handle = 0; 9717 - notify = true; 9706 + mgmt_send_adv_monitor_device_found(hdev, skb, skip_sk, 0); 9718 9707 } 9719 9708 9720 9709 if (report_device) 9721 9710 mgmt_event_skb(skb, skip_sk); 9722 9711 else 9723 9712 kfree_skb(skb); 9724 - 9725 - if (notify) 9726 - mgmt_event_skb(advmon_skb, skip_sk); 9727 - else 9728 - kfree_skb(advmon_skb); 9729 9713 } 9730 9714 9731 9715 void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,