aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc/llcp/sock.c
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2012-05-07 06:31:19 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-05-15 17:28:01 -0400
commitff353d86a92ee709e18fa485423dbaa7a52af8f3 (patch)
tree15e7400909f0d314b622135c4e447d0e687950a0 /net/nfc/llcp/sock.c
parent0f909361062d42b0ff7c6522e2347b56a0bf43cc (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.c42
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
30static 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
30static struct proto llcp_sock_proto = { 66static 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
470put_dev: 510put_dev: