diff options
author | Arman Uguray <armansito@chromium.org> | 2015-03-25 21:53:45 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2015-03-25 22:30:29 -0400 |
commit | 089fa8c09e7fd36b9db01c23c826fb7956f25a1e (patch) | |
tree | 37ebafe5dbf7dc78127f65dc42682732c1b00091 /net | |
parent | 5507e358112af307c1c8595a04a0ef172d197f3c (diff) |
Bluetooth: Update supported_flags for AD features
This patch updates the "supported_flags" parameter returned from the
"Read Advertising Features" command. Add Advertising will now return
an error if an unsupported flag is provided.
Signed-off-by: Arman Uguray <armansito@chromium.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/mgmt.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index de321b9087e7..eab09b5a71df 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -6540,6 +6540,21 @@ done: | |||
6540 | return err; | 6540 | return err; |
6541 | } | 6541 | } |
6542 | 6542 | ||
6543 | static u32 get_supported_adv_flags(struct hci_dev *hdev) | ||
6544 | { | ||
6545 | u32 flags = 0; | ||
6546 | |||
6547 | flags |= MGMT_ADV_FLAG_CONNECTABLE; | ||
6548 | flags |= MGMT_ADV_FLAG_DISCOV; | ||
6549 | flags |= MGMT_ADV_FLAG_LIMITED_DISCOV; | ||
6550 | flags |= MGMT_ADV_FLAG_MANAGED_FLAGS; | ||
6551 | |||
6552 | if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) | ||
6553 | flags |= MGMT_ADV_FLAG_TX_POWER; | ||
6554 | |||
6555 | return flags; | ||
6556 | } | ||
6557 | |||
6543 | static int read_adv_features(struct sock *sk, struct hci_dev *hdev, | 6558 | static int read_adv_features(struct sock *sk, struct hci_dev *hdev, |
6544 | void *data, u16 data_len) | 6559 | void *data, u16 data_len) |
6545 | { | 6560 | { |
@@ -6547,9 +6562,14 @@ static int read_adv_features(struct sock *sk, struct hci_dev *hdev, | |||
6547 | size_t rp_len; | 6562 | size_t rp_len; |
6548 | int err; | 6563 | int err; |
6549 | bool instance; | 6564 | bool instance; |
6565 | u32 supported_flags; | ||
6550 | 6566 | ||
6551 | BT_DBG("%s", hdev->name); | 6567 | BT_DBG("%s", hdev->name); |
6552 | 6568 | ||
6569 | if (!lmp_le_capable(hdev)) | ||
6570 | return mgmt_cmd_status(sk, hdev->id, MGMT_OP_READ_ADV_FEATURES, | ||
6571 | MGMT_STATUS_REJECTED); | ||
6572 | |||
6553 | hci_dev_lock(hdev); | 6573 | hci_dev_lock(hdev); |
6554 | 6574 | ||
6555 | rp_len = sizeof(*rp); | 6575 | rp_len = sizeof(*rp); |
@@ -6567,7 +6587,9 @@ static int read_adv_features(struct sock *sk, struct hci_dev *hdev, | |||
6567 | return -ENOMEM; | 6587 | return -ENOMEM; |
6568 | } | 6588 | } |
6569 | 6589 | ||
6570 | rp->supported_flags = cpu_to_le32(0); | 6590 | supported_flags = get_supported_adv_flags(hdev); |
6591 | |||
6592 | rp->supported_flags = cpu_to_le32(supported_flags); | ||
6571 | rp->max_adv_data_len = HCI_MAX_AD_LENGTH; | 6593 | rp->max_adv_data_len = HCI_MAX_AD_LENGTH; |
6572 | rp->max_scan_rsp_len = HCI_MAX_AD_LENGTH; | 6594 | rp->max_scan_rsp_len = HCI_MAX_AD_LENGTH; |
6573 | rp->max_instances = 1; | 6595 | rp->max_instances = 1; |
@@ -6689,6 +6711,7 @@ static int add_advertising(struct sock *sk, struct hci_dev *hdev, | |||
6689 | struct mgmt_cp_add_advertising *cp = data; | 6711 | struct mgmt_cp_add_advertising *cp = data; |
6690 | struct mgmt_rp_add_advertising rp; | 6712 | struct mgmt_rp_add_advertising rp; |
6691 | u32 flags; | 6713 | u32 flags; |
6714 | u32 supported_flags; | ||
6692 | u8 status; | 6715 | u8 status; |
6693 | u16 timeout; | 6716 | u16 timeout; |
6694 | int err; | 6717 | int err; |
@@ -6705,8 +6728,11 @@ static int add_advertising(struct sock *sk, struct hci_dev *hdev, | |||
6705 | flags = __le32_to_cpu(cp->flags); | 6728 | flags = __le32_to_cpu(cp->flags); |
6706 | timeout = __le16_to_cpu(cp->timeout); | 6729 | timeout = __le16_to_cpu(cp->timeout); |
6707 | 6730 | ||
6708 | /* The current implementation only supports adding one instance */ | 6731 | /* The current implementation only supports adding one instance and only |
6709 | if (cp->instance != 0x01) | 6732 | * a subset of the specified flags. |
6733 | */ | ||
6734 | supported_flags = get_supported_adv_flags(hdev); | ||
6735 | if (cp->instance != 0x01 || (flags & ~supported_flags)) | ||
6710 | return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING, | 6736 | return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING, |
6711 | MGMT_STATUS_INVALID_PARAMS); | 6737 | MGMT_STATUS_INVALID_PARAMS); |
6712 | 6738 | ||