Commit 26ac4c56 authored by Brian Gix's avatar Brian Gix Committed by Marcel Holtmann

Bluetooth: hci_sync: Convert MGMT_OP_SET_ADVERTISING

mgmt-test paths:
Set powered on - Privacy and Advertising
Set Advertising on - Success 2
Set Advertising on - Appearance 1
Set Advertising on - Local name 1
Set Advertising on - Name + Appear 1
Add Advertising - Success 4
Add Advertising - Success 5
Add Ext Advertising - Success 4
Add Ext Advertising - Success 5
Signed-off-by: default avatarBrian Gix <brian.gix@intel.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 71efbb08
...@@ -5608,29 +5608,25 @@ static int set_device_id(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -5608,29 +5608,25 @@ static int set_device_id(struct sock *sk, struct hci_dev *hdev, void *data,
return err; return err;
} }
static void enable_advertising_instance(struct hci_dev *hdev, u8 status, static void enable_advertising_instance(struct hci_dev *hdev, int err)
u16 opcode)
{ {
bt_dev_dbg(hdev, "status %u", status); if (err)
bt_dev_err(hdev, "failed to re-configure advertising %d", err);
else
bt_dev_dbg(hdev, "status %d", err);
} }
static void set_advertising_complete(struct hci_dev *hdev, u8 status, static void set_advertising_complete(struct hci_dev *hdev, void *data, int err)
u16 opcode)
{ {
struct cmd_lookup match = { NULL, hdev }; struct cmd_lookup match = { NULL, hdev };
struct hci_request req;
u8 instance; u8 instance;
struct adv_info *adv_instance; struct adv_info *adv_instance;
int err; u8 status = mgmt_status(err);
hci_dev_lock(hdev);
if (status) { if (status) {
u8 mgmt_err = mgmt_status(status);
mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev,
cmd_status_rsp, &mgmt_err); cmd_status_rsp, &status);
goto unlock; return;
} }
if (hci_dev_test_flag(hdev, HCI_LE_ADV)) if (hci_dev_test_flag(hdev, HCI_LE_ADV))
...@@ -5662,30 +5658,55 @@ static void set_advertising_complete(struct hci_dev *hdev, u8 status, ...@@ -5662,30 +5658,55 @@ static void set_advertising_complete(struct hci_dev *hdev, u8 status,
*/ */
if (hci_dev_test_flag(hdev, HCI_ADVERTISING) || if (hci_dev_test_flag(hdev, HCI_ADVERTISING) ||
list_empty(&hdev->adv_instances)) list_empty(&hdev->adv_instances))
goto unlock; return;
instance = hdev->cur_adv_instance; instance = hdev->cur_adv_instance;
if (!instance) { if (!instance) {
adv_instance = list_first_entry_or_null(&hdev->adv_instances, adv_instance = list_first_entry_or_null(&hdev->adv_instances,
struct adv_info, list); struct adv_info, list);
if (!adv_instance) if (!adv_instance)
goto unlock; return;
instance = adv_instance->instance; instance = adv_instance->instance;
} }
hci_req_init(&req, hdev); err = hci_schedule_adv_instance_sync(hdev, instance, true);
err = __hci_req_schedule_adv_instance(&req, instance, true); enable_advertising_instance(hdev, err);
}
if (!err) static int set_adv_sync(struct hci_dev *hdev, void *data)
err = hci_req_run(&req, enable_advertising_instance); {
struct mgmt_pending_cmd *cmd = data;
struct mgmt_mode *cp = cmd->param;
u8 val = !!cp->val;
if (err) if (cp->val == 0x02)
bt_dev_err(hdev, "failed to re-configure advertising"); hci_dev_set_flag(hdev, HCI_ADVERTISING_CONNECTABLE);
else
hci_dev_clear_flag(hdev, HCI_ADVERTISING_CONNECTABLE);
unlock: cancel_adv_timeout(hdev);
hci_dev_unlock(hdev);
if (val) {
/* Switch to instance "0" for the Set Advertising setting.
* We cannot use update_[adv|scan_rsp]_data() here as the
* HCI_ADVERTISING flag is not yet set.
*/
hdev->cur_adv_instance = 0x00;
if (ext_adv_capable(hdev)) {
hci_start_ext_adv_sync(hdev, 0x00);
} else {
hci_update_adv_data_sync(hdev, 0x00);
hci_update_scan_rsp_data_sync(hdev, 0x00);
hci_enable_advertising_sync(hdev);
}
} else {
hci_disable_advertising_sync(hdev);
}
return 0;
} }
static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data, static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data,
...@@ -5693,7 +5714,6 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -5693,7 +5714,6 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data,
{ {
struct mgmt_mode *cp = data; struct mgmt_mode *cp = data;
struct mgmt_pending_cmd *cmd; struct mgmt_pending_cmd *cmd;
struct hci_request req;
u8 val, status; u8 val, status;
int err; int err;
...@@ -5759,40 +5779,13 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -5759,40 +5779,13 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data,
} }
cmd = mgmt_pending_add(sk, MGMT_OP_SET_ADVERTISING, hdev, data, len); cmd = mgmt_pending_add(sk, MGMT_OP_SET_ADVERTISING, hdev, data, len);
if (!cmd) { if (!cmd)
err = -ENOMEM; err = -ENOMEM;
goto unlock;
}
hci_req_init(&req, hdev);
if (cp->val == 0x02)
hci_dev_set_flag(hdev, HCI_ADVERTISING_CONNECTABLE);
else else
hci_dev_clear_flag(hdev, HCI_ADVERTISING_CONNECTABLE); err = hci_cmd_sync_queue(hdev, set_adv_sync, cmd,
set_advertising_complete);
cancel_adv_timeout(hdev);
if (val) { if (err < 0 && cmd)
/* Switch to instance "0" for the Set Advertising setting.
* We cannot use update_[adv|scan_rsp]_data() here as the
* HCI_ADVERTISING flag is not yet set.
*/
hdev->cur_adv_instance = 0x00;
if (ext_adv_capable(hdev)) {
__hci_req_start_ext_adv(&req, 0x00);
} else {
__hci_req_update_adv_data(&req, 0x00);
__hci_req_update_scan_rsp_data(&req, 0x00);
__hci_req_enable_advertising(&req);
}
} else {
__hci_req_disable_advertising(&req);
}
err = hci_req_run(&req, set_advertising_complete);
if (err < 0)
mgmt_pending_remove(cmd); mgmt_pending_remove(cmd);
unlock: unlock:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment