diff options
author | Arman Uguray <armansito@chromium.org> | 2015-03-25 21:53:41 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2015-03-25 22:30:28 -0400 |
commit | b44133ff03be30b55f23036e62f403a3f7784fce (patch) | |
tree | cc03ec58ab22810289a7ff6391c69ecb68332417 /net/bluetooth | |
parent | e7a685d316e7d4b64cd3b2811687b0270d590386 (diff) |
Bluetooth: Support the "discoverable" adv flag
This patch adds support for the "discoverable" flag of the
Add Advertising command.
Signed-off-by: Arman Uguray <armansito@chromium.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/mgmt.c | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 672ff5b66c21..c1804527fa3b 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -975,13 +975,28 @@ static u8 create_default_adv_data(struct hci_dev *hdev, u8 *ptr) | |||
975 | 975 | ||
976 | static u8 create_instance_adv_data(struct hci_dev *hdev, u8 *ptr) | 976 | static u8 create_instance_adv_data(struct hci_dev *hdev, u8 *ptr) |
977 | { | 977 | { |
978 | /* TODO: Set the appropriate entries based on advertising instance flags | 978 | u8 ad_len = 0, flags = 0; |
979 | * here once flags other than 0 are supported. | 979 | |
980 | */ | 980 | if (hdev->adv_instance.flags & MGMT_ADV_FLAG_DISCOV) |
981 | flags |= LE_AD_GENERAL; | ||
982 | |||
983 | if (flags) { | ||
984 | if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) | ||
985 | flags |= LE_AD_NO_BREDR; | ||
986 | |||
987 | ptr[0] = 0x02; | ||
988 | ptr[1] = EIR_FLAGS; | ||
989 | ptr[2] = flags; | ||
990 | |||
991 | ad_len += 3; | ||
992 | ptr += 3; | ||
993 | } | ||
994 | |||
981 | memcpy(ptr, hdev->adv_instance.adv_data, | 995 | memcpy(ptr, hdev->adv_instance.adv_data, |
982 | hdev->adv_instance.adv_data_len); | 996 | hdev->adv_instance.adv_data_len); |
997 | ad_len += hdev->adv_instance.adv_data_len; | ||
983 | 998 | ||
984 | return hdev->adv_instance.adv_data_len; | 999 | return ad_len; |
985 | } | 1000 | } |
986 | 1001 | ||
987 | static void update_adv_data_for_instance(struct hci_request *req, u8 instance) | 1002 | static void update_adv_data_for_instance(struct hci_request *req, u8 instance) |
@@ -6556,12 +6571,16 @@ static int read_adv_features(struct sock *sk, struct hci_dev *hdev, | |||
6556 | } | 6571 | } |
6557 | 6572 | ||
6558 | static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data, | 6573 | static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data, |
6559 | u8 len) | 6574 | u8 len, bool is_adv_data) |
6560 | { | 6575 | { |
6561 | u8 max_len = HCI_MAX_AD_LENGTH; | 6576 | u8 max_len = HCI_MAX_AD_LENGTH; |
6562 | int i, cur_len; | 6577 | int i, cur_len; |
6578 | bool flags_managed = false; | ||
6563 | 6579 | ||
6564 | /* TODO: Correctly reduce len based on adv_flags. */ | 6580 | if (is_adv_data && (adv_flags & MGMT_ADV_FLAG_DISCOV)) { |
6581 | flags_managed = true; | ||
6582 | max_len -= 3; | ||
6583 | } | ||
6565 | 6584 | ||
6566 | if (len > max_len) | 6585 | if (len > max_len) |
6567 | return false; | 6586 | return false; |
@@ -6570,6 +6589,9 @@ static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data, | |||
6570 | for (i = 0, cur_len = 0; i < len; i += (cur_len + 1)) { | 6589 | for (i = 0, cur_len = 0; i < len; i += (cur_len + 1)) { |
6571 | cur_len = data[i]; | 6590 | cur_len = data[i]; |
6572 | 6591 | ||
6592 | if (flags_managed && data[i + 1] == EIR_FLAGS) | ||
6593 | return false; | ||
6594 | |||
6573 | /* If the current field length would exceed the total data | 6595 | /* If the current field length would exceed the total data |
6574 | * length, then it's invalid. | 6596 | * length, then it's invalid. |
6575 | */ | 6597 | */ |
@@ -6671,9 +6693,9 @@ static int add_advertising(struct sock *sk, struct hci_dev *hdev, | |||
6671 | goto unlock; | 6693 | goto unlock; |
6672 | } | 6694 | } |
6673 | 6695 | ||
6674 | if (!tlv_data_is_valid(hdev, flags, cp->data, cp->adv_data_len) || | 6696 | if (!tlv_data_is_valid(hdev, flags, cp->data, cp->adv_data_len, true) || |
6675 | !tlv_data_is_valid(hdev, flags, cp->data + cp->adv_data_len, | 6697 | !tlv_data_is_valid(hdev, flags, cp->data + cp->adv_data_len, |
6676 | cp->scan_rsp_len)) { | 6698 | cp->scan_rsp_len, false)) { |
6677 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING, | 6699 | err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING, |
6678 | MGMT_STATUS_INVALID_PARAMS); | 6700 | MGMT_STATUS_INVALID_PARAMS); |
6679 | goto unlock; | 6701 | goto unlock; |