diff options
author | Thierry Escande <thierry.escande@linux.intel.com> | 2013-06-04 11:34:51 +0200 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2013-06-14 13:45:05 +0200 |
commit | 17f7ae16aef1f58bc4af4c7a16b8778a91a30255 (patch) | |
tree | 02ee0a69207c231a5bd3939ccee7021cbbaddd65 /net/nfc | |
parent | 58e3dd1558f56e95e7077a63340bb33e7aa42946 (diff) |
NFC: Keep socket alive until the DISC PDU is actually sent
This patch keeps the socket alive and therefore does not remove
it from the sockets list in the local until the DISC PDU has been
actually sent. Otherwise we would reply with DM PDUs before sending
the DISC one.
Signed-off-by: Thierry Escande <thierry.escande@linux.intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'net/nfc')
-rw-r--r-- | net/nfc/llcp.h | 1 | ||||
-rw-r--r-- | net/nfc/llcp_core.c | 7 | ||||
-rw-r--r-- | net/nfc/llcp_sock.c | 7 |
3 files changed, 15 insertions, 0 deletions
diff --git a/net/nfc/llcp.h b/net/nfc/llcp.h index ac16ebe3069..71f649e5ef4 100644 --- a/net/nfc/llcp.h +++ b/net/nfc/llcp.h @@ -19,6 +19,7 @@ enum llcp_state { LLCP_CONNECTED = 1, /* wait_for_packet() wants that */ + LLCP_DISCONNECTING, LLCP_CLOSED, LLCP_BOUND, LLCP_LISTEN, diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c index 158bdbf668c..1c4c048e0a1 100644 --- a/net/nfc/llcp_core.c +++ b/net/nfc/llcp_core.c @@ -730,6 +730,13 @@ static void nfc_llcp_tx_work(struct work_struct *work) DUMP_PREFIX_OFFSET, 16, 1, skb->data, skb->len, true); + if (ptype == LLCP_PDU_DISC && sk != NULL && + sk->sk_state == LLCP_DISCONNECTING) { + nfc_llcp_sock_unlink(&local->sockets, sk); + sock_orphan(sk); + sock_put(sk); + } + if (ptype == LLCP_PDU_I) copy_skb = skb_copy(skb, GFP_ATOMIC); diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c index 03fd3162cee..47e7acfc023 100644 --- a/net/nfc/llcp_sock.c +++ b/net/nfc/llcp_sock.c @@ -626,6 +626,13 @@ static int llcp_sock_release(struct socket *sock) release_sock(sk); + /* Keep this sock alive and therefore do not remove it from the sockets + * list until the DISC PDU has been actually sent. Otherwise we would + * reply with DM PDUs before sending the DISC one. + */ + if (sk->sk_state == LLCP_DISCONNECTING) + return err; + if (sock->type == SOCK_RAW) nfc_llcp_sock_unlink(&local->raw_sockets, sk); else |