diff options
author | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-02-04 00:20:52 -0500 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-02-07 22:43:31 -0500 |
commit | fd83ccdb393e3190633e0240dd73faac8998164b (patch) | |
tree | a5d0c8c4fd9a99deb6e0aa25940d7b2d7682582e /net/bluetooth/l2cap_sock.c | |
parent | dcba0dba54b566a08376f93cab35cdabd6abda20 (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.c | 102 |
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 | ||
684 | static 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 | |||
781 | done: | ||
782 | release_sock(sk); | ||
783 | return err; | ||
784 | } | ||
785 | |||
684 | static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags) | 786 | static 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; |