diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2014-02-25 12:56:31 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-02-25 13:02:53 -0500 |
commit | a4858cb942b9afa57c1220aa5d9b536a0d7ec623 (patch) | |
tree | ee39ea92d8c10355c73fc372ba734c63f2d8636e /net/bluetooth | |
parent | ede81a2a1250dc9296a2b9bf384bba4e336a02e2 (diff) |
Bluetooth: Fix advertising address type when toggling connectable
When the connectable setting is toggled using mgmt_set_connectable the
HCI_CONNECTABLE flag will only be set once the related HCI commands
succeed. When determining what kind of advertising to do we need to
therefore also check whether there is a pending Set Connectable command
in addition to the current flag value.
The enable_advertising function was already taking care of this for the
advertising type with the help of the get_adv_type function, but was
failing to do the same for the address type selection. This patch
converts the get_adv_type function to be more generic in that it returns
the expected connectable state and updates the enable_advertising
function to use the return value both for the advertising type as well
as the advertising address type.
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/mgmt.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 25b8b278debd..d6e269287cfc 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -817,10 +817,9 @@ static void update_class(struct hci_request *req) | |||
817 | hci_req_add(req, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod); | 817 | hci_req_add(req, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod); |
818 | } | 818 | } |
819 | 819 | ||
820 | static u8 get_adv_type(struct hci_dev *hdev) | 820 | static bool get_connectable(struct hci_dev *hdev) |
821 | { | 821 | { |
822 | struct pending_cmd *cmd; | 822 | struct pending_cmd *cmd; |
823 | bool connectable; | ||
824 | 823 | ||
825 | /* If there's a pending mgmt command the flag will not yet have | 824 | /* If there's a pending mgmt command the flag will not yet have |
826 | * it's final value, so check for this first. | 825 | * it's final value, so check for this first. |
@@ -828,12 +827,10 @@ static u8 get_adv_type(struct hci_dev *hdev) | |||
828 | cmd = mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev); | 827 | cmd = mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev); |
829 | if (cmd) { | 828 | if (cmd) { |
830 | struct mgmt_mode *cp = cmd->param; | 829 | struct mgmt_mode *cp = cmd->param; |
831 | connectable = !!cp->val; | 830 | return cp->val; |
832 | } else { | ||
833 | connectable = test_bit(HCI_CONNECTABLE, &hdev->dev_flags); | ||
834 | } | 831 | } |
835 | 832 | ||
836 | return connectable ? LE_ADV_IND : LE_ADV_NONCONN_IND; | 833 | return test_bit(HCI_CONNECTABLE, &hdev->dev_flags); |
837 | } | 834 | } |
838 | 835 | ||
839 | static void enable_advertising(struct hci_request *req) | 836 | static void enable_advertising(struct hci_request *req) |
@@ -841,17 +838,21 @@ static void enable_advertising(struct hci_request *req) | |||
841 | struct hci_dev *hdev = req->hdev; | 838 | struct hci_dev *hdev = req->hdev; |
842 | struct hci_cp_le_set_adv_param cp; | 839 | struct hci_cp_le_set_adv_param cp; |
843 | u8 own_addr_type, enable = 0x01; | 840 | u8 own_addr_type, enable = 0x01; |
844 | bool require_privacy; | 841 | bool connectable; |
845 | 842 | ||
846 | require_privacy = !test_bit(HCI_CONNECTABLE, &hdev->dev_flags); | 843 | connectable = get_connectable(hdev); |
847 | 844 | ||
848 | if (hci_update_random_address(req, require_privacy, &own_addr_type) < 0) | 845 | /* Set require_privacy to true only when non-connectable |
846 | * advertising is used. In that case it is fine to use a | ||
847 | * non-resolvable private address. | ||
848 | */ | ||
849 | if (hci_update_random_address(req, !connectable, &own_addr_type) < 0) | ||
849 | return; | 850 | return; |
850 | 851 | ||
851 | memset(&cp, 0, sizeof(cp)); | 852 | memset(&cp, 0, sizeof(cp)); |
852 | cp.min_interval = __constant_cpu_to_le16(0x0800); | 853 | cp.min_interval = __constant_cpu_to_le16(0x0800); |
853 | cp.max_interval = __constant_cpu_to_le16(0x0800); | 854 | cp.max_interval = __constant_cpu_to_le16(0x0800); |
854 | cp.type = get_adv_type(hdev); | 855 | cp.type = connectable ? LE_ADV_IND : LE_ADV_NONCONN_IND; |
855 | cp.own_address_type = own_addr_type; | 856 | cp.own_address_type = own_addr_type; |
856 | cp.channel_map = hdev->le_adv_channel_map; | 857 | cp.channel_map = hdev->le_adv_channel_map; |
857 | 858 | ||