Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d52deb17 authored by Johan Hedberg's avatar Johan Hedberg Committed by Marcel Holtmann
Browse files

Bluetooth: Resume BT_CONNECTED state after LE security elevation



The LE ATT socket uses a special trick where it temporarily sets
BT_CONFIG state for the duration of a security level elevation. In order
to not require special hacks for going back to BT_CONNECTED state in the
l2cap_core.c code the most reasonable place to resume the state is the
resume callback. This patch adds a new flag to track the pending
security level change and ensures that the state is set back to
BT_CONNECTED in the resume callback in case the flag is set.

Signed-off-by: default avatarJohan Hedberg <johan.hedberg@intel.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 5ff6f34d
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -708,6 +708,7 @@ enum {
	FLAG_EFS_ENABLE,
	FLAG_EFS_ENABLE,
	FLAG_DEFER_SETUP,
	FLAG_DEFER_SETUP,
	FLAG_LE_CONN_REQ_SENT,
	FLAG_LE_CONN_REQ_SENT,
	FLAG_PENDING_SECURITY,
};
};


enum {
enum {
+6 −0
Original line number Original line Diff line number Diff line
@@ -790,6 +790,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
		if (chan->scid == L2CAP_CID_ATT) {
		if (chan->scid == L2CAP_CID_ATT) {
			if (smp_conn_security(conn->hcon, sec.level))
			if (smp_conn_security(conn->hcon, sec.level))
				break;
				break;
			set_bit(FLAG_PENDING_SECURITY, &chan->flags);
			sk->sk_state = BT_CONFIG;
			sk->sk_state = BT_CONFIG;
			chan->state = BT_CONFIG;
			chan->state = BT_CONFIG;


@@ -1359,6 +1360,11 @@ static void l2cap_sock_resume_cb(struct l2cap_chan *chan)
{
{
	struct sock *sk = chan->data;
	struct sock *sk = chan->data;


	if (test_and_clear_bit(FLAG_PENDING_SECURITY, &chan->flags)) {
		sk->sk_state = BT_CONNECTED;
		chan->state = BT_CONNECTED;
	}

	clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
	clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
	sk->sk_state_change(sk);
	sk->sk_state_change(sk);
}
}