diff options
Diffstat (limited to 'net/nfc')
-rw-r--r-- | net/nfc/llcp/commands.c | 46 | ||||
-rw-r--r-- | net/nfc/llcp/llcp.h | 2 |
2 files changed, 48 insertions, 0 deletions
diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c index 6db280ddc4c8..79415353cc28 100644 --- a/net/nfc/llcp/commands.c +++ b/net/nfc/llcp/commands.c | |||
@@ -579,6 +579,52 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, | |||
579 | return len; | 579 | return len; |
580 | } | 580 | } |
581 | 581 | ||
582 | int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap, | ||
583 | struct msghdr *msg, size_t len) | ||
584 | { | ||
585 | struct sk_buff *pdu; | ||
586 | struct nfc_llcp_local *local; | ||
587 | size_t frag_len = 0, remaining_len; | ||
588 | u8 *msg_ptr; | ||
589 | int err; | ||
590 | |||
591 | pr_debug("Send UI frame len %zd\n", len); | ||
592 | |||
593 | local = sock->local; | ||
594 | if (local == NULL) | ||
595 | return -ENODEV; | ||
596 | |||
597 | remaining_len = len; | ||
598 | msg_ptr = (u8 *) msg->msg_iov; | ||
599 | |||
600 | while (remaining_len > 0) { | ||
601 | |||
602 | frag_len = min_t(size_t, sock->miu, remaining_len); | ||
603 | |||
604 | pr_debug("Fragment %zd bytes remaining %zd", | ||
605 | frag_len, remaining_len); | ||
606 | |||
607 | pdu = nfc_alloc_send_skb(sock->dev, &sock->sk, MSG_DONTWAIT, | ||
608 | frag_len + LLCP_HEADER_SIZE, &err); | ||
609 | if (pdu == NULL) { | ||
610 | pr_err("Could not allocate PDU\n"); | ||
611 | continue; | ||
612 | } | ||
613 | |||
614 | pdu = llcp_add_header(pdu, dsap, ssap, LLCP_PDU_UI); | ||
615 | |||
616 | memcpy(skb_put(pdu, frag_len), msg_ptr, frag_len); | ||
617 | |||
618 | /* No need to check for the peer RW for UI frames */ | ||
619 | skb_queue_tail(&local->tx_queue, pdu); | ||
620 | |||
621 | remaining_len -= frag_len; | ||
622 | msg_ptr += frag_len; | ||
623 | } | ||
624 | |||
625 | return len; | ||
626 | } | ||
627 | |||
582 | int nfc_llcp_send_rr(struct nfc_llcp_sock *sock) | 628 | int nfc_llcp_send_rr(struct nfc_llcp_sock *sock) |
583 | { | 629 | { |
584 | struct sk_buff *skb; | 630 | struct sk_buff *skb; |
diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h index e06d03571644..276da3a6a589 100644 --- a/net/nfc/llcp/llcp.h +++ b/net/nfc/llcp/llcp.h | |||
@@ -221,6 +221,8 @@ int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason); | |||
221 | int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock); | 221 | int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock); |
222 | int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, | 222 | int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, |
223 | struct msghdr *msg, size_t len); | 223 | struct msghdr *msg, size_t len); |
224 | int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap, | ||
225 | struct msghdr *msg, size_t len); | ||
224 | int nfc_llcp_send_rr(struct nfc_llcp_sock *sock); | 226 | int nfc_llcp_send_rr(struct nfc_llcp_sock *sock); |
225 | 227 | ||
226 | /* Socket API */ | 228 | /* Socket API */ |