diff options
author | Samuel Ortiz <sameo@linux.intel.com> | 2012-05-07 06:31:19 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-05-15 17:28:01 -0400 |
commit | ff353d86a92ee709e18fa485423dbaa7a52af8f3 (patch) | |
tree | 15e7400909f0d314b622135c4e447d0e687950a0 /net/nfc/llcp/sock.c | |
parent | 0f909361062d42b0ff7c6522e2347b56a0bf43cc (diff) |
NFC: LLCP connect must wait for a CC frame
Blocking sockets should sleep on a CC (Connection Complete) reception
from the connect() call.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/nfc/llcp/sock.c')
-rw-r--r-- | net/nfc/llcp/sock.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index c13e02ebdef9..99196d3b84eb 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c | |||
@@ -27,6 +27,42 @@ | |||
27 | #include "../nfc.h" | 27 | #include "../nfc.h" |
28 | #include "llcp.h" | 28 | #include "llcp.h" |
29 | 29 | ||
30 | static int sock_wait_state(struct sock *sk, int state, unsigned long timeo) | ||
31 | { | ||
32 | DECLARE_WAITQUEUE(wait, current); | ||
33 | int err = 0; | ||
34 | |||
35 | pr_debug("sk %p", sk); | ||
36 | |||
37 | add_wait_queue(sk_sleep(sk), &wait); | ||
38 | set_current_state(TASK_INTERRUPTIBLE); | ||
39 | |||
40 | while (sk->sk_state != state) { | ||
41 | if (!timeo) { | ||
42 | err = -EINPROGRESS; | ||
43 | break; | ||
44 | } | ||
45 | |||
46 | if (signal_pending(current)) { | ||
47 | err = sock_intr_errno(timeo); | ||
48 | break; | ||
49 | } | ||
50 | |||
51 | release_sock(sk); | ||
52 | timeo = schedule_timeout(timeo); | ||
53 | lock_sock(sk); | ||
54 | set_current_state(TASK_INTERRUPTIBLE); | ||
55 | |||
56 | err = sock_error(sk); | ||
57 | if (err) | ||
58 | break; | ||
59 | } | ||
60 | |||
61 | __set_current_state(TASK_RUNNING); | ||
62 | remove_wait_queue(sk_sleep(sk), &wait); | ||
63 | return err; | ||
64 | } | ||
65 | |||
30 | static struct proto llcp_sock_proto = { | 66 | static struct proto llcp_sock_proto = { |
31 | .name = "NFC_LLCP", | 67 | .name = "NFC_LLCP", |
32 | .owner = THIS_MODULE, | 68 | .owner = THIS_MODULE, |
@@ -462,9 +498,13 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, | |||
462 | if (ret) | 498 | if (ret) |
463 | goto put_dev; | 499 | goto put_dev; |
464 | 500 | ||
465 | sk->sk_state = LLCP_CONNECTED; | 501 | ret = sock_wait_state(sk, LLCP_CONNECTED, |
502 | sock_sndtimeo(sk, flags & O_NONBLOCK)); | ||
503 | if (ret) | ||
504 | goto put_dev; | ||
466 | 505 | ||
467 | release_sock(sk); | 506 | release_sock(sk); |
507 | |||
468 | return 0; | 508 | return 0; |
469 | 509 | ||
470 | put_dev: | 510 | put_dev: |