Bluetooth: Pause RFCOMM TX when encryption drops

A role switch with devices following the Bluetooth pre-2.1 standards
or without Encryption Pause and Resume support is not possible if
encryption is enabled. Most newer headsets require the role switch,
but also require that the connection is encrypted.

For connections with a high security mode setting, the link will be
immediately dropped. When the connection uses medium security mode
setting, then a grace period is introduced where the TX is halted and
the remote device gets a change to re-enable encryption after the
role switch. If not re-enabled the link will be dropped.

Based on initial work by Ville Tervo <ville.tervo@nokia.com>

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
Marcel Holtmann
2009-01-16 08:17:51 +01:00
parent 9f2c8a03fb
commit 8c84b83076
2 changed files with 22 additions and 10 deletions

View File

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