1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2020 Google Corporation
6 #include <net/bluetooth/bluetooth.h>
7 #include <net/bluetooth/hci_core.h>
8 #include <net/bluetooth/mgmt.h>
10 #include "hci_request.h"
11 #include "mgmt_util.h"
14 #define MSFT_RSSI_THRESHOLD_VALUE_MIN -127
15 #define MSFT_RSSI_THRESHOLD_VALUE_MAX 20
16 #define MSFT_RSSI_LOW_TIMEOUT_MAX 0x3C
18 #define MSFT_OP_READ_SUPPORTED_FEATURES 0x00
19 struct msft_cp_read_supported_features {
23 struct msft_rp_read_supported_features {
31 #define MSFT_OP_LE_MONITOR_ADVERTISEMENT 0x03
32 #define MSFT_MONITOR_ADVERTISEMENT_TYPE_PATTERN 0x01
33 struct msft_le_monitor_advertisement_pattern {
40 struct msft_le_monitor_advertisement_pattern_data {
45 struct msft_cp_le_monitor_advertisement {
49 __u8 rssi_low_interval;
50 __u8 rssi_sampling_period;
55 struct msft_rp_le_monitor_advertisement {
61 #define MSFT_OP_LE_CANCEL_MONITOR_ADVERTISEMENT 0x04
62 struct msft_cp_le_cancel_monitor_advertisement {
67 struct msft_rp_le_cancel_monitor_advertisement {
72 #define MSFT_OP_LE_SET_ADVERTISEMENT_FILTER_ENABLE 0x05
73 struct msft_cp_le_set_advertisement_filter_enable {
78 struct msft_rp_le_set_advertisement_filter_enable {
83 #define MSFT_EV_LE_MONITOR_DEVICE 0x02
84 struct msft_ev_le_monitor_device {
91 struct msft_monitor_advertisement_handle_data {
94 struct list_head list;
101 struct list_head handle_map;
102 __u16 pending_add_handle;
103 __u16 pending_remove_handle;
109 static int __msft_add_monitor_pattern(struct hci_dev *hdev,
110 struct adv_monitor *monitor);
111 static int __msft_remove_monitor(struct hci_dev *hdev,
112 struct adv_monitor *monitor, u16 handle);
114 bool msft_monitor_supported(struct hci_dev *hdev)
116 return !!(msft_get_features(hdev) & MSFT_FEATURE_MASK_LE_ADV_MONITOR);
119 static bool read_supported_features(struct hci_dev *hdev,
120 struct msft_data *msft)
122 struct msft_cp_read_supported_features cp;
123 struct msft_rp_read_supported_features *rp;
126 cp.sub_opcode = MSFT_OP_READ_SUPPORTED_FEATURES;
128 skb = __hci_cmd_sync(hdev, hdev->msft_opcode, sizeof(cp), &cp,
131 bt_dev_err(hdev, "Failed to read MSFT supported features (%ld)",
136 if (skb->len < sizeof(*rp)) {
137 bt_dev_err(hdev, "MSFT supported features length mismatch");
141 rp = (struct msft_rp_read_supported_features *)skb->data;
143 if (rp->sub_opcode != MSFT_OP_READ_SUPPORTED_FEATURES)
146 if (rp->evt_prefix_len > 0) {
147 msft->evt_prefix = kmemdup(rp->evt_prefix, rp->evt_prefix_len,
149 if (!msft->evt_prefix)
153 msft->evt_prefix_len = rp->evt_prefix_len;
154 msft->features = __le64_to_cpu(rp->features);
156 if (msft->features & MSFT_FEATURE_MASK_CURVE_VALIDITY)
157 hdev->msft_curve_validity = true;
167 static void reregister_monitor(struct hci_dev *hdev, int handle)
169 struct adv_monitor *monitor;
170 struct msft_data *msft = hdev->msft_data;
174 monitor = idr_get_next(&hdev->adv_monitors_idr, &handle);
176 /* All monitors have been resumed */
177 msft->resuming = false;
178 hci_update_passive_scan(hdev);
182 msft->pending_add_handle = (u16)handle;
183 err = __msft_add_monitor_pattern(hdev, monitor);
185 /* If success, we return and wait for monitor added callback */
189 /* Otherwise remove the monitor and keep registering */
190 hci_free_adv_monitor(hdev, monitor);
195 /* is_mgmt = true matches the handle exposed to userspace via mgmt.
196 * is_mgmt = false matches the handle used by the msft controller.
197 * This function requires the caller holds hdev->lock
199 static struct msft_monitor_advertisement_handle_data *msft_find_handle_data
200 (struct hci_dev *hdev, u16 handle, bool is_mgmt)
202 struct msft_monitor_advertisement_handle_data *entry;
203 struct msft_data *msft = hdev->msft_data;
205 list_for_each_entry(entry, &msft->handle_map, list) {
206 if (is_mgmt && entry->mgmt_handle == handle)
208 if (!is_mgmt && entry->msft_handle == handle)
215 /* This function requires the caller holds hdev->lock */
216 static int msft_monitor_device_del(struct hci_dev *hdev, __u16 mgmt_handle,
217 bdaddr_t *bdaddr, __u8 addr_type,
220 struct monitored_device *dev, *tmp;
223 list_for_each_entry_safe(dev, tmp, &hdev->monitored_devices, list) {
224 /* mgmt_handle == 0 indicates remove all devices, whereas,
225 * bdaddr == NULL indicates remove all devices matching the
228 if ((!mgmt_handle || dev->handle == mgmt_handle) &&
229 (!bdaddr || (!bacmp(bdaddr, &dev->bdaddr) &&
230 addr_type == dev->addr_type))) {
231 if (notify && dev->notified) {
232 mgmt_adv_monitor_device_lost(hdev, dev->handle,
237 list_del(&dev->list);
246 static void msft_le_monitor_advertisement_cb(struct hci_dev *hdev,
247 u8 status, u16 opcode,
250 struct msft_rp_le_monitor_advertisement *rp;
251 struct adv_monitor *monitor;
252 struct msft_monitor_advertisement_handle_data *handle_data;
253 struct msft_data *msft = hdev->msft_data;
257 monitor = idr_find(&hdev->adv_monitors_idr, msft->pending_add_handle);
259 bt_dev_err(hdev, "msft add advmon: monitor %u is not found!",
260 msft->pending_add_handle);
261 status = HCI_ERROR_UNSPECIFIED;
268 rp = (struct msft_rp_le_monitor_advertisement *)skb->data;
269 if (skb->len < sizeof(*rp)) {
270 status = HCI_ERROR_UNSPECIFIED;
274 handle_data = kmalloc(sizeof(*handle_data), GFP_KERNEL);
276 status = HCI_ERROR_UNSPECIFIED;
280 handle_data->mgmt_handle = monitor->handle;
281 handle_data->msft_handle = rp->handle;
282 INIT_LIST_HEAD(&handle_data->list);
283 list_add(&handle_data->list, &msft->handle_map);
285 monitor->state = ADV_MONITOR_STATE_OFFLOADED;
288 if (status && monitor)
289 hci_free_adv_monitor(hdev, monitor);
291 hci_dev_unlock(hdev);
294 hci_add_adv_patterns_monitor_complete(hdev, status);
297 static void msft_le_cancel_monitor_advertisement_cb(struct hci_dev *hdev,
298 u8 status, u16 opcode,
301 struct msft_cp_le_cancel_monitor_advertisement *cp;
302 struct msft_rp_le_cancel_monitor_advertisement *rp;
303 struct adv_monitor *monitor;
304 struct msft_monitor_advertisement_handle_data *handle_data;
305 struct msft_data *msft = hdev->msft_data;
312 rp = (struct msft_rp_le_cancel_monitor_advertisement *)skb->data;
313 if (skb->len < sizeof(*rp)) {
314 status = HCI_ERROR_UNSPECIFIED;
320 cp = hci_sent_cmd_data(hdev, hdev->msft_opcode);
321 handle_data = msft_find_handle_data(hdev, cp->handle, false);
324 monitor = idr_find(&hdev->adv_monitors_idr,
325 handle_data->mgmt_handle);
327 if (monitor && monitor->state == ADV_MONITOR_STATE_OFFLOADED)
328 monitor->state = ADV_MONITOR_STATE_REGISTERED;
330 /* Do not free the monitor if it is being removed due to
331 * suspend. It will be re-monitored on resume.
333 if (monitor && !msft->suspending) {
334 hci_free_adv_monitor(hdev, monitor);
336 /* Clear any monitored devices by this Adv Monitor */
337 msft_monitor_device_del(hdev, handle_data->mgmt_handle,
341 list_del(&handle_data->list);
345 /* If remove all monitors is required, we need to continue the process
346 * here because the earlier it was paused when waiting for the
347 * response from controller.
349 if (msft->pending_remove_handle == 0) {
350 pending = hci_remove_all_adv_monitor(hdev, &err);
352 hci_dev_unlock(hdev);
357 status = HCI_ERROR_UNSPECIFIED;
360 hci_dev_unlock(hdev);
363 if (!msft->suspending)
364 hci_remove_adv_monitor_complete(hdev, status);
367 static int msft_remove_monitor_sync(struct hci_dev *hdev,
368 struct adv_monitor *monitor)
370 struct msft_cp_le_cancel_monitor_advertisement cp;
371 struct msft_monitor_advertisement_handle_data *handle_data;
375 handle_data = msft_find_handle_data(hdev, monitor->handle, true);
377 /* If no matched handle, just remove without telling controller */
381 cp.sub_opcode = MSFT_OP_LE_CANCEL_MONITOR_ADVERTISEMENT;
382 cp.handle = handle_data->msft_handle;
384 skb = __hci_cmd_sync(hdev, hdev->msft_opcode, sizeof(cp), &cp,
389 status = skb->data[0];
392 msft_le_cancel_monitor_advertisement_cb(hdev, status, hdev->msft_opcode,
398 /* This function requires the caller holds hci_req_sync_lock */
399 int msft_suspend_sync(struct hci_dev *hdev)
401 struct msft_data *msft = hdev->msft_data;
402 struct adv_monitor *monitor;
405 if (!msft || !msft_monitor_supported(hdev))
408 msft->suspending = true;
411 monitor = idr_get_next(&hdev->adv_monitors_idr, &handle);
415 msft_remove_monitor_sync(hdev, monitor);
420 /* All monitors have been removed */
421 msft->suspending = false;
426 static bool msft_monitor_rssi_valid(struct adv_monitor *monitor)
428 struct adv_rssi_thresholds *r = &monitor->rssi;
430 if (r->high_threshold < MSFT_RSSI_THRESHOLD_VALUE_MIN ||
431 r->high_threshold > MSFT_RSSI_THRESHOLD_VALUE_MAX ||
432 r->low_threshold < MSFT_RSSI_THRESHOLD_VALUE_MIN ||
433 r->low_threshold > MSFT_RSSI_THRESHOLD_VALUE_MAX)
436 /* High_threshold_timeout is not supported,
437 * once high_threshold is reached, events are immediately reported.
439 if (r->high_threshold_timeout != 0)
442 if (r->low_threshold_timeout > MSFT_RSSI_LOW_TIMEOUT_MAX)
445 /* Sampling period from 0x00 to 0xFF are all allowed */
449 static bool msft_monitor_pattern_valid(struct adv_monitor *monitor)
451 return msft_monitor_rssi_valid(monitor);
452 /* No additional check needed for pattern-based monitor */
455 static int msft_add_monitor_sync(struct hci_dev *hdev,
456 struct adv_monitor *monitor)
458 struct msft_cp_le_monitor_advertisement *cp;
459 struct msft_le_monitor_advertisement_pattern_data *pattern_data;
460 struct msft_le_monitor_advertisement_pattern *pattern;
461 struct adv_pattern *entry;
462 size_t total_size = sizeof(*cp) + sizeof(*pattern_data);
463 ptrdiff_t offset = 0;
464 u8 pattern_count = 0;
468 if (!msft_monitor_pattern_valid(monitor))
471 list_for_each_entry(entry, &monitor->patterns, list) {
473 total_size += sizeof(*pattern) + entry->length;
476 cp = kmalloc(total_size, GFP_KERNEL);
480 cp->sub_opcode = MSFT_OP_LE_MONITOR_ADVERTISEMENT;
481 cp->rssi_high = monitor->rssi.high_threshold;
482 cp->rssi_low = monitor->rssi.low_threshold;
483 cp->rssi_low_interval = (u8)monitor->rssi.low_threshold_timeout;
484 cp->rssi_sampling_period = monitor->rssi.sampling_period;
486 cp->cond_type = MSFT_MONITOR_ADVERTISEMENT_TYPE_PATTERN;
488 pattern_data = (void *)cp->data;
489 pattern_data->count = pattern_count;
491 list_for_each_entry(entry, &monitor->patterns, list) {
492 pattern = (void *)(pattern_data->data + offset);
493 /* the length also includes data_type and offset */
494 pattern->length = entry->length + 2;
495 pattern->data_type = entry->ad_type;
496 pattern->start_byte = entry->offset;
497 memcpy(pattern->pattern, entry->value, entry->length);
498 offset += sizeof(*pattern) + entry->length;
501 skb = __hci_cmd_sync(hdev, hdev->msft_opcode, total_size, cp,
508 status = skb->data[0];
511 msft_le_monitor_advertisement_cb(hdev, status, hdev->msft_opcode, skb);
516 /* This function requires the caller holds hci_req_sync_lock */
517 int msft_resume_sync(struct hci_dev *hdev)
519 struct msft_data *msft = hdev->msft_data;
520 struct adv_monitor *monitor;
523 if (!msft || !msft_monitor_supported(hdev))
528 /* Clear already tracked devices on resume. Once the monitors are
529 * reregistered, devices in range will be found again after resume.
531 hdev->advmon_pend_notify = false;
532 msft_monitor_device_del(hdev, 0, NULL, 0, true);
534 hci_dev_unlock(hdev);
536 msft->resuming = true;
539 monitor = idr_get_next(&hdev->adv_monitors_idr, &handle);
543 msft_add_monitor_sync(hdev, monitor);
548 /* All monitors have been resumed */
549 msft->resuming = false;
554 void msft_do_open(struct hci_dev *hdev)
556 struct msft_data *msft = hdev->msft_data;
558 if (hdev->msft_opcode == HCI_OP_NOP)
562 bt_dev_err(hdev, "MSFT extension not registered");
566 bt_dev_dbg(hdev, "Initialize MSFT extension");
568 /* Reset existing MSFT data before re-reading */
569 kfree(msft->evt_prefix);
570 msft->evt_prefix = NULL;
571 msft->evt_prefix_len = 0;
574 if (!read_supported_features(hdev, msft)) {
575 hdev->msft_data = NULL;
580 if (msft_monitor_supported(hdev)) {
581 msft->resuming = true;
582 msft_set_filter_enable(hdev, true);
583 /* Monitors get removed on power off, so we need to explicitly
584 * tell the controller to re-monitor.
586 reregister_monitor(hdev, 0);
590 void msft_do_close(struct hci_dev *hdev)
592 struct msft_data *msft = hdev->msft_data;
593 struct msft_monitor_advertisement_handle_data *handle_data, *tmp;
594 struct adv_monitor *monitor;
599 bt_dev_dbg(hdev, "Cleanup of MSFT extension");
601 /* The controller will silently remove all monitors on power off.
602 * Therefore, remove handle_data mapping and reset monitor state.
604 list_for_each_entry_safe(handle_data, tmp, &msft->handle_map, list) {
605 monitor = idr_find(&hdev->adv_monitors_idr,
606 handle_data->mgmt_handle);
608 if (monitor && monitor->state == ADV_MONITOR_STATE_OFFLOADED)
609 monitor->state = ADV_MONITOR_STATE_REGISTERED;
611 list_del(&handle_data->list);
617 /* Clear any devices that are being monitored and notify device lost */
618 hdev->advmon_pend_notify = false;
619 msft_monitor_device_del(hdev, 0, NULL, 0, true);
621 hci_dev_unlock(hdev);
624 void msft_register(struct hci_dev *hdev)
626 struct msft_data *msft = NULL;
628 bt_dev_dbg(hdev, "Register MSFT extension");
630 msft = kzalloc(sizeof(*msft), GFP_KERNEL);
632 bt_dev_err(hdev, "Failed to register MSFT extension");
636 INIT_LIST_HEAD(&msft->handle_map);
637 hdev->msft_data = msft;
640 void msft_unregister(struct hci_dev *hdev)
642 struct msft_data *msft = hdev->msft_data;
647 bt_dev_dbg(hdev, "Unregister MSFT extension");
649 hdev->msft_data = NULL;
651 kfree(msft->evt_prefix);
655 /* This function requires the caller holds hdev->lock */
656 static void msft_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr,
657 __u8 addr_type, __u16 mgmt_handle)
659 struct monitored_device *dev;
661 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
663 bt_dev_err(hdev, "MSFT vendor event %u: no memory",
664 MSFT_EV_LE_MONITOR_DEVICE);
668 bacpy(&dev->bdaddr, bdaddr);
669 dev->addr_type = addr_type;
670 dev->handle = mgmt_handle;
671 dev->notified = false;
673 INIT_LIST_HEAD(&dev->list);
674 list_add(&dev->list, &hdev->monitored_devices);
675 hdev->advmon_pend_notify = true;
678 /* This function requires the caller holds hdev->lock */
679 static void msft_device_lost(struct hci_dev *hdev, bdaddr_t *bdaddr,
680 __u8 addr_type, __u16 mgmt_handle)
682 if (!msft_monitor_device_del(hdev, mgmt_handle, bdaddr, addr_type,
684 bt_dev_err(hdev, "MSFT vendor event %u: dev %pMR not in list",
685 MSFT_EV_LE_MONITOR_DEVICE, bdaddr);
689 static void *msft_skb_pull(struct hci_dev *hdev, struct sk_buff *skb,
694 data = skb_pull_data(skb, len);
696 bt_dev_err(hdev, "Malformed MSFT vendor event: 0x%02x", ev);
701 /* This function requires the caller holds hdev->lock */
702 static void msft_monitor_device_evt(struct hci_dev *hdev, struct sk_buff *skb)
704 struct msft_ev_le_monitor_device *ev;
705 struct msft_monitor_advertisement_handle_data *handle_data;
708 ev = msft_skb_pull(hdev, skb, MSFT_EV_LE_MONITOR_DEVICE, sizeof(*ev));
713 "MSFT vendor event 0x%02x: handle 0x%04x state %d addr %pMR",
714 MSFT_EV_LE_MONITOR_DEVICE, ev->monitor_handle,
715 ev->monitor_state, &ev->bdaddr);
717 handle_data = msft_find_handle_data(hdev, ev->monitor_handle, false);
721 switch (ev->addr_type) {
722 case ADDR_LE_DEV_PUBLIC:
723 addr_type = BDADDR_LE_PUBLIC;
726 case ADDR_LE_DEV_RANDOM:
727 addr_type = BDADDR_LE_RANDOM;
732 "MSFT vendor event 0x%02x: unknown addr type 0x%02x",
733 MSFT_EV_LE_MONITOR_DEVICE, ev->addr_type);
737 if (ev->monitor_state)
738 msft_device_found(hdev, &ev->bdaddr, addr_type,
739 handle_data->mgmt_handle);
741 msft_device_lost(hdev, &ev->bdaddr, addr_type,
742 handle_data->mgmt_handle);
745 void msft_vendor_evt(struct hci_dev *hdev, void *data, struct sk_buff *skb)
747 struct msft_data *msft = hdev->msft_data;
754 /* When the extension has defined an event prefix, check that it
755 * matches, and otherwise just return.
757 if (msft->evt_prefix_len > 0) {
758 evt_prefix = msft_skb_pull(hdev, skb, 0, msft->evt_prefix_len);
762 if (memcmp(evt_prefix, msft->evt_prefix, msft->evt_prefix_len))
766 /* Every event starts at least with an event code and the rest of
767 * the data is variable and depends on the event code.
772 evt = msft_skb_pull(hdev, skb, 0, sizeof(*evt));
779 case MSFT_EV_LE_MONITOR_DEVICE:
780 msft_monitor_device_evt(hdev, skb);
784 bt_dev_dbg(hdev, "MSFT vendor event 0x%02x", *evt);
788 hci_dev_unlock(hdev);
791 __u64 msft_get_features(struct hci_dev *hdev)
793 struct msft_data *msft = hdev->msft_data;
795 return msft ? msft->features : 0;
798 static void msft_le_set_advertisement_filter_enable_cb(struct hci_dev *hdev,
799 u8 status, u16 opcode,
802 struct msft_cp_le_set_advertisement_filter_enable *cp;
803 struct msft_rp_le_set_advertisement_filter_enable *rp;
804 struct msft_data *msft = hdev->msft_data;
806 rp = (struct msft_rp_le_set_advertisement_filter_enable *)skb->data;
807 if (skb->len < sizeof(*rp))
810 /* Error 0x0C would be returned if the filter enabled status is
811 * already set to whatever we were trying to set.
812 * Although the default state should be disabled, some controller set
813 * the initial value to enabled. Because there is no way to know the
814 * actual initial value before sending this command, here we also treat
815 * error 0x0C as success.
817 if (status != 0x00 && status != 0x0C)
822 cp = hci_sent_cmd_data(hdev, hdev->msft_opcode);
823 msft->filter_enabled = cp->enable;
826 bt_dev_warn(hdev, "MSFT filter_enable is already %s",
827 cp->enable ? "on" : "off");
829 hci_dev_unlock(hdev);
832 /* This function requires the caller holds hdev->lock */
833 static int __msft_add_monitor_pattern(struct hci_dev *hdev,
834 struct adv_monitor *monitor)
836 struct msft_cp_le_monitor_advertisement *cp;
837 struct msft_le_monitor_advertisement_pattern_data *pattern_data;
838 struct msft_le_monitor_advertisement_pattern *pattern;
839 struct adv_pattern *entry;
840 struct hci_request req;
841 struct msft_data *msft = hdev->msft_data;
842 size_t total_size = sizeof(*cp) + sizeof(*pattern_data);
843 ptrdiff_t offset = 0;
844 u8 pattern_count = 0;
847 if (!msft_monitor_pattern_valid(monitor))
850 list_for_each_entry(entry, &monitor->patterns, list) {
852 total_size += sizeof(*pattern) + entry->length;
855 cp = kmalloc(total_size, GFP_KERNEL);
859 cp->sub_opcode = MSFT_OP_LE_MONITOR_ADVERTISEMENT;
860 cp->rssi_high = monitor->rssi.high_threshold;
861 cp->rssi_low = monitor->rssi.low_threshold;
862 cp->rssi_low_interval = (u8)monitor->rssi.low_threshold_timeout;
863 cp->rssi_sampling_period = monitor->rssi.sampling_period;
865 cp->cond_type = MSFT_MONITOR_ADVERTISEMENT_TYPE_PATTERN;
867 pattern_data = (void *)cp->data;
868 pattern_data->count = pattern_count;
870 list_for_each_entry(entry, &monitor->patterns, list) {
871 pattern = (void *)(pattern_data->data + offset);
872 /* the length also includes data_type and offset */
873 pattern->length = entry->length + 2;
874 pattern->data_type = entry->ad_type;
875 pattern->start_byte = entry->offset;
876 memcpy(pattern->pattern, entry->value, entry->length);
877 offset += sizeof(*pattern) + entry->length;
880 hci_req_init(&req, hdev);
881 hci_req_add(&req, hdev->msft_opcode, total_size, cp);
882 err = hci_req_run_skb(&req, msft_le_monitor_advertisement_cb);
886 msft->pending_add_handle = monitor->handle;
891 /* This function requires the caller holds hdev->lock */
892 int msft_add_monitor_pattern(struct hci_dev *hdev, struct adv_monitor *monitor)
894 struct msft_data *msft = hdev->msft_data;
899 if (msft->resuming || msft->suspending)
902 return __msft_add_monitor_pattern(hdev, monitor);
905 /* This function requires the caller holds hdev->lock */
906 static int __msft_remove_monitor(struct hci_dev *hdev,
907 struct adv_monitor *monitor, u16 handle)
909 struct msft_cp_le_cancel_monitor_advertisement cp;
910 struct msft_monitor_advertisement_handle_data *handle_data;
911 struct hci_request req;
912 struct msft_data *msft = hdev->msft_data;
915 handle_data = msft_find_handle_data(hdev, monitor->handle, true);
917 /* If no matched handle, just remove without telling controller */
921 cp.sub_opcode = MSFT_OP_LE_CANCEL_MONITOR_ADVERTISEMENT;
922 cp.handle = handle_data->msft_handle;
924 hci_req_init(&req, hdev);
925 hci_req_add(&req, hdev->msft_opcode, sizeof(cp), &cp);
926 err = hci_req_run_skb(&req, msft_le_cancel_monitor_advertisement_cb);
929 msft->pending_remove_handle = handle;
934 /* This function requires the caller holds hdev->lock */
935 int msft_remove_monitor(struct hci_dev *hdev, struct adv_monitor *monitor,
938 struct msft_data *msft = hdev->msft_data;
943 if (msft->resuming || msft->suspending)
946 return __msft_remove_monitor(hdev, monitor, handle);
949 void msft_req_add_set_filter_enable(struct hci_request *req, bool enable)
951 struct hci_dev *hdev = req->hdev;
952 struct msft_cp_le_set_advertisement_filter_enable cp;
954 cp.sub_opcode = MSFT_OP_LE_SET_ADVERTISEMENT_FILTER_ENABLE;
957 hci_req_add(req, hdev->msft_opcode, sizeof(cp), &cp);
960 int msft_set_filter_enable(struct hci_dev *hdev, bool enable)
962 struct hci_request req;
963 struct msft_data *msft = hdev->msft_data;
969 hci_req_init(&req, hdev);
970 msft_req_add_set_filter_enable(&req, enable);
971 err = hci_req_run_skb(&req, msft_le_set_advertisement_filter_enable_cb);
976 bool msft_curve_validity(struct hci_dev *hdev)
978 return hdev->msft_curve_validity;