diff -urN linux-2.4.24-org/include/net/bluetooth/rfcomm.h linux-2.4.24-test1/include/net/bluetooth/rfcomm.h --- linux-2.4.24-org/include/net/bluetooth/rfcomm.h Sat Nov 29 03:26:21 2003 +++ linux-2.4.24-test1/include/net/bluetooth/rfcomm.h Tue Jul 13 00:10:29 2004 @@ -317,6 +317,7 @@ void rfcomm_cleanup_sockets(void); int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d); +void rfcomm_sock_cleanup_garbage (struct rfcomm_dlc *d); /* ---- RFCOMM TTY ---- */ #define RFCOMM_MAX_DEV 256 diff -urN linux-2.4.24-org/net/bluetooth/rfcomm/core.c linux-2.4.24-test1/net/bluetooth/rfcomm/core.c --- linux-2.4.24-org/net/bluetooth/rfcomm/core.c Mon May 24 23:24:12 2004 +++ linux-2.4.24-test1/net/bluetooth/rfcomm/core.c Tue Jul 13 00:14:23 2004 @@ -365,6 +365,7 @@ rfcomm_dlc_unlock(d); skb_queue_purge(&d->tx_queue); + rfcomm_sock_cleanup_garbage (d); rfcomm_dlc_unlink(d); } diff -urN linux-2.4.24-org/net/bluetooth/rfcomm/sock.c linux-2.4.24-test1/net/bluetooth/rfcomm/sock.c --- linux-2.4.24-org/net/bluetooth/rfcomm/sock.c Mon Aug 25 20:44:44 2003 +++ linux-2.4.24-test1/net/bluetooth/rfcomm/sock.c Tue Jul 13 00:17:44 2004 @@ -110,6 +110,18 @@ } /* ---- Socket functions ---- */ +struct sock *__rfcomm_get_sock_by_dlc(struct rfcomm_dlc *d, bdaddr_t *src) +{ + struct sock *sk; + + for (sk = rfcomm_sk_list.head; sk; sk = sk->next) { + if (rfcomm_pi(sk)->dlc == d && + !bacmp(&bluez_pi(sk)->src, src)) + break; + } + + return sk; +} static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src) { struct sock *sk; @@ -244,6 +256,23 @@ lock_sock(sk); __rfcomm_sock_close(sk); release_sock(sk); +} + +void rfcomm_sock_cleanup_garbage (struct rfcomm_dlc *d) +{ + struct rfcomm_session *s = d->session; + struct sock *sk; + bdaddr_t src, dst; + + if (!s) + return; + + rfcomm_session_getaddr(s, &src, &dst); + sk = __rfcomm_get_sock_by_dlc (d, &src); + if (sk && sk->state == BT_CLOSED) { + rfcomm_sock_close (sk); + rfcomm_sock_kill (sk); + } } static void rfcomm_sock_init(struct sock *sk, struct sock *parent)