Skip to content

Commit 8e8b92e

Browse files
Vudentzholtmann
authored andcommitted
Bluetooth: hci_sync: Add hci_le_create_conn_sync
This adds hci_le_create_conn_sync and make hci_le_connect use it instead of queueing multiple commands which may conflict with the likes of hci_update_passive_scan which uses hci_cmd_sync_queue. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
1 parent fee6450 commit 8e8b92e

File tree

8 files changed

+300
-349
lines changed

8 files changed

+300
-349
lines changed

include/net/bluetooth/hci_core.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,8 +1121,7 @@ struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
11211121
enum conn_reasons conn_reason);
11221122
struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
11231123
u8 dst_type, bool dst_resolved, u8 sec_level,
1124-
u16 conn_timeout, u8 role,
1125-
bdaddr_t *direct_rpa);
1124+
u16 conn_timeout, u8 role);
11261125
struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
11271126
u8 sec_level, u8 auth_type,
11281127
enum conn_reasons conn_reason);

include/net/bluetooth/hci_sync.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,7 @@ int hci_stop_discovery_sync(struct hci_dev *hdev);
102102

103103
int hci_suspend_sync(struct hci_dev *hdev);
104104
int hci_resume_sync(struct hci_dev *hdev);
105+
106+
struct hci_conn;
107+
108+
int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn);

net/bluetooth/hci_conn.c

Lines changed: 14 additions & 291 deletions
Original file line numberDiff line numberDiff line change
@@ -911,267 +911,45 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)
911911
hci_enable_advertising(hdev);
912912
}
913913

914-
static void create_le_conn_complete(struct hci_dev *hdev, u8 status, u16 opcode)
914+
static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err)
915915
{
916-
struct hci_conn *conn;
916+
struct hci_conn *conn = data;
917917

918918
hci_dev_lock(hdev);
919919

920-
conn = hci_lookup_le_connect(hdev);
921-
922-
if (hdev->adv_instance_cnt)
923-
hci_req_resume_adv_instances(hdev);
924-
925-
if (!status) {
920+
if (!err) {
926921
hci_connect_le_scan_cleanup(conn);
927922
goto done;
928923
}
929924

930-
bt_dev_err(hdev, "request failed to create LE connection: "
931-
"status 0x%2.2x", status);
925+
bt_dev_err(hdev, "request failed to create LE connection: err %d", err);
932926

933927
if (!conn)
934928
goto done;
935929

936-
hci_le_conn_failed(conn, status);
930+
hci_le_conn_failed(conn, err);
937931

938932
done:
939933
hci_dev_unlock(hdev);
940934
}
941935

942-
static bool conn_use_rpa(struct hci_conn *conn)
943-
{
944-
struct hci_dev *hdev = conn->hdev;
945-
946-
return hci_dev_test_flag(hdev, HCI_PRIVACY);
947-
}
948-
949-
static void set_ext_conn_params(struct hci_conn *conn,
950-
struct hci_cp_le_ext_conn_param *p)
951-
{
952-
struct hci_dev *hdev = conn->hdev;
953-
954-
memset(p, 0, sizeof(*p));
955-
956-
p->scan_interval = cpu_to_le16(hdev->le_scan_int_connect);
957-
p->scan_window = cpu_to_le16(hdev->le_scan_window_connect);
958-
p->conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
959-
p->conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
960-
p->conn_latency = cpu_to_le16(conn->le_conn_latency);
961-
p->supervision_timeout = cpu_to_le16(conn->le_supv_timeout);
962-
p->min_ce_len = cpu_to_le16(0x0000);
963-
p->max_ce_len = cpu_to_le16(0x0000);
964-
}
965-
966-
static void hci_req_add_le_create_conn(struct hci_request *req,
967-
struct hci_conn *conn,
968-
bdaddr_t *direct_rpa)
969-
{
970-
struct hci_dev *hdev = conn->hdev;
971-
u8 own_addr_type;
972-
973-
/* If direct address was provided we use it instead of current
974-
* address.
975-
*/
976-
if (direct_rpa) {
977-
if (bacmp(&req->hdev->random_addr, direct_rpa))
978-
hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6,
979-
direct_rpa);
980-
981-
/* direct address is always RPA */
982-
own_addr_type = ADDR_LE_DEV_RANDOM;
983-
} else {
984-
/* Update random address, but set require_privacy to false so
985-
* that we never connect with an non-resolvable address.
986-
*/
987-
if (hci_update_random_address(req, false, conn_use_rpa(conn),
988-
&own_addr_type))
989-
return;
990-
}
991-
992-
if (use_ext_conn(hdev)) {
993-
struct hci_cp_le_ext_create_conn *cp;
994-
struct hci_cp_le_ext_conn_param *p;
995-
u8 data[sizeof(*cp) + sizeof(*p) * 3];
996-
u32 plen;
997-
998-
cp = (void *) data;
999-
p = (void *) cp->data;
1000-
1001-
memset(cp, 0, sizeof(*cp));
1002-
1003-
bacpy(&cp->peer_addr, &conn->dst);
1004-
cp->peer_addr_type = conn->dst_type;
1005-
cp->own_addr_type = own_addr_type;
1006-
1007-
plen = sizeof(*cp);
1008-
1009-
if (scan_1m(hdev)) {
1010-
cp->phys |= LE_SCAN_PHY_1M;
1011-
set_ext_conn_params(conn, p);
1012-
1013-
p++;
1014-
plen += sizeof(*p);
1015-
}
1016-
1017-
if (scan_2m(hdev)) {
1018-
cp->phys |= LE_SCAN_PHY_2M;
1019-
set_ext_conn_params(conn, p);
1020-
1021-
p++;
1022-
plen += sizeof(*p);
1023-
}
1024-
1025-
if (scan_coded(hdev)) {
1026-
cp->phys |= LE_SCAN_PHY_CODED;
1027-
set_ext_conn_params(conn, p);
1028-
1029-
plen += sizeof(*p);
1030-
}
1031-
1032-
hci_req_add(req, HCI_OP_LE_EXT_CREATE_CONN, plen, data);
1033-
1034-
} else {
1035-
struct hci_cp_le_create_conn cp;
1036-
1037-
memset(&cp, 0, sizeof(cp));
1038-
1039-
cp.scan_interval = cpu_to_le16(hdev->le_scan_int_connect);
1040-
cp.scan_window = cpu_to_le16(hdev->le_scan_window_connect);
1041-
1042-
bacpy(&cp.peer_addr, &conn->dst);
1043-
cp.peer_addr_type = conn->dst_type;
1044-
cp.own_address_type = own_addr_type;
1045-
cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
1046-
cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
1047-
cp.conn_latency = cpu_to_le16(conn->le_conn_latency);
1048-
cp.supervision_timeout = cpu_to_le16(conn->le_supv_timeout);
1049-
cp.min_ce_len = cpu_to_le16(0x0000);
1050-
cp.max_ce_len = cpu_to_le16(0x0000);
1051-
1052-
hci_req_add(req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
1053-
}
1054-
1055-
conn->state = BT_CONNECT;
1056-
clear_bit(HCI_CONN_SCANNING, &conn->flags);
1057-
}
1058-
1059-
static void hci_req_directed_advertising(struct hci_request *req,
1060-
struct hci_conn *conn)
936+
static int hci_connect_le_sync(struct hci_dev *hdev, void *data)
1061937
{
1062-
struct hci_dev *hdev = req->hdev;
1063-
u8 own_addr_type;
1064-
u8 enable;
1065-
1066-
if (ext_adv_capable(hdev)) {
1067-
struct hci_cp_le_set_ext_adv_params cp;
1068-
bdaddr_t random_addr;
1069-
1070-
/* Set require_privacy to false so that the remote device has a
1071-
* chance of identifying us.
1072-
*/
1073-
if (hci_get_random_address(hdev, false, conn_use_rpa(conn), NULL,
1074-
&own_addr_type, &random_addr) < 0)
1075-
return;
1076-
1077-
memset(&cp, 0, sizeof(cp));
1078-
1079-
cp.evt_properties = cpu_to_le16(LE_LEGACY_ADV_DIRECT_IND);
1080-
cp.own_addr_type = own_addr_type;
1081-
cp.channel_map = hdev->le_adv_channel_map;
1082-
cp.tx_power = HCI_TX_POWER_INVALID;
1083-
cp.primary_phy = HCI_ADV_PHY_1M;
1084-
cp.secondary_phy = HCI_ADV_PHY_1M;
1085-
cp.handle = 0; /* Use instance 0 for directed adv */
1086-
cp.own_addr_type = own_addr_type;
1087-
cp.peer_addr_type = conn->dst_type;
1088-
bacpy(&cp.peer_addr, &conn->dst);
1089-
1090-
/* As per Core Spec 5.2 Vol 2, PART E, Sec 7.8.53, for
1091-
* advertising_event_property LE_LEGACY_ADV_DIRECT_IND
1092-
* does not supports advertising data when the advertising set already
1093-
* contains some, the controller shall return erroc code 'Invalid
1094-
* HCI Command Parameters(0x12).
1095-
* So it is required to remove adv set for handle 0x00. since we use
1096-
* instance 0 for directed adv.
1097-
*/
1098-
__hci_req_remove_ext_adv_instance(req, cp.handle);
1099-
1100-
hci_req_add(req, HCI_OP_LE_SET_EXT_ADV_PARAMS, sizeof(cp), &cp);
938+
struct hci_conn *conn = data;
1101939

1102-
if (own_addr_type == ADDR_LE_DEV_RANDOM &&
1103-
bacmp(&random_addr, BDADDR_ANY) &&
1104-
bacmp(&random_addr, &hdev->random_addr)) {
1105-
struct hci_cp_le_set_adv_set_rand_addr cp;
1106-
1107-
memset(&cp, 0, sizeof(cp));
1108-
1109-
cp.handle = 0;
1110-
bacpy(&cp.bdaddr, &random_addr);
1111-
1112-
hci_req_add(req,
1113-
HCI_OP_LE_SET_ADV_SET_RAND_ADDR,
1114-
sizeof(cp), &cp);
1115-
}
1116-
1117-
__hci_req_enable_ext_advertising(req, 0x00);
1118-
} else {
1119-
struct hci_cp_le_set_adv_param cp;
940+
bt_dev_dbg(hdev, "conn %p", conn);
1120941

1121-
/* Clear the HCI_LE_ADV bit temporarily so that the
1122-
* hci_update_random_address knows that it's safe to go ahead
1123-
* and write a new random address. The flag will be set back on
1124-
* as soon as the SET_ADV_ENABLE HCI command completes.
1125-
*/
1126-
hci_dev_clear_flag(hdev, HCI_LE_ADV);
1127-
1128-
/* Set require_privacy to false so that the remote device has a
1129-
* chance of identifying us.
1130-
*/
1131-
if (hci_update_random_address(req, false, conn_use_rpa(conn),
1132-
&own_addr_type) < 0)
1133-
return;
1134-
1135-
memset(&cp, 0, sizeof(cp));
1136-
1137-
/* Some controllers might reject command if intervals are not
1138-
* within range for undirected advertising.
1139-
* BCM20702A0 is known to be affected by this.
1140-
*/
1141-
cp.min_interval = cpu_to_le16(0x0020);
1142-
cp.max_interval = cpu_to_le16(0x0020);
1143-
1144-
cp.type = LE_ADV_DIRECT_IND;
1145-
cp.own_address_type = own_addr_type;
1146-
cp.direct_addr_type = conn->dst_type;
1147-
bacpy(&cp.direct_addr, &conn->dst);
1148-
cp.channel_map = hdev->le_adv_channel_map;
1149-
1150-
hci_req_add(req, HCI_OP_LE_SET_ADV_PARAM, sizeof(cp), &cp);
1151-
1152-
enable = 0x01;
1153-
hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable),
1154-
&enable);
1155-
}
1156-
1157-
conn->state = BT_CONNECT;
942+
return hci_le_create_conn_sync(hdev, conn);
1158943
}
1159944

1160945
struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
1161946
u8 dst_type, bool dst_resolved, u8 sec_level,
1162-
u16 conn_timeout, u8 role, bdaddr_t *direct_rpa)
947+
u16 conn_timeout, u8 role)
1163948
{
1164-
struct hci_conn_params *params;
1165949
struct hci_conn *conn;
1166950
struct smp_irk *irk;
1167-
struct hci_request req;
1168951
int err;
1169952

1170-
/* This ensures that during disable le_scan address resolution
1171-
* will not be disabled if it is followed by le_create_conn
1172-
*/
1173-
bool rpa_le_conn = true;
1174-
1175953
/* Let's make sure that le is enabled.*/
1176954
if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
1177955
if (lmp_le_capable(hdev))
@@ -1230,68 +1008,13 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
12301008
conn->sec_level = BT_SECURITY_LOW;
12311009
conn->conn_timeout = conn_timeout;
12321010

1233-
hci_req_init(&req, hdev);
1234-
1235-
/* Disable advertising if we're active. For central role
1236-
* connections most controllers will refuse to connect if
1237-
* advertising is enabled, and for peripheral role connections we
1238-
* anyway have to disable it in order to start directed
1239-
* advertising. Any registered advertisements will be
1240-
* re-enabled after the connection attempt is finished.
1241-
*/
1242-
if (hci_dev_test_flag(hdev, HCI_LE_ADV))
1243-
__hci_req_pause_adv_instances(&req);
1244-
1245-
/* If requested to connect as peripheral use directed advertising */
1246-
if (conn->role == HCI_ROLE_SLAVE) {
1247-
/* If we're active scanning most controllers are unable
1248-
* to initiate advertising. Simply reject the attempt.
1249-
*/
1250-
if (hci_dev_test_flag(hdev, HCI_LE_SCAN) &&
1251-
hdev->le_scan_type == LE_SCAN_ACTIVE) {
1252-
hci_req_purge(&req);
1253-
hci_conn_del(conn);
1254-
return ERR_PTR(-EBUSY);
1255-
}
1256-
1257-
hci_req_directed_advertising(&req, conn);
1258-
goto create_conn;
1259-
}
1260-
1261-
params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
1262-
if (params) {
1263-
conn->le_conn_min_interval = params->conn_min_interval;
1264-
conn->le_conn_max_interval = params->conn_max_interval;
1265-
conn->le_conn_latency = params->conn_latency;
1266-
conn->le_supv_timeout = params->supervision_timeout;
1267-
} else {
1268-
conn->le_conn_min_interval = hdev->le_conn_min_interval;
1269-
conn->le_conn_max_interval = hdev->le_conn_max_interval;
1270-
conn->le_conn_latency = hdev->le_conn_latency;
1271-
conn->le_supv_timeout = hdev->le_supv_timeout;
1272-
}
1273-
1274-
/* If controller is scanning, we stop it since some controllers are
1275-
* not able to scan and connect at the same time. Also set the
1276-
* HCI_LE_SCAN_INTERRUPTED flag so that the command complete
1277-
* handler for scan disabling knows to set the correct discovery
1278-
* state.
1279-
*/
1280-
if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
1281-
hci_req_add_le_scan_disable(&req, rpa_le_conn);
1282-
hci_dev_set_flag(hdev, HCI_LE_SCAN_INTERRUPTED);
1283-
}
1284-
1285-
hci_req_add_le_create_conn(&req, conn, direct_rpa);
1011+
conn->state = BT_CONNECT;
1012+
clear_bit(HCI_CONN_SCANNING, &conn->flags);
12861013

1287-
create_conn:
1288-
err = hci_req_run(&req, create_le_conn_complete);
1014+
err = hci_cmd_sync_queue(hdev, hci_connect_le_sync, conn,
1015+
create_le_conn_complete);
12891016
if (err) {
12901017
hci_conn_del(conn);
1291-
1292-
if (hdev->adv_instance_cnt)
1293-
hci_req_resume_adv_instances(hdev);
1294-
12951018
return ERR_PTR(err);
12961019
}
12971020

net/bluetooth/hci_event.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5755,7 +5755,7 @@ static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, void *data,
57555755
static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
57565756
bdaddr_t *addr,
57575757
u8 addr_type, bool addr_resolved,
5758-
u8 adv_type, bdaddr_t *direct_rpa)
5758+
u8 adv_type)
57595759
{
57605760
struct hci_conn *conn;
57615761
struct hci_conn_params *params;
@@ -5810,7 +5810,7 @@ static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
58105810

58115811
conn = hci_connect_le(hdev, addr, addr_type, addr_resolved,
58125812
BT_SECURITY_LOW, hdev->def_le_autoconnect_timeout,
5813-
HCI_ROLE_MASTER, direct_rpa);
5813+
HCI_ROLE_MASTER);
58145814
if (!IS_ERR(conn)) {
58155815
/* If HCI_AUTO_CONN_EXPLICIT is set, conn is already owned
58165816
* by higher layer that tried to connect, if no then
@@ -5933,7 +5933,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
59335933
* for advertising reports) and is already verified to be RPA above.
59345934
*/
59355935
conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, bdaddr_resolved,
5936-
type, direct_addr);
5936+
type);
59375937
if (!ext_adv && conn && type == LE_ADV_IND && len <= HCI_MAX_AD_LENGTH) {
59385938
/* Store report for later inclusion by
59395939
* mgmt_device_connected

0 commit comments

Comments
 (0)