aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc/llcp
diff options
context:
space:
mode:
Diffstat (limited to 'net/nfc/llcp')
-rw-r--r--net/nfc/llcp/commands.c4
-rw-r--r--net/nfc/llcp/llcp.c7
-rw-r--r--net/nfc/llcp/sock.c57
3 files changed, 64 insertions, 4 deletions
diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c
index 11a3b7d98dc5..bf8ae4f0b90c 100644
--- a/net/nfc/llcp/commands.c
+++ b/net/nfc/llcp/commands.c
@@ -488,7 +488,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
488 488
489 memcpy(skb_put(pdu, frag_len), msg_ptr, frag_len); 489 memcpy(skb_put(pdu, frag_len), msg_ptr, frag_len);
490 490
491 skb_queue_head(&sock->tx_queue, pdu); 491 skb_queue_tail(&sock->tx_queue, pdu);
492 492
493 lock_sock(sk); 493 lock_sock(sk);
494 494
@@ -502,7 +502,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
502 502
503 kfree(msg_data); 503 kfree(msg_data);
504 504
505 return 0; 505 return len;
506} 506}
507 507
508int nfc_llcp_send_rr(struct nfc_llcp_sock *sock) 508int nfc_llcp_send_rr(struct nfc_llcp_sock *sock)
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..3f339b19d140 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,
@@ -304,11 +340,24 @@ static unsigned int llcp_sock_poll(struct file *file, struct socket *sock,
304 mask |= POLLERR; 340 mask |= POLLERR;
305 341
306 if (!skb_queue_empty(&sk->sk_receive_queue)) 342 if (!skb_queue_empty(&sk->sk_receive_queue))
307 mask |= POLLIN; 343 mask |= POLLIN | POLLRDNORM;
308 344
309 if (sk->sk_state == LLCP_CLOSED) 345 if (sk->sk_state == LLCP_CLOSED)
310 mask |= POLLHUP; 346 mask |= POLLHUP;
311 347
348 if (sk->sk_shutdown & RCV_SHUTDOWN)
349 mask |= POLLRDHUP | POLLIN | POLLRDNORM;
350
351 if (sk->sk_shutdown == SHUTDOWN_MASK)
352 mask |= POLLHUP;
353
354 if (sock_writeable(sk))
355 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
356 else
357 set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
358
359 pr_debug("mask 0x%x\n", mask);
360
312 return mask; 361 return mask;
313} 362}
314 363
@@ -462,9 +511,13 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
462 if (ret) 511 if (ret)
463 goto put_dev; 512 goto put_dev;
464 513
465 sk->sk_state = LLCP_CONNECTED; 514 ret = sock_wait_state(sk, LLCP_CONNECTED,
515 sock_sndtimeo(sk, flags & O_NONBLOCK));
516 if (ret)
517 goto put_dev;
466 518
467 release_sock(sk); 519 release_sock(sk);
520
468 return 0; 521 return 0;
469 522
470put_dev: 523put_dev: