Commit d094afa155273e03b82981ea818d39c7a2dfba86

Authored by Samuel Ortiz
Committed by John W. Linville
1 parent 0767a7fa87

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>

Showing 3 changed files with 33 additions and 3 deletions Side-by-side Diff

net/nfc/llcp/commands.c
... ... @@ -428,4 +428,28 @@
428 428  
429 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 +}
... ... @@ -627,8 +627,9 @@
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 633 struct nfc_llcp_local *local = sock->local;
633 634  
634 635 pr_debug("Remote ready %d tx queue len %d remote rw %d",
635 636  
... ... @@ -651,7 +652,10 @@
651 652  
652 653 skb_queue_tail(&local->tx_queue, pdu);
653 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 661 static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local,
... ... @@ -716,7 +720,8 @@
716 720 else if (ptype == LLCP_PDU_RNR)
717 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 726 release_sock(sk);
722 727 nfc_llcp_sock_put(llcp_sock);
... ... @@ -165,7 +165,7 @@
165 165 struct nfc_llcp_sock *sock);
166 166 u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local);
167 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 170 /* Sock API */
171 171 struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp);
... ... @@ -190,6 +190,7 @@
190 190 int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock);
191 191 int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
192 192 struct msghdr *msg, size_t len);
  193 +int nfc_llcp_send_rr(struct nfc_llcp_sock *sock);
193 194  
194 195 /* Socket API */
195 196 int __init nfc_llcp_sock_init(void);