summaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2015-11-22 09:24:44 -0500
committerMarcel Holtmann <marcel@holtmann.org>2015-12-09 18:51:48 -0500
commitaed1a8851db022c3bd22af41a343068b8c6e40c1 (patch)
tree74efd21f8ee36965782e8394cb0e8ee70aa598aa /net/bluetooth
parent14bf5eac7a4f4bf0729ff8eb358de4fab967cee1 (diff)
Bluetooth: Move discoverable changes to hdev->req_workqueue
The discoverable mode is intrinsically linked with the connectable mode e.g. through sharing the same HCI command (Write Scan Enable) for BR/EDR. It makes therefore sense to move it to hci_request.c and run the changes through the same hdev->req_workqueue. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_request.c64
-rw-r--r--net/bluetooth/mgmt.c90
2 files changed, 77 insertions, 77 deletions
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index e5e827b762b9..8f72218ed805 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -1351,6 +1351,68 @@ void __hci_req_update_class(struct hci_request *req)
1351 hci_req_add(req, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod); 1351 hci_req_add(req, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod);
1352} 1352}
1353 1353
1354static void write_iac(struct hci_request *req)
1355{
1356 struct hci_dev *hdev = req->hdev;
1357 struct hci_cp_write_current_iac_lap cp;
1358
1359 if (!hci_dev_test_flag(hdev, HCI_DISCOVERABLE))
1360 return;
1361
1362 if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE)) {
1363 /* Limited discoverable mode */
1364 cp.num_iac = min_t(u8, hdev->num_iac, 2);
1365 cp.iac_lap[0] = 0x00; /* LIAC */
1366 cp.iac_lap[1] = 0x8b;
1367 cp.iac_lap[2] = 0x9e;
1368 cp.iac_lap[3] = 0x33; /* GIAC */
1369 cp.iac_lap[4] = 0x8b;
1370 cp.iac_lap[5] = 0x9e;
1371 } else {
1372 /* General discoverable mode */
1373 cp.num_iac = 1;
1374 cp.iac_lap[0] = 0x33; /* GIAC */
1375 cp.iac_lap[1] = 0x8b;
1376 cp.iac_lap[2] = 0x9e;
1377 }
1378
1379 hci_req_add(req, HCI_OP_WRITE_CURRENT_IAC_LAP,
1380 (cp.num_iac * 3) + 1, &cp);
1381}
1382
1383static int discoverable_update(struct hci_request *req, unsigned long opt)
1384{
1385 struct hci_dev *hdev = req->hdev;
1386
1387 hci_dev_lock(hdev);
1388
1389 if (hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
1390 write_iac(req);
1391 __hci_req_update_scan(req);
1392 __hci_req_update_class(req);
1393 }
1394
1395 /* Advertising instances don't use the global discoverable setting, so
1396 * only update AD if advertising was enabled using Set Advertising.
1397 */
1398 if (hci_dev_test_flag(hdev, HCI_ADVERTISING))
1399 __hci_req_update_adv_data(req, HCI_ADV_CURRENT);
1400
1401 hci_dev_unlock(hdev);
1402
1403 return 0;
1404}
1405
1406static void discoverable_update_work(struct work_struct *work)
1407{
1408 struct hci_dev *hdev = container_of(work, struct hci_dev,
1409 discoverable_update);
1410 u8 status;
1411
1412 hci_req_sync(hdev, discoverable_update, 0, HCI_CMD_TIMEOUT, &status);
1413 mgmt_set_discoverable_complete(hdev, status);
1414}
1415
1354void __hci_abort_conn(struct hci_request *req, struct hci_conn *conn, 1416void __hci_abort_conn(struct hci_request *req, struct hci_conn *conn,
1355 u8 reason) 1417 u8 reason)
1356{ 1418{
@@ -1867,6 +1929,7 @@ void hci_request_setup(struct hci_dev *hdev)
1867 INIT_WORK(&hdev->bg_scan_update, bg_scan_update); 1929 INIT_WORK(&hdev->bg_scan_update, bg_scan_update);
1868 INIT_WORK(&hdev->scan_update, scan_update_work); 1930 INIT_WORK(&hdev->scan_update, scan_update_work);
1869 INIT_WORK(&hdev->connectable_update, connectable_update_work); 1931 INIT_WORK(&hdev->connectable_update, connectable_update_work);
1932 INIT_WORK(&hdev->discoverable_update, discoverable_update_work);
1870 INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 1933 INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
1871 INIT_DELAYED_WORK(&hdev->le_scan_restart, le_scan_restart_work); 1934 INIT_DELAYED_WORK(&hdev->le_scan_restart, le_scan_restart_work);
1872 INIT_DELAYED_WORK(&hdev->adv_instance_expire, adv_timeout_expire); 1935 INIT_DELAYED_WORK(&hdev->adv_instance_expire, adv_timeout_expire);
@@ -1880,6 +1943,7 @@ void hci_request_cancel_all(struct hci_dev *hdev)
1880 cancel_work_sync(&hdev->bg_scan_update); 1943 cancel_work_sync(&hdev->bg_scan_update);
1881 cancel_work_sync(&hdev->scan_update); 1944 cancel_work_sync(&hdev->scan_update);
1882 cancel_work_sync(&hdev->connectable_update); 1945 cancel_work_sync(&hdev->connectable_update);
1946 cancel_work_sync(&hdev->discoverable_update);
1883 cancel_delayed_work_sync(&hdev->le_scan_disable); 1947 cancel_delayed_work_sync(&hdev->le_scan_disable);
1884 cancel_delayed_work_sync(&hdev->le_scan_restart); 1948 cancel_delayed_work_sync(&hdev->le_scan_restart);
1885 1949
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index f5a4ee92f2bf..8846cb3b0aaa 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1282,13 +1282,9 @@ static u8 mgmt_le_support(struct hci_dev *hdev)
1282 return MGMT_STATUS_SUCCESS; 1282 return MGMT_STATUS_SUCCESS;
1283} 1283}
1284 1284
1285static void set_discoverable_complete(struct hci_dev *hdev, u8 status, 1285void mgmt_set_discoverable_complete(struct hci_dev *hdev, u8 status)
1286 u16 opcode)
1287{ 1286{
1288 struct mgmt_pending_cmd *cmd; 1287 struct mgmt_pending_cmd *cmd;
1289 struct mgmt_mode *cp;
1290 struct hci_request req;
1291 bool changed;
1292 1288
1293 BT_DBG("status 0x%02x", status); 1289 BT_DBG("status 0x%02x", status);
1294 1290
@@ -1305,33 +1301,14 @@ static void set_discoverable_complete(struct hci_dev *hdev, u8 status,
1305 goto remove_cmd; 1301 goto remove_cmd;
1306 } 1302 }
1307 1303
1308 cp = cmd->param; 1304 if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE) &&
1309 if (cp->val) { 1305 hdev->discov_timeout > 0) {
1310 changed = !hci_dev_test_and_set_flag(hdev, HCI_DISCOVERABLE); 1306 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
1311 1307 queue_delayed_work(hdev->req_workqueue, &hdev->discov_off, to);
1312 if (hdev->discov_timeout > 0) {
1313 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
1314 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
1315 to);
1316 }
1317 } else {
1318 changed = hci_dev_test_and_clear_flag(hdev, HCI_DISCOVERABLE);
1319 } 1308 }
1320 1309
1321 send_settings_rsp(cmd->sk, MGMT_OP_SET_DISCOVERABLE, hdev); 1310 send_settings_rsp(cmd->sk, MGMT_OP_SET_DISCOVERABLE, hdev);
1322 1311 new_settings(hdev, cmd->sk);
1323 if (changed)
1324 new_settings(hdev, cmd->sk);
1325
1326 /* When the discoverable mode gets changed, make sure
1327 * that class of device has the limited discoverable
1328 * bit correctly set. Also update page scan based on whitelist
1329 * entries.
1330 */
1331 hci_req_init(&req, hdev);
1332 __hci_req_update_scan(&req);
1333 __hci_req_update_class(&req);
1334 hci_req_run(&req, NULL);
1335 1312
1336remove_cmd: 1313remove_cmd:
1337 mgmt_pending_remove(cmd); 1314 mgmt_pending_remove(cmd);
@@ -1345,9 +1322,7 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
1345{ 1322{
1346 struct mgmt_cp_set_discoverable *cp = data; 1323 struct mgmt_cp_set_discoverable *cp = data;
1347 struct mgmt_pending_cmd *cmd; 1324 struct mgmt_pending_cmd *cmd;
1348 struct hci_request req;
1349 u16 timeout; 1325 u16 timeout;
1350 u8 scan;
1351 int err; 1326 int err;
1352 1327
1353 BT_DBG("request for %s", hdev->name); 1328 BT_DBG("request for %s", hdev->name);
@@ -1447,58 +1422,19 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
1447 cancel_delayed_work(&hdev->discov_off); 1422 cancel_delayed_work(&hdev->discov_off);
1448 hdev->discov_timeout = timeout; 1423 hdev->discov_timeout = timeout;
1449 1424
1425 if (cp->val)
1426 hci_dev_set_flag(hdev, HCI_DISCOVERABLE);
1427 else
1428 hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
1429
1450 /* Limited discoverable mode */ 1430 /* Limited discoverable mode */
1451 if (cp->val == 0x02) 1431 if (cp->val == 0x02)
1452 hci_dev_set_flag(hdev, HCI_LIMITED_DISCOVERABLE); 1432 hci_dev_set_flag(hdev, HCI_LIMITED_DISCOVERABLE);
1453 else 1433 else
1454 hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE); 1434 hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
1455 1435
1456 hci_req_init(&req, hdev); 1436 queue_work(hdev->req_workqueue, &hdev->discoverable_update);
1457 1437 err = 0;
1458 /* The procedure for LE-only controllers is much simpler - just
1459 * update the advertising data.
1460 */
1461 if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
1462 goto update_ad;
1463
1464 scan = SCAN_PAGE;
1465
1466 if (cp->val) {
1467 struct hci_cp_write_current_iac_lap hci_cp;
1468
1469 if (cp->val == 0x02) {
1470 /* Limited discoverable mode */
1471 hci_cp.num_iac = min_t(u8, hdev->num_iac, 2);
1472 hci_cp.iac_lap[0] = 0x00; /* LIAC */
1473 hci_cp.iac_lap[1] = 0x8b;
1474 hci_cp.iac_lap[2] = 0x9e;
1475 hci_cp.iac_lap[3] = 0x33; /* GIAC */
1476 hci_cp.iac_lap[4] = 0x8b;
1477 hci_cp.iac_lap[5] = 0x9e;
1478 } else {
1479 /* General discoverable mode */
1480 hci_cp.num_iac = 1;
1481 hci_cp.iac_lap[0] = 0x33; /* GIAC */
1482 hci_cp.iac_lap[1] = 0x8b;
1483 hci_cp.iac_lap[2] = 0x9e;
1484 }
1485
1486 hci_req_add(&req, HCI_OP_WRITE_CURRENT_IAC_LAP,
1487 (hci_cp.num_iac * 3) + 1, &hci_cp);
1488
1489 scan |= SCAN_INQUIRY;
1490 } else {
1491 hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
1492 }
1493
1494 hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
1495
1496update_ad:
1497 __hci_req_update_adv_data(&req, HCI_ADV_CURRENT);
1498
1499 err = hci_req_run(&req, set_discoverable_complete);
1500 if (err < 0)
1501 mgmt_pending_remove(cmd);
1502 1438
1503failed: 1439failed:
1504 hci_dev_unlock(hdev); 1440 hci_dev_unlock(hdev);