diff --git a/include/bluetooth/conn.h b/include/bluetooth/conn.h index a55219b9321..358503e263d 100644 --- a/include/bluetooth/conn.h +++ b/include/bluetooth/conn.h @@ -34,6 +34,8 @@ #ifndef __BT_CONN_H #define __BT_CONN_H +#include + #include /** Opaque type representing a connection to a remote device */ @@ -93,4 +95,18 @@ struct bt_conn_cb { */ void bt_conn_cb_register(struct bt_conn_cb *cb); +/** @brief Automatically connect to remote device if it's in range. + * + * This function enables/disables automatic connection initiation. + * Everytime the device looses the connection with peer, this connection + * will be re-established if connectable advertisement from peer is received. + * + * @param conn Existing connection object. + * @param auto_conn boolean value. If true, auto connect is enabled, + * if false, auto connect is disabled. + * + * @return none + */ +void bt_conn_set_auto_conn(struct bt_conn *conn, bool auto_conn); + #endif /* __BT_CONN_H */ diff --git a/net/bluetooth/conn.c b/net/bluetooth/conn.c index b563bf734d6..ff8d47cd685 100644 --- a/net/bluetooth/conn.c +++ b/net/bluetooth/conn.c @@ -465,3 +465,12 @@ int bt_security(struct bt_conn *conn, bt_security_t sec) return bt_smp_send_pairing_req(conn); } + +void bt_conn_set_auto_conn(struct bt_conn *conn, bool auto_conn) +{ + if (auto_conn) { + atomic_set_bit(conn->flags, BT_CONN_AUTO_CONNECT); + } else { + atomic_clear_bit(conn->flags, BT_CONN_AUTO_CONNECT); + } +} diff --git a/net/bluetooth/conn_internal.h b/net/bluetooth/conn_internal.h index 59bc71f0d00..4f8476d651a 100644 --- a/net/bluetooth/conn_internal.h +++ b/net/bluetooth/conn_internal.h @@ -48,10 +48,16 @@ struct bt_conn_l2cap { uint8_t ident; }; +/* bt_conn flags: the flags defined here represent connection parameters */ +enum { + BT_CONN_AUTO_CONNECT, +}; + struct bt_conn { struct bt_dev *dev; uint16_t handle; uint8_t role; + atomic_t flags[1]; bt_addr_le_t src; bt_addr_le_t dst; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 8bee8bfce07..1c7eb9f68d8 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -691,6 +691,12 @@ static void hci_disconn_complete(struct bt_buf *buf) bt_conn_set_state(conn, BT_CONN_DISCONNECTED); conn->handle = 0; + + if (atomic_test_bit(conn->flags, BT_CONN_AUTO_CONNECT)) { + bt_conn_set_state(conn, BT_CONN_CONNECT_SCAN); + trigger_scan(); + } + bt_conn_put(conn); if (dev.adv_enable) { @@ -1660,6 +1666,13 @@ int bt_disconnect(struct bt_conn *conn, uint8_t reason) case BT_CONN_CONNECT: return bt_hci_connect_le_cancel(conn); case BT_CONN_CONNECTED: + /* Disconnection is initiated by us, so auto connection shall + * be disabled. Otherwise the passive scan would be enabled + * and we could send LE Create Connection as soon as the remote + * starts advertising. + */ + bt_conn_set_auto_conn(conn, false); + return bt_hci_disconnect(conn, reason); case BT_CONN_DISCONNECT: return 0;