summaryrefslogtreecommitdiffstats
path: root/net/nfc
diff options
context:
space:
mode:
authorThierry Escande <thierry.escande@linux.intel.com>2013-06-04 11:34:51 +0200
committerSamuel Ortiz <sameo@linux.intel.com>2013-06-14 13:45:05 +0200
commit17f7ae16aef1f58bc4af4c7a16b8778a91a30255 (patch)
tree02ee0a69207c231a5bd3939ccee7021cbbaddd65 /net/nfc
parent58e3dd1558f56e95e7077a63340bb33e7aa42946 (diff)
downloadop-kernel-dev-17f7ae16aef1f58bc4af4c7a16b8778a91a30255.zip
op-kernel-dev-17f7ae16aef1f58bc4af4c7a16b8778a91a30255.tar.gz
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.h1
-rw-r--r--net/nfc/llcp_core.c7
-rw-r--r--net/nfc/llcp_sock.c7
3 files changed, 15 insertions, 0 deletions
diff --git a/net/nfc/llcp.h b/net/nfc/llcp.h
index ac16ebe..71f649e 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 158bdbf..1c4c048 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 03fd316..47e7acf 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
OpenPOWER on IntegriCloud