summaryrefslogtreecommitdiff
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))