aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_request.c
diff options
context:
space:
mode:
authorŁukasz Rymanowski <lukasz.rymanowski@codecoup.pl>2017-12-08 07:40:57 -0500
committerMarcel Holtmann <marcel@holtmann.org>2017-12-13 03:41:37 -0500
commit9e1e9f20ca96026c56ac613317ea4bf01c6c3385 (patch)
tree56117e225b5e1ecea03a1158131da87f5278b8df /net/bluetooth/hci_request.c
parent4166493c97c0c70e8d7678422c2214dc5ec6e9d3 (diff)
Bluetooth: Add support to advertise when connected
So far, kernel did not allow to advertise when there was a connection established. With this patch kernel does allow it if controller supports it. If controller supports non-connectable advertising when connected, then only non-connectable advertising instances will be advertised. Signed-off-by: Łukasz Rymanowski <lukasz.rymanowski@codecoup.pl> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/hci_request.c')
-rw-r--r--net/bluetooth/hci_request.c55
1 files changed, 46 insertions, 9 deletions
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index da59f82754bc..3394e6791673 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -919,6 +919,43 @@ static bool adv_use_rpa(struct hci_dev *hdev, uint32_t flags)
919 return true; 919 return true;
920} 920}
921 921
922static bool is_advertising_allowed(struct hci_dev *hdev, bool connectable)
923{
924 /* If there is no connection we are OK to advertise. */
925 if (hci_conn_num(hdev, LE_LINK) == 0)
926 return true;
927
928 /* Check le_states if there is any connection in slave role. */
929 if (hdev->conn_hash.le_num_slave > 0) {
930 /* Slave connection state and non connectable mode bit 20. */
931 if (!connectable && !(hdev->le_states[2] & 0x10))
932 return false;
933
934 /* Slave connection state and connectable mode bit 38
935 * and scannable bit 21.
936 */
937 if (connectable && (!(hdev->le_states[4] & 0x01) ||
938 !(hdev->le_states[2] & 0x40)))
939 return false;
940 }
941
942 /* Check le_states if there is any connection in master role. */
943 if (hci_conn_num(hdev, LE_LINK) != hdev->conn_hash.le_num_slave) {
944 /* Master connection state and non connectable mode bit 18. */
945 if (!connectable && !(hdev->le_states[2] & 0x02))
946 return false;
947
948 /* Master connection state and connectable mode bit 35 and
949 * scannable 19.
950 */
951 if (connectable && (!(hdev->le_states[4] & 0x10) ||
952 !(hdev->le_states[2] & 0x08)))
953 return false;
954 }
955
956 return true;
957}
958
922void __hci_req_enable_advertising(struct hci_request *req) 959void __hci_req_enable_advertising(struct hci_request *req)
923{ 960{
924 struct hci_dev *hdev = req->hdev; 961 struct hci_dev *hdev = req->hdev;
@@ -927,7 +964,15 @@ void __hci_req_enable_advertising(struct hci_request *req)
927 bool connectable; 964 bool connectable;
928 u32 flags; 965 u32 flags;
929 966
930 if (hci_conn_num(hdev, LE_LINK) > 0) 967 flags = get_adv_instance_flags(hdev, hdev->cur_adv_instance);
968
969 /* If the "connectable" instance flag was not set, then choose between
970 * ADV_IND and ADV_NONCONN_IND based on the global connectable setting.
971 */
972 connectable = (flags & MGMT_ADV_FLAG_CONNECTABLE) ||
973 mgmt_get_connectable(hdev);
974
975 if (!is_advertising_allowed(hdev, connectable))
931 return; 976 return;
932 977
933 if (hci_dev_test_flag(hdev, HCI_LE_ADV)) 978 if (hci_dev_test_flag(hdev, HCI_LE_ADV))
@@ -940,14 +985,6 @@ void __hci_req_enable_advertising(struct hci_request *req)
940 */ 985 */
941 hci_dev_clear_flag(hdev, HCI_LE_ADV); 986 hci_dev_clear_flag(hdev, HCI_LE_ADV);
942 987
943 flags = get_adv_instance_flags(hdev, hdev->cur_adv_instance);
944
945 /* If the "connectable" instance flag was not set, then choose between
946 * ADV_IND and ADV_NONCONN_IND based on the global connectable setting.
947 */
948 connectable = (flags & MGMT_ADV_FLAG_CONNECTABLE) ||
949 mgmt_get_connectable(hdev);
950
951 /* Set require_privacy to true only when non-connectable 988 /* Set require_privacy to true only when non-connectable
952 * advertising is used. In that case it is fine to use a 989 * advertising is used. In that case it is fine to use a
953 * non-resolvable private address. 990 * non-resolvable private address.