Skip to content

Commit

Permalink
Bluetooth: hci_sync: Refactor add Adv Monitor
Browse files Browse the repository at this point in the history
Make use of hci_cmd_sync_queue for adding an advertisement monitor.

Signed-off-by: Manish Mandlik <mmandlik@google.com>
Reviewed-by: Miao-chen Chou <mcchou@google.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  • Loading branch information
liveusr authored and Vudentz committed Jul 22, 2022
1 parent 63b1a7d commit b747a83
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 196 deletions.
5 changes: 1 addition & 4 deletions include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1420,10 +1420,8 @@ bool hci_adv_instance_is_scannable(struct hci_dev *hdev, u8 instance);

void hci_adv_monitors_clear(struct hci_dev *hdev);
void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor);
int hci_add_adv_patterns_monitor_complete(struct hci_dev *hdev, u8 status);
int hci_remove_adv_monitor_complete(struct hci_dev *hdev, u8 status);
bool hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor,
int *err);
int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor);
bool hci_remove_single_adv_monitor(struct hci_dev *hdev, u16 handle, int *err);
bool hci_remove_all_adv_monitor(struct hci_dev *hdev, int *err);
bool hci_is_adv_monitoring(struct hci_dev *hdev);
Expand Down Expand Up @@ -1885,7 +1883,6 @@ void mgmt_advertising_removed(struct sock *sk, struct hci_dev *hdev,
u8 instance);
void mgmt_adv_monitor_removed(struct hci_dev *hdev, u16 handle);
int mgmt_phy_configuration_changed(struct hci_dev *hdev, struct sock *skip);
int mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev, u8 status);
int mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, u8 status);
void mgmt_adv_monitor_device_lost(struct hci_dev *hdev, u16 handle,
bdaddr_t *bdaddr, u8 addr_type);
Expand Down
46 changes: 20 additions & 26 deletions net/bluetooth/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1880,61 +1880,55 @@ void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
kfree(monitor);
}

int hci_add_adv_patterns_monitor_complete(struct hci_dev *hdev, u8 status)
{
return mgmt_add_adv_patterns_monitor_complete(hdev, status);
}

int hci_remove_adv_monitor_complete(struct hci_dev *hdev, u8 status)
{
return mgmt_remove_adv_monitor_complete(hdev, status);
}

/* Assigns handle to a monitor, and if offloading is supported and power is on,
* also attempts to forward the request to the controller.
* Returns true if request is forwarded (result is pending), false otherwise.
* This function requires the caller holds hdev->lock.
* This function requires the caller holds hci_req_sync_lock.
*/
bool hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor,
int *err)
int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
{
int min, max, handle;
int status = 0;

*err = 0;
if (!monitor)
return -EINVAL;

if (!monitor) {
*err = -EINVAL;
return false;
}
hci_dev_lock(hdev);

min = HCI_MIN_ADV_MONITOR_HANDLE;
max = HCI_MIN_ADV_MONITOR_HANDLE + HCI_MAX_ADV_MONITOR_NUM_HANDLES;
handle = idr_alloc(&hdev->adv_monitors_idr, monitor, min, max,
GFP_KERNEL);
if (handle < 0) {
*err = handle;
return false;
}

hci_dev_unlock(hdev);

if (handle < 0)
return handle;

monitor->handle = handle;

if (!hdev_is_powered(hdev))
return false;
return status;

switch (hci_get_adv_monitor_offload_ext(hdev)) {
case HCI_ADV_MONITOR_EXT_NONE:
hci_update_passive_scan(hdev);
bt_dev_dbg(hdev, "%s add monitor status %d", hdev->name, *err);
bt_dev_dbg(hdev, "%s add monitor %d status %d", hdev->name,
monitor->handle, status);
/* Message was not forwarded to controller - not an error */
return false;
break;

case HCI_ADV_MONITOR_EXT_MSFT:
*err = msft_add_monitor_pattern(hdev, monitor);
bt_dev_dbg(hdev, "%s add monitor msft status %d", hdev->name,
*err);
status = msft_add_monitor_pattern(hdev, monitor);
bt_dev_dbg(hdev, "%s add monitor %d msft status %d", hdev->name,
monitor->handle, status);
break;
}

return (*err == 0);
return status;
}

/* Attempts to tell the controller and free the monitor. If somehow the
Expand Down
52 changes: 17 additions & 35 deletions net/bluetooth/mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -4646,23 +4646,15 @@ static int read_adv_mon_features(struct sock *sk, struct hci_dev *hdev,
return err;
}

int mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev, u8 status)
static void mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev,
void *data, int status)
{
struct mgmt_rp_add_adv_patterns_monitor rp;
struct mgmt_pending_cmd *cmd;
struct adv_monitor *monitor;
int err = 0;
struct mgmt_pending_cmd *cmd = data;
struct adv_monitor *monitor = cmd->user_data;

hci_dev_lock(hdev);

cmd = pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev);
if (!cmd) {
cmd = pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR, hdev);
if (!cmd)
goto done;
}

monitor = cmd->user_data;
rp.monitor_handle = cpu_to_le16(monitor->handle);

if (!status) {
Expand All @@ -4673,26 +4665,29 @@ int mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev, u8 status)
hci_update_passive_scan(hdev);
}

err = mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
mgmt_status(status), &rp, sizeof(rp));
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
mgmt_status(status), &rp, sizeof(rp));
mgmt_pending_remove(cmd);

done:
hci_dev_unlock(hdev);
bt_dev_dbg(hdev, "add monitor %d complete, status %u",
bt_dev_dbg(hdev, "add monitor %d complete, status %d",
rp.monitor_handle, status);
}

return err;
static int mgmt_add_adv_patterns_monitor_sync(struct hci_dev *hdev, void *data)
{
struct mgmt_pending_cmd *cmd = data;
struct adv_monitor *monitor = cmd->user_data;

return hci_add_adv_monitor(hdev, monitor);
}

static int __add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev,
struct adv_monitor *m, u8 status,
void *data, u16 len, u16 op)
{
struct mgmt_rp_add_adv_patterns_monitor rp;
struct mgmt_pending_cmd *cmd;
int err;
bool pending;

hci_dev_lock(hdev);

Expand All @@ -4714,31 +4709,18 @@ static int __add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev,
}

cmd->user_data = m;
pending = hci_add_adv_monitor(hdev, m, &err);
err = hci_cmd_sync_queue(hdev, mgmt_add_adv_patterns_monitor_sync, cmd,
mgmt_add_adv_patterns_monitor_complete);
if (err) {
if (err == -ENOSPC || err == -ENOMEM)
if (err == -ENOMEM)
status = MGMT_STATUS_NO_RESOURCES;
else if (err == -EINVAL)
status = MGMT_STATUS_INVALID_PARAMS;
else
status = MGMT_STATUS_FAILED;

mgmt_pending_remove(cmd);
goto unlock;
}

if (!pending) {
mgmt_pending_remove(cmd);
rp.monitor_handle = cpu_to_le16(m->handle);
mgmt_adv_monitor_added(sk, hdev, m->handle);
m->state = ADV_MONITOR_STATE_REGISTERED;
hdev->adv_monitors_cnt++;

hci_dev_unlock(hdev);
return mgmt_cmd_complete(sk, hdev->id, op, MGMT_STATUS_SUCCESS,
&rp, sizeof(rp));
}

hci_dev_unlock(hdev);

return 0;
Expand Down

0 comments on commit b747a83

Please sign in to comment.