diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2011-11-07 15:16:02 -0500 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-11-08 09:54:09 -0500 |
commit | 16ab91ab48287aa4fc757f3618820f728ee4412f (patch) | |
tree | 9266bb78e7beedfbf08160a3309349d927b5ac7f /net | |
parent | 89352e7d3ab372ffad8efe2aa070e0b63df42b85 (diff) |
Bluetooth: Add timeout field to mgmt_set_discoverable
Based on the revised mgmt API set_discoverable has a timeout parameter
to specify how long the adapter will remain discoverable. A value of 0
means "indefinitively".
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/hci_core.c | 25 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 5 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 7 |
3 files changed, 36 insertions, 1 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 6a4bd2d8da99..2da3f907e9b7 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -595,6 +595,11 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
595 | tasklet_kill(&hdev->rx_task); | 595 | tasklet_kill(&hdev->rx_task); |
596 | tasklet_kill(&hdev->tx_task); | 596 | tasklet_kill(&hdev->tx_task); |
597 | 597 | ||
598 | if (hdev->discov_timeout > 0) { | ||
599 | cancel_delayed_work_sync(&hdev->discov_off); | ||
600 | hdev->discov_timeout = 0; | ||
601 | } | ||
602 | |||
598 | hci_dev_lock_bh(hdev); | 603 | hci_dev_lock_bh(hdev); |
599 | inquiry_cache_flush(hdev); | 604 | inquiry_cache_flush(hdev); |
600 | hci_conn_hash_flush(hdev); | 605 | hci_conn_hash_flush(hdev); |
@@ -968,6 +973,24 @@ void hci_del_off_timer(struct hci_dev *hdev) | |||
968 | del_timer(&hdev->off_timer); | 973 | del_timer(&hdev->off_timer); |
969 | } | 974 | } |
970 | 975 | ||
976 | static void hci_discov_off(struct work_struct *work) | ||
977 | { | ||
978 | struct hci_dev *hdev; | ||
979 | u8 scan = SCAN_PAGE; | ||
980 | |||
981 | hdev = container_of(work, struct hci_dev, discov_off.work); | ||
982 | |||
983 | BT_DBG("%s", hdev->name); | ||
984 | |||
985 | hci_dev_lock_bh(hdev); | ||
986 | |||
987 | hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan); | ||
988 | |||
989 | hdev->discov_timeout = 0; | ||
990 | |||
991 | hci_dev_unlock_bh(hdev); | ||
992 | } | ||
993 | |||
971 | int hci_uuids_clear(struct hci_dev *hdev) | 994 | int hci_uuids_clear(struct hci_dev *hdev) |
972 | { | 995 | { |
973 | struct list_head *p, *n; | 996 | struct list_head *p, *n; |
@@ -1485,6 +1508,8 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1485 | INIT_WORK(&hdev->power_off, hci_power_off); | 1508 | INIT_WORK(&hdev->power_off, hci_power_off); |
1486 | setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev); | 1509 | setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev); |
1487 | 1510 | ||
1511 | INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); | ||
1512 | |||
1488 | memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); | 1513 | memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); |
1489 | 1514 | ||
1490 | atomic_set(&hdev->promisc, 0); | 1515 | atomic_set(&hdev->promisc, 0); |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 0c11203c261a..cf9926565937 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -292,6 +292,11 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) | |||
292 | set_bit(HCI_ISCAN, &hdev->flags); | 292 | set_bit(HCI_ISCAN, &hdev->flags); |
293 | if (!old_iscan) | 293 | if (!old_iscan) |
294 | mgmt_discoverable(hdev->id, 1); | 294 | mgmt_discoverable(hdev->id, 1); |
295 | if (hdev->discov_timeout > 0) { | ||
296 | int to = msecs_to_jiffies(hdev->discov_timeout * 1000); | ||
297 | queue_delayed_work(hdev->workqueue, &hdev->discov_off, | ||
298 | to); | ||
299 | } | ||
295 | } else if (old_iscan) | 300 | } else if (old_iscan) |
296 | mgmt_discoverable(hdev->id, 0); | 301 | mgmt_discoverable(hdev->id, 0); |
297 | 302 | ||
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 0f9ef9432462..724d4fee2bd7 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -350,7 +350,7 @@ failed: | |||
350 | static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, | 350 | static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, |
351 | u16 len) | 351 | u16 len) |
352 | { | 352 | { |
353 | struct mgmt_mode *cp; | 353 | struct mgmt_cp_set_discoverable *cp; |
354 | struct hci_dev *hdev; | 354 | struct hci_dev *hdev; |
355 | struct pending_cmd *cmd; | 355 | struct pending_cmd *cmd; |
356 | u8 scan; | 356 | u8 scan; |
@@ -396,11 +396,16 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, | |||
396 | 396 | ||
397 | if (cp->val) | 397 | if (cp->val) |
398 | scan |= SCAN_INQUIRY; | 398 | scan |= SCAN_INQUIRY; |
399 | else | ||
400 | cancel_delayed_work_sync(&hdev->discov_off); | ||
399 | 401 | ||
400 | err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); | 402 | err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); |
401 | if (err < 0) | 403 | if (err < 0) |
402 | mgmt_pending_remove(cmd); | 404 | mgmt_pending_remove(cmd); |
403 | 405 | ||
406 | if (cp->val) | ||
407 | hdev->discov_timeout = get_unaligned_le16(&cp->timeout); | ||
408 | |||
404 | failed: | 409 | failed: |
405 | hci_dev_unlock_bh(hdev); | 410 | hci_dev_unlock_bh(hdev); |
406 | hci_dev_put(hdev); | 411 | hci_dev_put(hdev); |