Commit 53a0ac2ee810cf82ec374b686a1dc3c32399265a
Committed by
John W. Linville
1 parent
53aef92054
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
NFC: LLCP socket sendmsg implemetation
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Showing 3 changed files with 62 additions and 1 deletions Side-by-side Diff
net/nfc/llcp/commands.c
... | ... | @@ -397,4 +397,35 @@ |
397 | 397 | |
398 | 398 | return 0; |
399 | 399 | } |
400 | + | |
401 | +int 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 | +} |
net/nfc/llcp/llcp.h
... | ... | @@ -188,6 +188,8 @@ |
188 | 188 | int nfc_llcp_send_cc(struct nfc_llcp_sock *sock); |
189 | 189 | int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason); |
190 | 190 | int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock); |
191 | +int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, | |
192 | + struct msghdr *msg, size_t len); | |
191 | 193 | |
192 | 194 | /* Socket API */ |
193 | 195 | int __init nfc_llcp_sock_init(void); |
net/nfc/llcp/sock.c
... | ... | @@ -482,6 +482,34 @@ |
482 | 482 | return ret; |
483 | 483 | } |
484 | 484 | |
485 | +static 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 | + | |
485 | 513 | static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock, |
486 | 514 | struct msghdr *msg, size_t len, int flags) |
487 | 515 | { |
... | ... | @@ -567,7 +595,7 @@ |
567 | 595 | .shutdown = sock_no_shutdown, |
568 | 596 | .setsockopt = sock_no_setsockopt, |
569 | 597 | .getsockopt = sock_no_getsockopt, |
570 | - .sendmsg = sock_no_sendmsg, | |
598 | + .sendmsg = llcp_sock_sendmsg, | |
571 | 599 | .recvmsg = llcp_sock_recvmsg, |
572 | 600 | .mmap = sock_no_mmap, |
573 | 601 | }; |