Skip to content

Commit 2bd1b23

Browse files
Vudentzholtmann
authored andcommitted
Bluetooth: hci_sync: Convert MGMT_OP_SET_DISCOVERABLE to use cmd_sync
This makes MGMT_OP_SET_DISCOVERABLE use hci_cmd_sync_queue instead of use a dedicated discoverable_update work. Signed-off-by: Luiz Augusto von Dentz <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent be6c5ba commit 2bd1b23

File tree

5 files changed

+112
-38
lines changed

5 files changed

+112
-38
lines changed

include/net/bluetooth/hci_core.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,6 @@ struct hci_dev {
496496
struct work_struct bg_scan_update;
497497
struct work_struct scan_update;
498498
struct work_struct connectable_update;
499-
struct work_struct discoverable_update;
500499
struct delayed_work le_scan_disable;
501500
struct delayed_work le_scan_restart;
502501

@@ -1828,7 +1827,6 @@ void mgmt_new_conn_param(struct hci_dev *hdev, bdaddr_t *bdaddr,
18281827
void mgmt_smp_complete(struct hci_conn *conn, bool complete);
18291828
bool mgmt_get_connectable(struct hci_dev *hdev);
18301829
void mgmt_set_connectable_complete(struct hci_dev *hdev, u8 status);
1831-
void mgmt_set_discoverable_complete(struct hci_dev *hdev, u8 status);
18321830
u8 mgmt_get_adv_discov_flags(struct hci_dev *hdev);
18331831
void mgmt_advertising_added(struct sock *sk, struct hci_dev *hdev,
18341832
u8 instance);

include/net/bluetooth/hci_sync.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ int hci_dev_close_sync(struct hci_dev *hdev);
9090
int hci_powered_update_sync(struct hci_dev *hdev);
9191
int hci_set_powered_sync(struct hci_dev *hdev, u8 val);
9292

93+
int hci_update_discoverable_sync(struct hci_dev *hdev);
94+
int hci_update_discoverable(struct hci_dev *hdev);
95+
9396
int hci_start_discovery_sync(struct hci_dev *hdev);
9497
int hci_stop_discovery_sync(struct hci_dev *hdev);
9598

net/bluetooth/hci_request.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,16 +2131,6 @@ static int discoverable_update(struct hci_request *req, unsigned long opt)
21312131
return 0;
21322132
}
21332133

2134-
static void discoverable_update_work(struct work_struct *work)
2135-
{
2136-
struct hci_dev *hdev = container_of(work, struct hci_dev,
2137-
discoverable_update);
2138-
u8 status;
2139-
2140-
hci_req_sync(hdev, discoverable_update, 0, HCI_CMD_TIMEOUT, &status);
2141-
mgmt_set_discoverable_complete(hdev, status);
2142-
}
2143-
21442134
void __hci_abort_conn(struct hci_request *req, struct hci_conn *conn,
21452135
u8 reason)
21462136
{
@@ -2852,7 +2842,6 @@ void hci_request_setup(struct hci_dev *hdev)
28522842
INIT_WORK(&hdev->bg_scan_update, bg_scan_update);
28532843
INIT_WORK(&hdev->scan_update, scan_update_work);
28542844
INIT_WORK(&hdev->connectable_update, connectable_update_work);
2855-
INIT_WORK(&hdev->discoverable_update, discoverable_update_work);
28562845
INIT_DELAYED_WORK(&hdev->discov_off, discov_off);
28572846
INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
28582847
INIT_DELAYED_WORK(&hdev->le_scan_restart, le_scan_restart_work);
@@ -2868,7 +2857,6 @@ void hci_request_cancel_all(struct hci_dev *hdev)
28682857
cancel_work_sync(&hdev->bg_scan_update);
28692858
cancel_work_sync(&hdev->scan_update);
28702859
cancel_work_sync(&hdev->connectable_update);
2871-
cancel_work_sync(&hdev->discoverable_update);
28722860
cancel_delayed_work_sync(&hdev->discov_off);
28732861
cancel_delayed_work_sync(&hdev->le_scan_disable);
28742862
cancel_delayed_work_sync(&hdev->le_scan_restart);

net/bluetooth/hci_sync.c

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1699,7 +1699,6 @@ static int hci_resume_advertising_sync(struct hci_dev *hdev)
16991699
hdev->advertising_paused = false;
17001700
if (hdev->advertising_old_state) {
17011701
hci_dev_set_flag(hdev, HCI_ADVERTISING);
1702-
queue_work(hdev->req_workqueue, &hdev->discoverable_update);
17031702
hdev->advertising_old_state = 0;
17041703
}
17051704

@@ -4392,6 +4391,95 @@ int hci_set_powered_sync(struct hci_dev *hdev, u8 val)
43924391
return hci_power_off_sync(hdev);
43934392
}
43944393

4394+
static int hci_write_iac_sync(struct hci_dev *hdev)
4395+
{
4396+
struct hci_cp_write_current_iac_lap cp;
4397+
4398+
if (!hci_dev_test_flag(hdev, HCI_DISCOVERABLE))
4399+
return 0;
4400+
4401+
memset(&cp, 0, sizeof(cp));
4402+
4403+
if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE)) {
4404+
/* Limited discoverable mode */
4405+
cp.num_iac = min_t(u8, hdev->num_iac, 2);
4406+
cp.iac_lap[0] = 0x00; /* LIAC */
4407+
cp.iac_lap[1] = 0x8b;
4408+
cp.iac_lap[2] = 0x9e;
4409+
cp.iac_lap[3] = 0x33; /* GIAC */
4410+
cp.iac_lap[4] = 0x8b;
4411+
cp.iac_lap[5] = 0x9e;
4412+
} else {
4413+
/* General discoverable mode */
4414+
cp.num_iac = 1;
4415+
cp.iac_lap[0] = 0x33; /* GIAC */
4416+
cp.iac_lap[1] = 0x8b;
4417+
cp.iac_lap[2] = 0x9e;
4418+
}
4419+
4420+
return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_CURRENT_IAC_LAP,
4421+
(cp.num_iac * 3) + 1, &cp,
4422+
HCI_CMD_TIMEOUT);
4423+
}
4424+
4425+
int hci_update_discoverable_sync(struct hci_dev *hdev)
4426+
{
4427+
int err = 0;
4428+
4429+
if (hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
4430+
err = hci_write_iac_sync(hdev);
4431+
if (err)
4432+
return err;
4433+
4434+
err = hci_update_scan_sync(hdev);
4435+
if (err)
4436+
return err;
4437+
4438+
err = hci_update_class_sync(hdev);
4439+
if (err)
4440+
return err;
4441+
}
4442+
4443+
/* Advertising instances don't use the global discoverable setting, so
4444+
* only update AD if advertising was enabled using Set Advertising.
4445+
*/
4446+
if (hci_dev_test_flag(hdev, HCI_ADVERTISING)) {
4447+
err = hci_update_adv_data_sync(hdev, 0x00);
4448+
if (err)
4449+
return err;
4450+
4451+
/* Discoverable mode affects the local advertising
4452+
* address in limited privacy mode.
4453+
*/
4454+
if (hci_dev_test_flag(hdev, HCI_LIMITED_PRIVACY)) {
4455+
if (ext_adv_capable(hdev))
4456+
err = hci_start_ext_adv_sync(hdev, 0x00);
4457+
else
4458+
err = hci_enable_advertising_sync(hdev);
4459+
}
4460+
}
4461+
4462+
return err;
4463+
}
4464+
4465+
static int update_discoverable_sync(struct hci_dev *hdev, void *data)
4466+
{
4467+
return hci_update_discoverable_sync(hdev);
4468+
}
4469+
4470+
int hci_update_discoverable(struct hci_dev *hdev)
4471+
{
4472+
/* Only queue if it would have any effect */
4473+
if (hdev_is_powered(hdev) &&
4474+
hci_dev_test_flag(hdev, HCI_ADVERTISING) &&
4475+
hci_dev_test_flag(hdev, HCI_DISCOVERABLE) &&
4476+
hci_dev_test_flag(hdev, HCI_LIMITED_PRIVACY))
4477+
return hci_cmd_sync_queue(hdev, update_discoverable_sync, NULL,
4478+
NULL);
4479+
4480+
return 0;
4481+
}
4482+
43954483
static int hci_inquiry_sync(struct hci_dev *hdev, u8 length)
43964484
{
43974485
const u8 giac[3] = { 0x33, 0x8b, 0x9e };

net/bluetooth/mgmt.c

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,23 +1370,20 @@ static u8 mgmt_le_support(struct hci_dev *hdev)
13701370
return MGMT_STATUS_SUCCESS;
13711371
}
13721372

1373-
void mgmt_set_discoverable_complete(struct hci_dev *hdev, u8 status)
1373+
static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data,
1374+
int err)
13741375
{
1375-
struct mgmt_pending_cmd *cmd;
1376+
struct mgmt_pending_cmd *cmd = data;
13761377

1377-
bt_dev_dbg(hdev, "status 0x%02x", status);
1378+
bt_dev_dbg(hdev, "err %d", err);
13781379

13791380
hci_dev_lock(hdev);
13801381

1381-
cmd = pending_find(MGMT_OP_SET_DISCOVERABLE, hdev);
1382-
if (!cmd)
1383-
goto unlock;
1384-
1385-
if (status) {
1386-
u8 mgmt_err = mgmt_status(status);
1382+
if (err) {
1383+
u8 mgmt_err = mgmt_status(err);
13871384
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
13881385
hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
1389-
goto remove_cmd;
1386+
goto done;
13901387
}
13911388

13921389
if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE) &&
@@ -1398,13 +1395,18 @@ void mgmt_set_discoverable_complete(struct hci_dev *hdev, u8 status)
13981395
send_settings_rsp(cmd->sk, MGMT_OP_SET_DISCOVERABLE, hdev);
13991396
new_settings(hdev, cmd->sk);
14001397

1401-
remove_cmd:
1402-
mgmt_pending_remove(cmd);
1403-
1404-
unlock:
1398+
done:
1399+
mgmt_pending_free(cmd);
14051400
hci_dev_unlock(hdev);
14061401
}
14071402

1403+
static int set_discoverable_sync(struct hci_dev *hdev, void *data)
1404+
{
1405+
BT_DBG("%s", hdev->name);
1406+
1407+
return hci_update_discoverable_sync(hdev);
1408+
}
1409+
14081410
static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
14091411
u16 len)
14101412
{
@@ -1503,7 +1505,7 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
15031505
goto failed;
15041506
}
15051507

1506-
cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, hdev, data, len);
1508+
cmd = mgmt_pending_new(sk, MGMT_OP_SET_DISCOVERABLE, hdev, data, len);
15071509
if (!cmd) {
15081510
err = -ENOMEM;
15091511
goto failed;
@@ -1527,8 +1529,8 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
15271529
else
15281530
hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
15291531

1530-
queue_work(hdev->req_workqueue, &hdev->discoverable_update);
1531-
err = 0;
1532+
err = hci_cmd_sync_queue(hdev, set_discoverable_sync, cmd,
1533+
mgmt_set_discoverable_complete);
15321534

15331535
failed:
15341536
hci_dev_unlock(hdev);
@@ -1677,12 +1679,7 @@ static int set_bondable(struct sock *sk, struct hci_dev *hdev, void *data,
16771679
/* In limited privacy mode the change of bondable mode
16781680
* may affect the local advertising address.
16791681
*/
1680-
if (hdev_is_powered(hdev) &&
1681-
hci_dev_test_flag(hdev, HCI_ADVERTISING) &&
1682-
hci_dev_test_flag(hdev, HCI_DISCOVERABLE) &&
1683-
hci_dev_test_flag(hdev, HCI_LIMITED_PRIVACY))
1684-
queue_work(hdev->req_workqueue,
1685-
&hdev->discoverable_update);
1682+
hci_update_discoverable(hdev);
16861683

16871684
err = new_settings(hdev, sk);
16881685
}

0 commit comments

Comments
 (0)