Hi Patrick, On Wed, Jul 15, 2020 at 7:50 AM Patrick Steinhardt <ps@xxxxxx> wrote: > > Starting with the upgrade to v5.8-rc3, I've noticed I wasn't able to > connect to my Bluetooth headset properly anymore. While connecting to > the device would eventually succeed, bluetoothd seemed to be confused > about the current connection state where the state was flapping hence > and forth. Bisecting this issue led to commit 3ca44c16b0dc ("Bluetooth: > Consolidate encryption handling in hci_encrypt_cfm"), which refactored > `hci_encrypt_cfm` to also handle updating the connection state. > > The commit in question changed the code to call `hci_connect_cfm` inside > `hci_encrypt_cfm` and updating the connection state. But the conversion > didn't keep old behaviour of when the connection state is updated, which > now causes us to not properly update it anymore. > > Fix the issue by adding another parameter to the function that allows > callers to specify whether the connection state should be updated, which > allows us to restore previous behaviour. > > Fixes: 3ca44c16b0dc ("Bluetooth: Consolidate encryption handling in hci_encrypt_cfm") > Signed-off-by: Patrick Steinhardt <ps@xxxxxx> > --- > include/net/bluetooth/hci_core.h | 4 ++-- > net/bluetooth/hci_event.c | 6 +++--- > 2 files changed, 5 insertions(+), 5 deletions(-) > > diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h > index cdd4f1db8670..9abcc4a89abc 100644 > --- a/include/net/bluetooth/hci_core.h > +++ b/include/net/bluetooth/hci_core.h > @@ -1381,13 +1381,13 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) > conn->security_cfm_cb(conn, status); > } > > -static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status) > +static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 update_state) > { > struct hci_cb *cb; > __u8 encrypt; > > if (conn->state == BT_CONFIG) { > - if (status) > + if (update_state) The intent was actually to have if (!status) as it means the encryption has succeeded the state can be considered connected, so I wonder if we really need to introduce another parameter. Anyway as it is broken we need to come up with a fix rather quickly. > conn->state = BT_CONNECTED; > > hci_connect_cfm(conn, status); > diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c > index cfeaee347db3..483d35eda2f1 100644 > --- a/net/bluetooth/hci_event.c > +++ b/net/bluetooth/hci_event.c > @@ -2931,7 +2931,7 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) > &cp); > } else { > clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); > - hci_encrypt_cfm(conn, ev->status); > + hci_encrypt_cfm(conn, ev->status, 0); > } > } > > @@ -3016,7 +3016,7 @@ static void read_enc_key_size_complete(struct hci_dev *hdev, u8 status, > conn->enc_key_size = rp->key_size; > } > > - hci_encrypt_cfm(conn, 0); > + hci_encrypt_cfm(conn, 0, 1); > > unlock: > hci_dev_unlock(hdev); > @@ -3134,7 +3134,7 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) > } > > notify: > - hci_encrypt_cfm(conn, ev->status); > + hci_encrypt_cfm(conn, ev->status, !ev->status); > > unlock: > hci_dev_unlock(hdev); > -- > 2.27.0 > -- Luiz Augusto von Dentz