aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2014-12-05 04:55:57 -0500
committerJohan Hedberg <johan.hedberg@intel.com>2014-12-05 05:37:35 -0500
commitb487b9ce9340a6e98d7f8277399304b23b7be456 (patch)
tree97d5dae05e0cdc97a037f1ce932b8c220e5cbfc3 /net/bluetooth
parentbda157a40077447b25a1172a17b8ef81a2905cb7 (diff)
Bluetooth: Add framework for device found filtering based on UUID
Using Start Service Discovery provides the option to specifiy a list of UUID that are used to filter out device found events. This patch provides the framework for hooking up the UUID filter. 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/mgmt.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 1715c91dfa28..e39190a51590 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -6802,6 +6802,11 @@ void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192,
6802 mgmt_pending_remove(cmd); 6802 mgmt_pending_remove(cmd);
6803} 6803}
6804 6804
6805static bool eir_has_uuids(u8 *eir, u16 eir_len, u16 uuid_count, u8 (*uuids)[16])
6806{
6807 return false;
6808}
6809
6805void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 6810void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
6806 u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, 6811 u8 addr_type, u8 *dev_class, s8 rssi, u32 flags,
6807 u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len) 6812 u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len)
@@ -6809,6 +6814,7 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
6809 char buf[512]; 6814 char buf[512];
6810 struct mgmt_ev_device_found *ev = (void *) buf; 6815 struct mgmt_ev_device_found *ev = (void *) buf;
6811 size_t ev_size; 6816 size_t ev_size;
6817 bool match;
6812 6818
6813 /* Don't send events for a non-kernel initiated discovery. With 6819 /* Don't send events for a non-kernel initiated discovery. With
6814 * LE one exception is if we have pend_le_reports > 0 in which 6820 * LE one exception is if we have pend_le_reports > 0 in which
@@ -6843,15 +6849,59 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
6843 ev->rssi = rssi; 6849 ev->rssi = rssi;
6844 ev->flags = cpu_to_le32(flags); 6850 ev->flags = cpu_to_le32(flags);
6845 6851
6846 if (eir_len > 0) 6852 if (eir_len > 0) {
6853 /* When using service discovery and a list of UUID is
6854 * provided, results with no matching UUID should be
6855 * dropped. In case there is a match the result is
6856 * kept and checking possible scan response data
6857 * will be skipped.
6858 */
6859 if (hdev->discovery.uuid_count > 0) {
6860 match = eir_has_uuids(eir, eir_len,
6861 hdev->discovery.uuid_count,
6862 hdev->discovery.uuids);
6863 if (!match)
6864 return;
6865 }
6866
6867 /* Copy EIR or advertising data into event */
6847 memcpy(ev->eir, eir, eir_len); 6868 memcpy(ev->eir, eir, eir_len);
6869 } else {
6870 /* When using service discovery and a list of UUID is
6871 * provided, results with empty EIR or advertising data
6872 * should be dropped since they do not match any UUID.
6873 */
6874 if (hdev->discovery.uuid_count > 0)
6875 return;
6876 }
6848 6877
6849 if (dev_class && !eir_has_data_type(ev->eir, eir_len, EIR_CLASS_OF_DEV)) 6878 if (dev_class && !eir_has_data_type(ev->eir, eir_len, EIR_CLASS_OF_DEV))
6850 eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV, 6879 eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV,
6851 dev_class, 3); 6880 dev_class, 3);
6852 6881
6853 if (scan_rsp_len > 0) 6882 if (scan_rsp_len > 0) {
6883 /* When using service discovery and a list of UUID is
6884 * provided, results with no matching UUID should be
6885 * dropped if there is no previous match from the
6886 * advertising data.
6887 */
6888 if (hdev->discovery.uuid_count > 0) {
6889 if (!match && !eir_has_uuids(scan_rsp, scan_rsp_len,
6890 hdev->discovery.uuid_count,
6891 hdev->discovery.uuids))
6892 return;
6893 }
6894
6895 /* Append scan response data to event */
6854 memcpy(ev->eir + eir_len, scan_rsp, scan_rsp_len); 6896 memcpy(ev->eir + eir_len, scan_rsp, scan_rsp_len);
6897 } else {
6898 /* When using service discovery and a list of UUID is
6899 * provided, results with empty scan response and no
6900 * previous matched advertising data should be dropped.
6901 */
6902 if (hdev->discovery.uuid_count > 0 && !match)
6903 return;
6904 }
6855 6905
6856 ev->eir_len = cpu_to_le16(eir_len + scan_rsp_len); 6906 ev->eir_len = cpu_to_le16(eir_len + scan_rsp_len);
6857 ev_size = sizeof(*ev) + eir_len + scan_rsp_len; 6907 ev_size = sizeof(*ev) + eir_len + scan_rsp_len;