diff options
author | Samuel Ortiz <sameo@linux.intel.com> | 2012-03-04 19:03:42 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-03-06 15:16:22 -0500 |
commit | d094afa155273e03b82981ea818d39c7a2dfba86 (patch) | |
tree | 85aafb65a5612c9d30fb68118a18948e22178f68 /net | |
parent | 0767a7fa87ff18f6a11e3de954c5386a45b9d96e (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.c | 24 | ||||
-rw-r--r-- | net/nfc/llcp/llcp.c | 9 | ||||
-rw-r--r-- | net/nfc/llcp/llcp.h | 3 |
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 | |||
432 | int 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 | ||
630 | void nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock) | 630 | int 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 | ||
657 | static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, | 661 | static 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); |
166 | u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local); | 166 | u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local); |
167 | void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap); | 167 | void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap); |
168 | void nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock); | 168 | int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock); |
169 | 169 | ||
170 | /* Sock API */ | 170 | /* Sock API */ |
171 | struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp); | 171 | struct 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); | |||
190 | int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock); | 190 | int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock); |
191 | int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, | 191 | int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, |
192 | struct msghdr *msg, size_t len); | 192 | struct msghdr *msg, size_t len); |
193 | int nfc_llcp_send_rr(struct nfc_llcp_sock *sock); | ||
193 | 194 | ||
194 | /* Socket API */ | 195 | /* Socket API */ |
195 | int __init nfc_llcp_sock_init(void); | 196 | int __init nfc_llcp_sock_init(void); |