From 32bde4fe7870a640441733563502786b3596bd76 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Thu, 12 Dec 2019 14:28:44 +0100 Subject: [PATCH] Bluetooth: host: Refactor host auto initiated LL procedures Refactor the handling of the host auto initiated LL procedures. This makes it easier to add new auto initiated procedures as well as reduced the maintenance by reducing code duplication. Signed-off-by: Joakim Andersson --- subsys/bluetooth/host/conn_internal.h | 3 + subsys/bluetooth/host/hci_core.c | 119 +++++++++++--------------- 2 files changed, 53 insertions(+), 69 deletions(-) diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index 995a5aea1c4..b792603d954 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -31,6 +31,9 @@ enum { BT_CONN_SLAVE_PARAM_L2CAP, /* If should force L2CAP for CPUP */ BT_CONN_FORCE_PAIR, /* Pairing even with existing keys. */ + BT_CONN_AUTO_PHY_COMPLETE, /* Auto-initiated PHY procedure done */ + BT_CONN_AUTO_FEATURE_EXCH, /* Auto-initiated LE Feat done */ + /* Total number of flags - must be at the end of the enum */ BT_CONN_NUM_FLAGS, }; diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 5778ffeacba..d963e5a290c 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -1078,12 +1078,53 @@ static struct bt_conn *find_pending_connect(bt_addr_le_t *peer_addr) return bt_conn_lookup_state_le(peer_addr, BT_CONN_CONNECT_DIR_ADV); } +static void conn_auto_initiate(struct bt_conn *conn) +{ + int err; + + if (conn->state != BT_CONN_CONNECTED) { + /* It is possible that connection was disconnected directly from + * connected callback so we must check state before doing + * connection parameters update. + */ + return; + } + + if (!atomic_test_bit(conn->flags, BT_CONN_AUTO_FEATURE_EXCH) && + ((conn->role == BT_HCI_ROLE_MASTER) || + BT_FEAT_LE_SLAVE_FEATURE_XCHG(bt_dev.le.features))) { + err = hci_le_read_remote_features(conn); + if (!err) { + return; + } + } + + if (IS_ENABLED(CONFIG_BT_AUTO_PHY_UPDATE) && + !atomic_test_bit(conn->flags, BT_CONN_AUTO_PHY_COMPLETE) && + BT_FEAT_LE_PHY_2M(bt_dev.le.features)) { + err = hci_le_set_phy(conn); + if (!err) { + atomic_set_bit(conn->flags, BT_CONN_AUTO_PHY_UPDATE); + return; + } + } + + if (IS_ENABLED(CONFIG_BT_DATA_LEN_UPDATE) && + BT_FEAT_LE_DLE(bt_dev.le.features)) { + hci_le_set_data_len(conn); + } + + if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && + conn->role == BT_CONN_ROLE_SLAVE) { + slave_update_conn_param(conn); + } +} + static void enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt) { u16_t handle = sys_le16_to_cpu(evt->handle); bt_addr_le_t peer_addr, id_addr; struct bt_conn *conn; - int err; BT_DBG("status 0x%02x handle %u role %u %s", evt->status, handle, evt->role, bt_addr_le_str(&evt->peer_addr)); @@ -1256,41 +1297,8 @@ static void enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt) bt_conn_set_state(conn, BT_CONN_CONNECTED); - /* - * it is possible that connection was disconnected directly from - * connected callback so we must check state before doing connection - * parameters update - */ - if (conn->state != BT_CONN_CONNECTED) { - goto done; - } - - if ((evt->role == BT_HCI_ROLE_MASTER) || - BT_FEAT_LE_SLAVE_FEATURE_XCHG(bt_dev.le.features)) { - err = hci_le_read_remote_features(conn); - if (!err) { - goto done; - } - } - - if (IS_ENABLED(CONFIG_BT_AUTO_PHY_UPDATE) && - BT_FEAT_LE_PHY_2M(bt_dev.le.features)) { - err = hci_le_set_phy(conn); - if (!err) { - atomic_set_bit(conn->flags, BT_CONN_AUTO_PHY_UPDATE); - goto done; - } - } - - if (IS_ENABLED(CONFIG_BT_DATA_LEN_UPDATE) && - BT_FEAT_LE_DLE(bt_dev.le.features)) { - hci_le_set_data_len(conn); - } - - if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && - conn->role == BT_CONN_ROLE_SLAVE) { - slave_update_conn_param(conn); - } + /* Start auto-initiated procedures */ + conn_auto_initiate(conn); done: bt_conn_unref(conn); @@ -1363,30 +1371,10 @@ static void le_remote_feat_complete(struct net_buf *buf) sizeof(conn->le.features)); } - if (IS_ENABLED(CONFIG_BT_AUTO_PHY_UPDATE) && - BT_FEAT_LE_PHY_2M(bt_dev.le.features) && - BT_FEAT_LE_PHY_2M(conn->le.features)) { - int err; + atomic_set_bit(conn->flags, BT_CONN_AUTO_FEATURE_EXCH); + /* Continue with auto-initiated procedures */ + conn_auto_initiate(conn); - err = hci_le_set_phy(conn); - if (!err) { - atomic_set_bit(conn->flags, BT_CONN_AUTO_PHY_UPDATE); - goto done; - } - } - - if (IS_ENABLED(CONFIG_BT_DATA_LEN_UPDATE) && - BT_FEAT_LE_DLE(bt_dev.le.features) && - BT_FEAT_LE_DLE(conn->le.features)) { - hci_le_set_data_len(conn); - } - - if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && - conn->role == BT_CONN_ROLE_SLAVE) { - slave_update_conn_param(conn); - } - -done: bt_conn_unref(conn); } @@ -1437,16 +1425,9 @@ static void le_phy_update_complete(struct net_buf *buf) goto done; } - if (IS_ENABLED(CONFIG_BT_DATA_LEN_UPDATE) && - BT_FEAT_LE_DLE(bt_dev.le.features) && - BT_FEAT_LE_DLE(conn->le.features)) { - hci_le_set_data_len(conn); - } - - if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && - conn->role == BT_CONN_ROLE_SLAVE) { - slave_update_conn_param(conn); - } + atomic_set_bit(conn->flags, BT_CONN_AUTO_PHY_COMPLETE); + /* Continue with auto-initiated procedures */ + conn_auto_initiate(conn); done: bt_conn_unref(conn);