aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2012-03-04 19:03:42 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-03-06 15:16:22 -0500
commitd094afa155273e03b82981ea818d39c7a2dfba86 (patch)
tree85aafb65a5612c9d30fb68118a18948e22178f68 /net
parent0767a7fa87ff18f6a11e3de954c5386a45b9d96e (diff)
NFC: Send LLCP RR frames to acknowledge received I frames
In order to acknowledge an I frame, we have to either queue pending local I frames or queue a receiver ready frame. Signed-off-by: Samuel Ortiz <sameo@linux.intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/nfc/llcp/commands.c24
-rw-r--r--net/nfc/llcp/llcp.c9
-rw-r--r--net/nfc/llcp/llcp.h3
3 files changed, 33 insertions, 3 deletions
diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c
index f6c2257c11aa..8ebd322b11eb 100644
--- a/net/nfc/llcp/commands.c
+++ b/net/nfc/llcp/commands.c
@@ -428,3 +428,27 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
428 428
429 return 0; 429 return 0;
430} 430}
431
432int nfc_llcp_send_rr(struct nfc_llcp_sock *sock)
433{
434 struct sk_buff *skb;
435 struct nfc_llcp_local *local;
436
437 pr_debug("Send rr nr %d\n", sock->recv_n);
438
439 local = sock->local;
440 if (local == NULL)
441 return -ENODEV;
442
443 skb = llcp_allocate_pdu(sock, LLCP_PDU_RR, LLCP_SEQUENCE_SIZE);
444 if (skb == NULL)
445 return -ENOMEM;
446
447 skb_put(skb, LLCP_SEQUENCE_SIZE);
448
449 skb->data[2] = sock->recv_n % 16;
450
451 skb_queue_head(&local->tx_queue, skb);
452
453 return 0;
454}
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c
index 2506810cd780..a0cb133c610a 100644
--- a/net/nfc/llcp/llcp.c
+++ b/net/nfc/llcp/llcp.c
@@ -627,8 +627,9 @@ fail:
627 627
628} 628}
629 629
630void nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock) 630int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock)
631{ 631{
632 int nr_frames = 0;
632 struct nfc_llcp_local *local = sock->local; 633 struct nfc_llcp_local *local = sock->local;
633 634
634 pr_debug("Remote ready %d tx queue len %d remote rw %d", 635 pr_debug("Remote ready %d tx queue len %d remote rw %d",
@@ -651,7 +652,10 @@ void nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock)
651 652
652 skb_queue_tail(&local->tx_queue, pdu); 653 skb_queue_tail(&local->tx_queue, pdu);
653 skb_queue_tail(&sock->tx_pending_queue, pending_pdu); 654 skb_queue_tail(&sock->tx_pending_queue, pending_pdu);
655 nr_frames++;
654 } 656 }
657
658 return nr_frames;
655} 659}
656 660
657static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, 661static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local,
@@ -716,7 +720,8 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local,
716 else if (ptype == LLCP_PDU_RNR) 720 else if (ptype == LLCP_PDU_RNR)
717 llcp_sock->remote_ready = false; 721 llcp_sock->remote_ready = false;
718 722
719 nfc_llcp_queue_i_frames(llcp_sock); 723 if (nfc_llcp_queue_i_frames(llcp_sock) == 0)
724 nfc_llcp_send_rr(llcp_sock);
720 725
721 release_sock(sk); 726 release_sock(sk);
722 nfc_llcp_sock_put(llcp_sock); 727 nfc_llcp_sock_put(llcp_sock);
diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h
index 36d8572c8beb..054c64ffdaa7 100644
--- a/net/nfc/llcp/llcp.h
+++ b/net/nfc/llcp/llcp.h
@@ -165,7 +165,7 @@ u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local,
165 struct nfc_llcp_sock *sock); 165 struct nfc_llcp_sock *sock);
166u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local); 166u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local);
167void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap); 167void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap);
168void nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock); 168int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock);
169 169
170/* Sock API */ 170/* Sock API */
171struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp); 171struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp);
@@ -190,6 +190,7 @@ int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason);
190int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock); 190int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock);
191int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, 191int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
192 struct msghdr *msg, size_t len); 192 struct msghdr *msg, size_t len);
193int nfc_llcp_send_rr(struct nfc_llcp_sock *sock);
193 194
194/* Socket API */ 195/* Socket API */
195int __init nfc_llcp_sock_init(void); 196int __init nfc_llcp_sock_init(void);