aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/l2cap_sock.c
diff options
context:
space:
mode:
authorGustavo F. Padovan <padovan@profusion.mobi>2011-02-04 00:20:52 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2011-02-07 22:43:31 -0500
commitfd83ccdb393e3190633e0240dd73faac8998164b (patch)
treea5d0c8c4fd9a99deb6e0aa25940d7b2d7682582e /net/bluetooth/l2cap_sock.c
parentdcba0dba54b566a08376f93cab35cdabd6abda20 (diff)
Bluetooth: move l2cap_sock_sendmsg() to l2cap_sock.c
Also moves some L2CAP sending functions declaration to l2cap.h Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/l2cap_sock.c')
-rw-r--r--net/bluetooth/l2cap_sock.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 93af233bb167..fe4f834f03dd 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -681,6 +681,108 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
681 return err; 681 return err;
682} 682}
683 683
684static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
685{
686 struct sock *sk = sock->sk;
687 struct l2cap_pinfo *pi = l2cap_pi(sk);
688 struct sk_buff *skb;
689 u16 control;
690 int err;
691
692 BT_DBG("sock %p, sk %p", sock, sk);
693
694 err = sock_error(sk);
695 if (err)
696 return err;
697
698 if (msg->msg_flags & MSG_OOB)
699 return -EOPNOTSUPP;
700
701 lock_sock(sk);
702
703 if (sk->sk_state != BT_CONNECTED) {
704 err = -ENOTCONN;
705 goto done;
706 }
707
708 /* Connectionless channel */
709 if (sk->sk_type == SOCK_DGRAM) {
710 skb = l2cap_create_connless_pdu(sk, msg, len);
711 if (IS_ERR(skb)) {
712 err = PTR_ERR(skb);
713 } else {
714 l2cap_do_send(sk, skb);
715 err = len;
716 }
717 goto done;
718 }
719
720 switch (pi->mode) {
721 case L2CAP_MODE_BASIC:
722 /* Check outgoing MTU */
723 if (len > pi->omtu) {
724 err = -EMSGSIZE;
725 goto done;
726 }
727
728 /* Create a basic PDU */
729 skb = l2cap_create_basic_pdu(sk, msg, len);
730 if (IS_ERR(skb)) {
731 err = PTR_ERR(skb);
732 goto done;
733 }
734
735 l2cap_do_send(sk, skb);
736 err = len;
737 break;
738
739 case L2CAP_MODE_ERTM:
740 case L2CAP_MODE_STREAMING:
741 /* Entire SDU fits into one PDU */
742 if (len <= pi->remote_mps) {
743 control = L2CAP_SDU_UNSEGMENTED;
744 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
745 if (IS_ERR(skb)) {
746 err = PTR_ERR(skb);
747 goto done;
748 }
749 __skb_queue_tail(TX_QUEUE(sk), skb);
750
751 if (sk->sk_send_head == NULL)
752 sk->sk_send_head = skb;
753
754 } else {
755 /* Segment SDU into multiples PDUs */
756 err = l2cap_sar_segment_sdu(sk, msg, len);
757 if (err < 0)
758 goto done;
759 }
760
761 if (pi->mode == L2CAP_MODE_STREAMING) {
762 l2cap_streaming_send(sk);
763 } else {
764 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
765 (pi->conn_state & L2CAP_CONN_WAIT_F)) {
766 err = len;
767 break;
768 }
769 err = l2cap_ertm_send(sk);
770 }
771
772 if (err >= 0)
773 err = len;
774 break;
775
776 default:
777 BT_DBG("bad state %1.1x", pi->mode);
778 err = -EBADFD;
779 }
780
781done:
782 release_sock(sk);
783 return err;
784}
785
684static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags) 786static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
685{ 787{
686 struct sock *sk = sock->sk; 788 struct sock *sk = sock->sk;