aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc/llcp
diff options
context:
space:
mode:
Diffstat (limited to 'net/nfc/llcp')
-rw-r--r--net/nfc/llcp/commands.c31
-rw-r--r--net/nfc/llcp/llcp.h2
-rw-r--r--net/nfc/llcp/sock.c30
3 files changed, 62 insertions, 1 deletions
diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c
index 151f2ef429c4..f6c2257c11aa 100644
--- a/net/nfc/llcp/commands.c
+++ b/net/nfc/llcp/commands.c
@@ -397,3 +397,34 @@ int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock)
397 397
398 return 0; 398 return 0;
399} 399}
400
401int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
402 struct msghdr *msg, size_t len)
403{
404 struct sk_buff *pdu;
405 struct sock *sk;
406
407 pr_debug("Send I frame\n");
408
409 pdu = llcp_allocate_pdu(sock, LLCP_PDU_I, len + LLCP_SEQUENCE_SIZE);
410 if (pdu == NULL)
411 return -ENOMEM;
412
413 skb_put(pdu, LLCP_SEQUENCE_SIZE);
414
415 if (memcpy_fromiovec(skb_put(pdu, len), msg->msg_iov, len)) {
416 kfree_skb(pdu);
417 return -EFAULT;
418 }
419
420 skb_queue_head(&sock->tx_queue, pdu);
421
422 sk = &sock->sk;
423 lock_sock(sk);
424
425 nfc_llcp_queue_i_frames(sock);
426
427 release_sock(sk);
428
429 return 0;
430}
diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h
index 0a72ee627641..36d8572c8beb 100644
--- a/net/nfc/llcp/llcp.h
+++ b/net/nfc/llcp/llcp.h
@@ -188,6 +188,8 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock);
188int nfc_llcp_send_cc(struct nfc_llcp_sock *sock); 188int nfc_llcp_send_cc(struct nfc_llcp_sock *sock);
189int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason); 189int 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,
192 struct msghdr *msg, size_t len);
191 193
192/* Socket API */ 194/* Socket API */
193int __init nfc_llcp_sock_init(void); 195int __init nfc_llcp_sock_init(void);
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c
index f738ccd535f1..b8bef367ee49 100644
--- a/net/nfc/llcp/sock.c
+++ b/net/nfc/llcp/sock.c
@@ -482,6 +482,34 @@ error:
482 return ret; 482 return ret;
483} 483}
484 484
485static int llcp_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
486 struct msghdr *msg, size_t len)
487{
488 struct sock *sk = sock->sk;
489 struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
490 int ret;
491
492 pr_debug("sock %p sk %p", sock, sk);
493
494 ret = sock_error(sk);
495 if (ret)
496 return ret;
497
498 if (msg->msg_flags & MSG_OOB)
499 return -EOPNOTSUPP;
500
501 lock_sock(sk);
502
503 if (sk->sk_state != LLCP_CONNECTED) {
504 release_sock(sk);
505 return -ENOTCONN;
506 }
507
508 release_sock(sk);
509
510 return nfc_llcp_send_i_frame(llcp_sock, msg, len);
511}
512
485static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock, 513static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
486 struct msghdr *msg, size_t len, int flags) 514 struct msghdr *msg, size_t len, int flags)
487{ 515{
@@ -567,7 +595,7 @@ static const struct proto_ops llcp_sock_ops = {
567 .shutdown = sock_no_shutdown, 595 .shutdown = sock_no_shutdown,
568 .setsockopt = sock_no_setsockopt, 596 .setsockopt = sock_no_setsockopt,
569 .getsockopt = sock_no_getsockopt, 597 .getsockopt = sock_no_getsockopt,
570 .sendmsg = sock_no_sendmsg, 598 .sendmsg = llcp_sock_sendmsg,
571 .recvmsg = llcp_sock_recvmsg, 599 .recvmsg = llcp_sock_recvmsg,
572 .mmap = sock_no_mmap, 600 .mmap = sock_no_mmap,
573}; 601};