Bluetooth: Add handler of MGMT_OP_REMOVE_ADV_MONITOR
This adds the request handler of MGMT_OP_REMOVE_ADV_MONITOR command. Note that the controller-based monitoring is not yet in place. This removes the internal monitor(s) without sending HCI traffic, so the request returns immediately. The following test was performed. - Issue btmgmt advmon-remove with valid and invalid handles. Signed-off-by: Miao-chen Chou <mcchou@chromium.org> Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
committed by
Johan Hedberg
parent
b139553db5
commit
bd2fbc6cb8
@ -1283,6 +1283,7 @@ void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired);
|
|||||||
void hci_adv_monitors_clear(struct hci_dev *hdev);
|
void hci_adv_monitors_clear(struct hci_dev *hdev);
|
||||||
void hci_free_adv_monitor(struct adv_monitor *monitor);
|
void hci_free_adv_monitor(struct adv_monitor *monitor);
|
||||||
int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor);
|
int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor);
|
||||||
|
int hci_remove_adv_monitor(struct hci_dev *hdev, u16 handle);
|
||||||
|
|
||||||
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
|
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
|
||||||
|
|
||||||
|
@ -3041,6 +3041,37 @@ int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int free_adv_monitor(int id, void *ptr, void *data)
|
||||||
|
{
|
||||||
|
struct hci_dev *hdev = data;
|
||||||
|
struct adv_monitor *monitor = ptr;
|
||||||
|
|
||||||
|
idr_remove(&hdev->adv_monitors_idr, monitor->handle);
|
||||||
|
hci_free_adv_monitor(monitor);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function requires the caller holds hdev->lock */
|
||||||
|
int hci_remove_adv_monitor(struct hci_dev *hdev, u16 handle)
|
||||||
|
{
|
||||||
|
struct adv_monitor *monitor;
|
||||||
|
|
||||||
|
if (handle) {
|
||||||
|
monitor = idr_find(&hdev->adv_monitors_idr, handle);
|
||||||
|
if (!monitor)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
idr_remove(&hdev->adv_monitors_idr, monitor->handle);
|
||||||
|
hci_free_adv_monitor(monitor);
|
||||||
|
} else {
|
||||||
|
/* Remove all monitors if handle is 0. */
|
||||||
|
idr_for_each(&hdev->adv_monitors_idr, &free_adv_monitor, hdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
|
struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
|
||||||
bdaddr_t *bdaddr, u8 type)
|
bdaddr_t *bdaddr, u8 type)
|
||||||
{
|
{
|
||||||
|
@ -121,6 +121,7 @@ static const u16 mgmt_commands[] = {
|
|||||||
MGMT_OP_SET_DEVICE_FLAGS,
|
MGMT_OP_SET_DEVICE_FLAGS,
|
||||||
MGMT_OP_READ_ADV_MONITOR_FEATURES,
|
MGMT_OP_READ_ADV_MONITOR_FEATURES,
|
||||||
MGMT_OP_ADD_ADV_PATTERNS_MONITOR,
|
MGMT_OP_ADD_ADV_PATTERNS_MONITOR,
|
||||||
|
MGMT_OP_REMOVE_ADV_MONITOR,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u16 mgmt_events[] = {
|
static const u16 mgmt_events[] = {
|
||||||
@ -4118,6 +4119,39 @@ failed:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev,
|
||||||
|
void *data, u16 len)
|
||||||
|
{
|
||||||
|
struct mgmt_cp_remove_adv_monitor *cp = data;
|
||||||
|
struct mgmt_rp_remove_adv_monitor rp;
|
||||||
|
u16 handle;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
BT_DBG("request for %s", hdev->name);
|
||||||
|
|
||||||
|
hci_dev_lock(hdev);
|
||||||
|
|
||||||
|
handle = __le16_to_cpu(cp->monitor_handle);
|
||||||
|
|
||||||
|
err = hci_remove_adv_monitor(hdev, handle);
|
||||||
|
if (err == -ENOENT) {
|
||||||
|
err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_REMOVE_ADV_MONITOR,
|
||||||
|
MGMT_STATUS_INVALID_INDEX);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
hci_dev_unlock(hdev);
|
||||||
|
|
||||||
|
rp.monitor_handle = cp->monitor_handle;
|
||||||
|
|
||||||
|
return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_ADV_MONITOR,
|
||||||
|
MGMT_STATUS_SUCCESS, &rp, sizeof(rp));
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
hci_dev_unlock(hdev);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
|
static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
|
||||||
u16 opcode, struct sk_buff *skb)
|
u16 opcode, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
@ -7589,6 +7623,7 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
|
|||||||
{ read_adv_mon_features, MGMT_READ_ADV_MONITOR_FEATURES_SIZE },
|
{ read_adv_mon_features, MGMT_READ_ADV_MONITOR_FEATURES_SIZE },
|
||||||
{ add_adv_patterns_monitor,MGMT_ADD_ADV_PATTERNS_MONITOR_SIZE,
|
{ add_adv_patterns_monitor,MGMT_ADD_ADV_PATTERNS_MONITOR_SIZE,
|
||||||
HCI_MGMT_VAR_LEN },
|
HCI_MGMT_VAR_LEN },
|
||||||
|
{ remove_adv_monitor, MGMT_REMOVE_ADV_MONITOR_SIZE },
|
||||||
};
|
};
|
||||||
|
|
||||||
void mgmt_index_added(struct hci_dev *hdev)
|
void mgmt_index_added(struct hci_dev *hdev)
|
||||||
|
Reference in New Issue
Block a user