diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index bda68d833ddd..80072611d26a 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h @@ -204,10 +204,11 @@ struct rfcomm_dlc { #define RFCOMM_TX_THROTTLED 1 #define RFCOMM_TIMED_OUT 2 #define RFCOMM_MSC_PENDING 3 -#define RFCOMM_AUTH_PENDING 4 -#define RFCOMM_AUTH_ACCEPT 5 -#define RFCOMM_AUTH_REJECT 6 -#define RFCOMM_DEFER_SETUP 7 +#define RFCOMM_SEC_PENDING 4 +#define RFCOMM_AUTH_PENDING 5 +#define RFCOMM_AUTH_ACCEPT 6 +#define RFCOMM_AUTH_REJECT 7 +#define RFCOMM_DEFER_SETUP 8 /* Scheduling flags and events */ #define RFCOMM_SCHED_STATE 0 diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index db83f92d274c..dafaee91cdfb 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -1979,12 +1979,23 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt) list_for_each_safe(p, n, &s->dlcs) { d = list_entry(p, struct rfcomm_dlc, list); - if (!status && encrypt == 0x00 && - d->sec_level == BT_SECURITY_HIGH && - (d->state == BT_CONNECTED || - d->state == BT_CONFIG)) { - __rfcomm_dlc_close(d, ECONNREFUSED); - continue; + if (test_and_clear_bit(RFCOMM_SEC_PENDING, &d->flags)) { + rfcomm_dlc_clear_timer(d); + if (status || encrypt == 0x00) { + __rfcomm_dlc_close(d, ECONNREFUSED); + continue; + } + } + + if (d->state == BT_CONNECTED && !status && encrypt == 0x00) { + if (d->sec_level == BT_SECURITY_MEDIUM) { + set_bit(RFCOMM_SEC_PENDING, &d->flags); + rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); + continue; + } else if (d->sec_level == BT_SECURITY_HIGH) { + __rfcomm_dlc_close(d, ECONNREFUSED); + continue; + } } if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags))