summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/rfcomm.h9
-rw-r--r--net/bluetooth/rfcomm/core.c23
2 files changed, 22 insertions, 10 deletions
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))