aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/nfc/llcp/llcp.c7
-rw-r--r--net/nfc/llcp/sock.c42
2 files changed, 48 insertions, 1 deletions
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c
index 92988aa620dc..42994fac26d6 100644
--- a/net/nfc/llcp/llcp.c
+++ b/net/nfc/llcp/llcp.c
@@ -448,6 +448,8 @@ static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local,
448{ 448{
449 struct nfc_llcp_sock *sock, *llcp_sock, *n; 449 struct nfc_llcp_sock *sock, *llcp_sock, *n;
450 450
451 pr_debug("ssap dsap %d %d\n", ssap, dsap);
452
451 if (ssap == 0 && dsap == 0) 453 if (ssap == 0 && dsap == 0)
452 return NULL; 454 return NULL;
453 455
@@ -783,6 +785,7 @@ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local,
783static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb) 785static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb)
784{ 786{
785 struct nfc_llcp_sock *llcp_sock; 787 struct nfc_llcp_sock *llcp_sock;
788 struct sock *sk;
786 u8 dsap, ssap; 789 u8 dsap, ssap;
787 790
788 dsap = nfc_llcp_dsap(skb); 791 dsap = nfc_llcp_dsap(skb);
@@ -801,10 +804,14 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb)
801 } 804 }
802 805
803 llcp_sock->dsap = ssap; 806 llcp_sock->dsap = ssap;
807 sk = &llcp_sock->sk;
804 808
805 nfc_llcp_parse_tlv(local, &skb->data[LLCP_HEADER_SIZE], 809 nfc_llcp_parse_tlv(local, &skb->data[LLCP_HEADER_SIZE],
806 skb->len - LLCP_HEADER_SIZE); 810 skb->len - LLCP_HEADER_SIZE);
807 811
812 sk->sk_state = LLCP_CONNECTED;
813 sk->sk_state_change(sk);
814
808 nfc_llcp_sock_put(llcp_sock); 815 nfc_llcp_sock_put(llcp_sock);
809} 816}
810 817
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: