Skip to content

Commit

Permalink
Bluetooth: hci_sync: Convert MGMT_OP_SET_ADVERTISING
Browse files Browse the repository at this point in the history
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: Brian Gix <brian.gix@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
  • Loading branch information
Brian Gix authored and Marcel Holtmann committed Oct 29, 2021
1 parent 71efbb0 commit 26ac4c5
Showing 1 changed file with 48 additions and 55 deletions.
103 changes: 48 additions & 55 deletions net/bluetooth/mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -5608,29 +5608,25 @@ static int set_device_id(struct sock *sk, struct hci_dev *hdev, void *data,
return err;
}

static void enable_advertising_instance(struct hci_dev *hdev, u8 status,
u16 opcode)
static void enable_advertising_instance(struct hci_dev *hdev, int err)
{
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,
u16 opcode)
static void set_advertising_complete(struct hci_dev *hdev, void *data, int err)
{
struct cmd_lookup match = { NULL, hdev };
struct hci_request req;
u8 instance;
struct adv_info *adv_instance;
int err;

hci_dev_lock(hdev);
u8 status = mgmt_status(err);

if (status) {
u8 mgmt_err = mgmt_status(status);

mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev,
cmd_status_rsp, &mgmt_err);
goto unlock;
cmd_status_rsp, &status);
return;
}

if (hci_dev_test_flag(hdev, HCI_LE_ADV))
Expand Down Expand Up @@ -5662,38 +5658,62 @@ static void set_advertising_complete(struct hci_dev *hdev, u8 status,
*/
if (hci_dev_test_flag(hdev, HCI_ADVERTISING) ||
list_empty(&hdev->adv_instances))
goto unlock;
return;

instance = hdev->cur_adv_instance;
if (!instance) {
adv_instance = list_first_entry_or_null(&hdev->adv_instances,
struct adv_info, list);
if (!adv_instance)
goto unlock;
return;

instance = adv_instance->instance;
}

hci_req_init(&req, hdev);
err = hci_schedule_adv_instance_sync(hdev, instance, true);

enable_advertising_instance(hdev, err);
}

err = __hci_req_schedule_adv_instance(&req, instance, true);
static int set_adv_sync(struct hci_dev *hdev, void *data)
{
struct mgmt_pending_cmd *cmd = data;
struct mgmt_mode *cp = cmd->param;
u8 val = !!cp->val;

if (!err)
err = hci_req_run(&req, enable_advertising_instance);
if (cp->val == 0x02)
hci_dev_set_flag(hdev, HCI_ADVERTISING_CONNECTABLE);
else
hci_dev_clear_flag(hdev, HCI_ADVERTISING_CONNECTABLE);

if (err)
bt_dev_err(hdev, "failed to re-configure advertising");
cancel_adv_timeout(hdev);

unlock:
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,
u16 len)
{
struct mgmt_mode *cp = data;
struct mgmt_pending_cmd *cmd;
struct hci_request req;
u8 val, status;
int err;

Expand Down Expand Up @@ -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);
if (!cmd) {
if (!cmd)
err = -ENOMEM;
goto unlock;
}

hci_req_init(&req, hdev);

if (cp->val == 0x02)
hci_dev_set_flag(hdev, HCI_ADVERTISING_CONNECTABLE);
else
hci_dev_clear_flag(hdev, HCI_ADVERTISING_CONNECTABLE);

cancel_adv_timeout(hdev);
err = hci_cmd_sync_queue(hdev, set_adv_sync, cmd,
set_advertising_complete);

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_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)
if (err < 0 && cmd)
mgmt_pending_remove(cmd);

unlock:
Expand Down

0 comments on commit 26ac4c5

Please sign in to comment.