On Mon, Jul 13, 2009 at 2:27 PM, Luiz Augusto von Dentz<luiz.dentz@xxxxxxxxx> wrote: > Hi Nick, > > On Mon, Jul 13, 2009 at 12:46 PM, Nick Pelly<npelly@xxxxxxxxxx> wrote: >> Any comments on this patch? >> >> It works for me, but my understanding of the RFCOMM state machine is naive. >> > > iirc BT_CONFIG(PN frame) means the DLC is being configured than we got > into connecting phase (BT_CONNECT) and send SABM frame. Only when > receiving UA frame DLC is consider connected (BT_CONNECTED), so your > patch seems good by assuming that we don't need to send a DISC for a > DLC not connected. But there is still a good use for it to cancel the > DLC connection attempt, so perhaps a better alternative would be to > use a much shorter timeout in those cases. Thanks for the advice. I have prepared a new patch which uses a very short timeout (10ms) on the DLC disconnect when in BT_CONFIG. I have tested this patch and it also resolves the issue. Patch attached. Nick
From 80bc07e9703e4303f04c26158b096bcbd00fd665 Mon Sep 17 00:00:00 2001 From: Nick Pelly <npelly@xxxxxxxxxx> Date: Tue, 14 Jul 2009 07:57:54 -0700 Subject: [PATCH] Bluetooth: Use a very short timeout for dlci disconnect when in BT_CONFIG. This fixes a bug where shutdown() and close() on a rfcomm socket during ACL connection would not cause HCI Create Connection Cancel. Signed-off-by: Nick Pelly <npelly@xxxxxxxxxx> --- include/net/bluetooth/rfcomm.h | 7 ++++--- net/bluetooth/rfcomm/core.c | 10 +++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index 8007261..eeb3ffa 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h @@ -26,9 +26,10 @@ #define RFCOMM_PSM 3 -#define RFCOMM_CONN_TIMEOUT (HZ * 30) -#define RFCOMM_DISC_TIMEOUT (HZ * 20) -#define RFCOMM_AUTH_TIMEOUT (HZ * 25) +#define RFCOMM_CONN_TIMEOUT (HZ * 30) +#define RFCOMM_DISC_TIMEOUT (HZ * 20) +#define RFCOMM_AUTH_TIMEOUT (HZ * 25) +#define RFCOMM_CONFIG_DISC_TIMEOUT (HZ / 100) #define RFCOMM_DEFAULT_MTU 127 #define RFCOMM_DEFAULT_CREDITS 7 diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 1d0fb0f..476d856 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -419,6 +419,7 @@ int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 chann static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err) { + long timeout = RFCOMM_DISC_TIMEOUT; struct rfcomm_session *s = d->session; if (!s) return 0; @@ -427,8 +428,11 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err) d, d->state, d->dlci, err, s); switch (d->state) { - case BT_CONNECT: case BT_CONFIG: + timeout = RFCOMM_CONFIG_DISC_TIMEOUT; + /* Fall-through */ + + case BT_CONNECT: if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { set_bit(RFCOMM_AUTH_REJECT, &d->flags); rfcomm_schedule(RFCOMM_SCHED_AUTH); @@ -440,10 +444,10 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err) d->state = BT_DISCONN; if (skb_queue_empty(&d->tx_queue)) { rfcomm_send_disc(s, d->dlci); - rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT); + rfcomm_dlc_set_timer(d, timeout); } else { rfcomm_queue_disc(d); - rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT * 2); + rfcomm_dlc_set_timer(d, timeout * 2); } break; -- 1.6.3.1