diff options
| author | Marcel Holtmann <marcel@holtmann.org> | 2015-03-13 01:30:58 -0400 |
|---|---|---|
| committer | Johan Hedberg <johan.hedberg@intel.com> | 2015-03-13 06:07:54 -0400 |
| commit | cc91cb042ce5dab66fedeb94260b18f193ed33d9 (patch) | |
| tree | e21de1be11a57c1baedc10c8257b98c2686e60bb | |
| parent | 983f9814c0199c26a58cbfe98f071e3bfa968839 (diff) | |
Bluetooth: Add support connectable advertising setting
The patch adds a second advertising setting that allows switching of the
controller into connectable mode independent of the global connectable
setting.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
| -rw-r--r-- | include/net/bluetooth/hci.h | 1 | ||||
| -rw-r--r-- | net/bluetooth/mgmt.c | 39 |
2 files changed, 31 insertions, 9 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index f76f45ae76c3..0f3413b285a5 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
| @@ -217,6 +217,7 @@ enum { | |||
| 217 | HCI_HS_ENABLED, | 217 | HCI_HS_ENABLED, |
| 218 | HCI_LE_ENABLED, | 218 | HCI_LE_ENABLED, |
| 219 | HCI_ADVERTISING, | 219 | HCI_ADVERTISING, |
| 220 | HCI_ADVERTISING_CONNECTABLE, | ||
| 220 | HCI_CONNECTABLE, | 221 | HCI_CONNECTABLE, |
| 221 | HCI_DISCOVERABLE, | 222 | HCI_DISCOVERABLE, |
| 222 | HCI_LIMITED_DISCOVERABLE, | 223 | HCI_LIMITED_DISCOVERABLE, |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 025f29bf1f1a..0761f2e0fefa 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
| @@ -1110,7 +1110,10 @@ static void enable_advertising(struct hci_request *req) | |||
| 1110 | */ | 1110 | */ |
| 1111 | clear_bit(HCI_LE_ADV, &hdev->dev_flags); | 1111 | clear_bit(HCI_LE_ADV, &hdev->dev_flags); |
| 1112 | 1112 | ||
| 1113 | connectable = get_connectable(hdev); | 1113 | if (test_bit(HCI_ADVERTISING_CONNECTABLE, &hdev->dev_flags)) |
| 1114 | connectable = true; | ||
| 1115 | else | ||
| 1116 | connectable = get_connectable(hdev); | ||
| 1114 | 1117 | ||
| 1115 | /* Set require_privacy to true only when non-connectable | 1118 | /* Set require_privacy to true only when non-connectable |
| 1116 | * advertising is used. In that case it is fine to use a | 1119 | * advertising is used. In that case it is fine to use a |
| @@ -4430,7 +4433,7 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data, | |||
| 4430 | struct mgmt_mode *cp = data; | 4433 | struct mgmt_mode *cp = data; |
| 4431 | struct mgmt_pending_cmd *cmd; | 4434 | struct mgmt_pending_cmd *cmd; |
| 4432 | struct hci_request req; | 4435 | struct hci_request req; |
| 4433 | u8 val, enabled, status; | 4436 | u8 val, status; |
| 4434 | int err; | 4437 | int err; |
| 4435 | 4438 | ||
| 4436 | BT_DBG("request for %s", hdev->name); | 4439 | BT_DBG("request for %s", hdev->name); |
| @@ -4440,29 +4443,42 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data, | |||
| 4440 | return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, | 4443 | return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, |
| 4441 | status); | 4444 | status); |
| 4442 | 4445 | ||
| 4443 | if (cp->val != 0x00 && cp->val != 0x01) | 4446 | if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02) |
| 4444 | return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, | 4447 | return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, |
| 4445 | MGMT_STATUS_INVALID_PARAMS); | 4448 | MGMT_STATUS_INVALID_PARAMS); |
| 4446 | 4449 | ||
| 4447 | hci_dev_lock(hdev); | 4450 | hci_dev_lock(hdev); |
| 4448 | 4451 | ||
| 4449 | val = !!cp->val; | 4452 | val = !!cp->val; |
| 4450 | enabled = test_bit(HCI_ADVERTISING, &hdev->dev_flags); | ||
| 4451 | 4453 | ||
| 4452 | /* The following conditions are ones which mean that we should | 4454 | /* The following conditions are ones which mean that we should |
| 4453 | * not do any HCI communication but directly send a mgmt | 4455 | * not do any HCI communication but directly send a mgmt |
| 4454 | * response to user space (after toggling the flag if | 4456 | * response to user space (after toggling the flag if |
| 4455 | * necessary). | 4457 | * necessary). |
| 4456 | */ | 4458 | */ |
| 4457 | if (!hdev_is_powered(hdev) || val == enabled || | 4459 | if (!hdev_is_powered(hdev) || |
| 4460 | (val == test_bit(HCI_ADVERTISING, &hdev->dev_flags) && | ||
| 4461 | (cp->val == 0x02) == test_bit(HCI_ADVERTISING_CONNECTABLE, | ||
| 4462 | &hdev->dev_flags)) || | ||
| 4458 | hci_conn_num(hdev, LE_LINK) > 0 || | 4463 | hci_conn_num(hdev, LE_LINK) > 0 || |
| 4459 | (test_bit(HCI_LE_SCAN, &hdev->dev_flags) && | 4464 | (test_bit(HCI_LE_SCAN, &hdev->dev_flags) && |
| 4460 | hdev->le_scan_type == LE_SCAN_ACTIVE)) { | 4465 | hdev->le_scan_type == LE_SCAN_ACTIVE)) { |
| 4461 | bool changed = false; | 4466 | bool changed; |
| 4462 | 4467 | ||
| 4463 | if (val != test_bit(HCI_ADVERTISING, &hdev->dev_flags)) { | 4468 | if (cp->val) { |
| 4464 | change_bit(HCI_ADVERTISING, &hdev->dev_flags); | 4469 | changed = !test_and_set_bit(HCI_ADVERTISING, |
| 4465 | changed = true; | 4470 | &hdev->dev_flags); |
| 4471 | if (cp->val == 0x02) | ||
| 4472 | set_bit(HCI_ADVERTISING_CONNECTABLE, | ||
| 4473 | &hdev->dev_flags); | ||
| 4474 | else | ||
| 4475 | clear_bit(HCI_ADVERTISING_CONNECTABLE, | ||
| 4476 | &hdev->dev_flags); | ||
| 4477 | } else { | ||
| 4478 | changed = test_and_clear_bit(HCI_ADVERTISING, | ||
| 4479 | &hdev->dev_flags); | ||
| 4480 | clear_bit(HCI_ADVERTISING_CONNECTABLE, | ||
| 4481 | &hdev->dev_flags); | ||
| 4466 | } | 4482 | } |
| 4467 | 4483 | ||
| 4468 | err = send_settings_rsp(sk, MGMT_OP_SET_ADVERTISING, hdev); | 4484 | err = send_settings_rsp(sk, MGMT_OP_SET_ADVERTISING, hdev); |
| @@ -4490,6 +4506,11 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data, | |||
| 4490 | 4506 | ||
| 4491 | hci_req_init(&req, hdev); | 4507 | hci_req_init(&req, hdev); |
| 4492 | 4508 | ||
| 4509 | if (cp->val == 0x02) | ||
| 4510 | set_bit(HCI_ADVERTISING_CONNECTABLE, &hdev->dev_flags); | ||
| 4511 | else | ||
| 4512 | clear_bit(HCI_ADVERTISING_CONNECTABLE, &hdev->dev_flags); | ||
| 4513 | |||
| 4493 | if (val) | 4514 | if (val) |
| 4494 | enable_advertising(&req); | 4515 | enable_advertising(&req); |
| 4495 | else | 4516 | else |
