diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index d0d08e5df12..f027f98162c 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -362,7 +362,7 @@ static void conn_update_timeout(struct k_work *work) * auto connect flag if it was set, instead just cancel * connection directly */ - bt_hci_cmd_send(BT_HCI_OP_LE_CREATE_CONN_CANCEL, NULL); + bt_le_create_conn_cancel(); return; } @@ -2071,8 +2071,7 @@ int bt_conn_disconnect(struct bt_conn *conn, u8_t reason) if (IS_ENABLED(CONFIG_BT_CENTRAL)) { k_delayed_work_cancel(&conn->update_work); - return bt_hci_cmd_send(BT_HCI_OP_LE_CREATE_CONN_CANCEL, - NULL); + return bt_le_create_conn_cancel(); } return 0; @@ -2110,25 +2109,20 @@ int bt_conn_create_auto_le(const struct bt_le_conn_param *param) return -EINVAL; } - if (atomic_test_bit(bt_dev.flags, BT_DEV_EXPLICIT_SCAN)) { - return -EINVAL; - } - - if (atomic_test_bit(bt_dev.flags, BT_DEV_AUTO_CONN)) { + conn = bt_conn_lookup_state_le(BT_ADDR_LE_NONE, BT_CONN_CONNECT_AUTO); + if (conn) { + bt_conn_unref(conn); return -EALREADY; } - /* Don't start initiator if we have general discovery procedure. */ - conn = bt_conn_lookup_state_le(NULL, BT_CONN_CONNECT_SCAN); - if (conn) { - bt_conn_unref(conn); + /* Scanning either to connect or explicit scan, either case scanner was + * started by application and should not be stopped. + */ + if (atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING)) { return -EINVAL; } - /* Don't start initiator if we have direct discovery procedure. */ - conn = bt_conn_lookup_state_le(NULL, BT_CONN_CONNECT); - if (conn) { - bt_conn_unref(conn); + if (atomic_test_bit(bt_dev.flags, BT_DEV_INITIATING)) { return -EINVAL; } @@ -2137,9 +2131,11 @@ int bt_conn_create_auto_le(const struct bt_le_conn_param *param) return -ENOMEM; } + atomic_set_bit(conn->flags, BT_CONN_AUTO_CONNECT); + bt_conn_set_param_le(conn, param); bt_conn_set_state(conn, BT_CONN_CONNECT_AUTO); - err = bt_le_auto_conn(param); + err = bt_le_create_conn(conn); if (err) { BT_ERR("Failed to start whitelist scan"); @@ -2164,17 +2160,19 @@ int bt_conn_create_auto_stop(void) return -EINVAL; } - if (!atomic_test_bit(bt_dev.flags, BT_DEV_AUTO_CONN)) { + conn = bt_conn_lookup_state_le(BT_ADDR_LE_NONE, BT_CONN_CONNECT_AUTO); + if (!conn) { return -EINVAL; } - conn = bt_conn_lookup_state_le(BT_ADDR_LE_NONE, BT_CONN_CONNECT_AUTO); - if (conn) { - bt_conn_set_state(conn, BT_CONN_DISCONNECTED); - bt_conn_unref(conn); + if (!atomic_test_bit(bt_dev.flags, BT_DEV_INITIATING)) { + return -EINVAL; } - err = bt_le_auto_conn_cancel(); + bt_conn_set_state(conn, BT_CONN_DISCONNECTED); + bt_conn_unref(conn); + + err = bt_le_create_conn_cancel(); if (err) { BT_ERR("Failed to stop initiator"); return err; @@ -2202,8 +2200,7 @@ struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer, return NULL; } - if (IS_ENABLED(CONFIG_BT_WHITELIST) && - atomic_test_bit(bt_dev.flags, BT_DEV_AUTO_CONN)) { + if (atomic_test_bit(bt_dev.flags, BT_DEV_INITIATING)) { return NULL; } @@ -2250,7 +2247,7 @@ struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer, #endif bt_conn_set_state(conn, BT_CONN_CONNECT); - if (bt_le_direct_conn(conn)) { + if (bt_le_create_conn(conn)) { bt_conn_set_state(conn, BT_CONN_DISCONNECTED); bt_conn_unref(conn); diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index a792b19ebfd..6cb9ccf0d3c 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -740,20 +740,17 @@ static void hci_num_completed_packets(struct net_buf *buf) } #if defined(CONFIG_BT_CENTRAL) -#if defined(CONFIG_BT_WHITELIST) -int bt_le_auto_conn(const struct bt_le_conn_param *conn_param) +int bt_le_create_conn(const struct bt_conn *conn) { - struct net_buf *buf; - struct cmd_state_set state; struct bt_hci_cp_le_create_conn *cp; + struct cmd_state_set state; + bool use_filter = false; + struct net_buf *buf; u8_t own_addr_type; int err; - if (atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING)) { - err = set_le_scan_enable(BT_HCI_LE_SCAN_DISABLE); - if (err) { - return err; - } + if (IS_ENABLED(CONFIG_BT_WHITELIST)) { + use_filter = atomic_test_bit(conn->flags, BT_CONN_AUTO_CONNECT); } if (IS_ENABLED(CONFIG_BT_PRIVACY)) { @@ -789,103 +786,54 @@ int bt_le_auto_conn(const struct bt_le_conn_param *conn_param) } cp = net_buf_add(buf, sizeof(*cp)); - (void)memset(cp, 0, sizeof(*cp)); - - cp->filter_policy = BT_HCI_LE_CREATE_CONN_FP_WHITELIST; cp->own_addr_type = own_addr_type; - /* User Initiated procedure use fast scan parameters. */ - cp->scan_interval = sys_cpu_to_le16(BT_GAP_SCAN_FAST_INTERVAL); - cp->scan_window = sys_cpu_to_le16(BT_GAP_SCAN_FAST_WINDOW); + if (use_filter) { + /* User Initiated procedure use fast scan parameters. */ + bt_addr_le_copy(&cp->peer_addr, BT_ADDR_LE_ANY); + cp->filter_policy = BT_HCI_LE_CREATE_CONN_FP_WHITELIST; + cp->scan_interval = sys_cpu_to_le16(BT_GAP_SCAN_FAST_INTERVAL); + cp->scan_window = sys_cpu_to_le16(BT_GAP_SCAN_FAST_WINDOW); + } else { + const bt_addr_le_t *peer_addr = &conn->le.dst; - cp->conn_interval_min = sys_cpu_to_le16(conn_param->interval_min); - cp->conn_interval_max = sys_cpu_to_le16(conn_param->interval_max); - cp->conn_latency = sys_cpu_to_le16(conn_param->latency); - cp->supervision_timeout = sys_cpu_to_le16(conn_param->timeout); +#if defined(CONFIG_BT_SMP) + if (!bt_dev.le.rl_size || + bt_dev.le.rl_entries > bt_dev.le.rl_size) { + /* Host resolving is used, use the RPA directly. */ + peer_addr = &conn->le.resp_addr; + } +#endif + bt_addr_le_copy(&cp->peer_addr, peer_addr); + cp->filter_policy = BT_HCI_LE_CREATE_CONN_FP_DIRECT; + /* Interval == window for continuous scanning */ + cp->scan_interval = sys_cpu_to_le16(BT_GAP_SCAN_FAST_INTERVAL); + cp->scan_window = cp->scan_interval; + } - cmd_state_set_init(&state, bt_dev.flags, BT_DEV_AUTO_CONN, true); + cp->conn_interval_min = sys_cpu_to_le16(conn->le.interval_min); + cp->conn_interval_max = sys_cpu_to_le16(conn->le.interval_max); + cp->conn_latency = sys_cpu_to_le16(conn->le.latency); + cp->supervision_timeout = sys_cpu_to_le16(conn->le.timeout); + + cmd_state_set_init(&state, bt_dev.flags, BT_DEV_INITIATING, true); cmd(buf)->state = &state; return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CREATE_CONN, buf, NULL); } -int bt_le_auto_conn_cancel(void) +int bt_le_create_conn_cancel(void) { struct net_buf *buf; struct cmd_state_set state; buf = bt_hci_cmd_create(BT_HCI_OP_LE_CREATE_CONN_CANCEL, 0); - cmd_state_set_init(&state, bt_dev.flags, BT_DEV_AUTO_CONN, false); + cmd_state_set_init(&state, bt_dev.flags, BT_DEV_INITIATING, false); cmd(buf)->state = &state; return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CREATE_CONN_CANCEL, buf, NULL); } -#endif /* defined(CONFIG_BT_WHITELIST) */ -int bt_le_direct_conn(const struct bt_conn *conn) -{ - struct net_buf *buf; - struct bt_hci_cp_le_create_conn *cp; - u8_t own_addr_type; - const bt_addr_le_t *peer_addr; - int err; - - if (IS_ENABLED(CONFIG_BT_PRIVACY)) { - err = le_set_private_addr(conn->id); - if (err) { - return err; - } - - if (BT_FEAT_LE_PRIVACY(bt_dev.le.features)) { - own_addr_type = BT_HCI_OWN_ADDR_RPA_OR_RANDOM; - } else { - own_addr_type = BT_ADDR_LE_RANDOM; - } - } else { - /* If Static Random address is used as Identity address we - * need to restore it before creating connection. Otherwise - * NRPA used for active scan could be used for connection. - */ - const bt_addr_le_t *own_addr = &bt_dev.id_addr[conn->id]; - - if (own_addr->type == BT_ADDR_LE_RANDOM) { - err = set_random_address(&own_addr->a); - if (err) { - return err; - } - } - - own_addr_type = own_addr->type; - } - - buf = bt_hci_cmd_create(BT_HCI_OP_LE_CREATE_CONN, sizeof(*cp)); - if (!buf) { - return -ENOBUFS; - } - - cp = net_buf_add(buf, sizeof(*cp)); - (void)memset(cp, 0, sizeof(*cp)); - - /* Interval == window for continuous scanning */ - cp->scan_interval = sys_cpu_to_le16(BT_GAP_SCAN_FAST_INTERVAL); - cp->scan_window = cp->scan_interval; - - peer_addr = &conn->le.dst; -#if defined(CONFIG_BT_SMP) - if (!bt_dev.le.rl_size || bt_dev.le.rl_entries > bt_dev.le.rl_size) { - /* Host resolving is used, use the RPA directly. */ - peer_addr = &conn->le.resp_addr; - } -#endif - bt_addr_le_copy(&cp->peer_addr, peer_addr); - cp->own_addr_type = own_addr_type; - cp->conn_interval_min = sys_cpu_to_le16(conn->le.interval_min); - cp->conn_interval_max = sys_cpu_to_le16(conn->le.interval_max); - cp->conn_latency = sys_cpu_to_le16(conn->le.latency); - cp->supervision_timeout = sys_cpu_to_le16(conn->le.timeout); - - return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CREATE_CONN, buf, NULL); -} #endif /* CONFIG_BT_CENTRAL */ int bt_hci_disconnect(u16_t handle, u8_t reason) @@ -1290,12 +1238,11 @@ static void enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt) } if (IS_ENABLED(CONFIG_BT_CENTRAL) && - IS_ENABLED(CONFIG_BT_WHITELIST) && evt->role == BT_HCI_ROLE_MASTER) { - /* Clear auto conn even if we are not able to add connection + /* Clear initiating even if we are not able to add connection * object to keep the host in sync with controller state. */ - atomic_clear_bit(bt_dev.flags, BT_DEV_AUTO_CONN); + atomic_clear_bit(bt_dev.flags, BT_DEV_INITIATING); } if (!conn) { @@ -1657,7 +1604,7 @@ static void check_pending_conn(const bt_addr_le_t *id_addr, } bt_addr_le_copy(&conn->le.resp_addr, addr); - if (bt_le_direct_conn(conn)) { + if (bt_le_create_conn(conn)) { goto failed; } diff --git a/subsys/bluetooth/host/hci_core.h b/subsys/bluetooth/host/hci_core.h index 92df9da1947..56b76f1b688 100644 --- a/subsys/bluetooth/host/hci_core.h +++ b/subsys/bluetooth/host/hci_core.h @@ -42,7 +42,7 @@ enum { BT_DEV_ACTIVE_SCAN, BT_DEV_SCAN_FILTER_DUP, BT_DEV_SCAN_WL, - BT_DEV_AUTO_CONN, + BT_DEV_INITIATING, BT_DEV_RPA_VALID, @@ -187,9 +187,8 @@ bool bt_le_conn_params_valid(const struct bt_le_conn_param *param); int bt_le_scan_update(bool fast_scan); -int bt_le_direct_conn(const struct bt_conn *conn); -int bt_le_auto_conn(const struct bt_le_conn_param *conn_param); -int bt_le_auto_conn_cancel(void); +int bt_le_create_conn(const struct bt_conn *conn); +int bt_le_create_conn_cancel(void); bool bt_addr_le_is_bonded(u8_t id, const bt_addr_le_t *addr); const bt_addr_le_t *bt_lookup_id_addr(u8_t id, const bt_addr_le_t *addr);