aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/l2cap_sock.c
diff options
context:
space:
mode:
authorGustavo F. Padovan <padovan@profusion.mobi>2011-04-28 17:50:17 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-06-08 15:58:16 -0400
commit9a91a04a95d30a18909e2aec9d7b17b4c86088a7 (patch)
treee0c260031fe79ceaa8cb858b7316ce43974cef08 /net/bluetooth/l2cap_sock.c
parent4519de9a0478d8de438f8b80ab2e94668ef63ab4 (diff)
Bluetooth: Create l2cap_chan_send()
This move all the sending logic to l2cap_core.c, but we still have a socket dependence there, struct msghdr. It will be removed in some of the further commits. Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/l2cap_sock.c')
-rw-r--r--net/bluetooth/l2cap_sock.c83
1 files changed, 3 insertions, 80 deletions
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 290130ca1c4a..0ecf214bd30e 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -673,8 +673,6 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
673{ 673{
674 struct sock *sk = sock->sk; 674 struct sock *sk = sock->sk;
675 struct l2cap_chan *chan = l2cap_pi(sk)->chan; 675 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
676 struct sk_buff *skb;
677 u16 control;
678 int err; 676 int err;
679 677
680 BT_DBG("sock %p, sk %p", sock, sk); 678 BT_DBG("sock %p, sk %p", sock, sk);
@@ -689,87 +687,12 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
689 lock_sock(sk); 687 lock_sock(sk);
690 688
691 if (sk->sk_state != BT_CONNECTED) { 689 if (sk->sk_state != BT_CONNECTED) {
692 err = -ENOTCONN; 690 release_sock(sk);
693 goto done; 691 return -ENOTCONN;
694 } 692 }
695 693
696 /* Connectionless channel */ 694 err = l2cap_chan_send(chan, msg, len);
697 if (sk->sk_type == SOCK_DGRAM) {
698 skb = l2cap_create_connless_pdu(chan, msg, len);
699 if (IS_ERR(skb)) {
700 err = PTR_ERR(skb);
701 } else {
702 l2cap_do_send(chan, skb);
703 err = len;
704 }
705 goto done;
706 }
707 695
708 switch (chan->mode) {
709 case L2CAP_MODE_BASIC:
710 /* Check outgoing MTU */
711 if (len > chan->omtu) {
712 err = -EMSGSIZE;
713 goto done;
714 }
715
716 /* Create a basic PDU */
717 skb = l2cap_create_basic_pdu(chan, msg, len);
718 if (IS_ERR(skb)) {
719 err = PTR_ERR(skb);
720 goto done;
721 }
722
723 l2cap_do_send(chan, skb);
724 err = len;
725 break;
726
727 case L2CAP_MODE_ERTM:
728 case L2CAP_MODE_STREAMING:
729 /* Entire SDU fits into one PDU */
730 if (len <= chan->remote_mps) {
731 control = L2CAP_SDU_UNSEGMENTED;
732 skb = l2cap_create_iframe_pdu(chan, msg, len, control,
733 0);
734 if (IS_ERR(skb)) {
735 err = PTR_ERR(skb);
736 goto done;
737 }
738 __skb_queue_tail(&chan->tx_q, skb);
739
740 if (chan->tx_send_head == NULL)
741 chan->tx_send_head = skb;
742
743 } else {
744 /* Segment SDU into multiples PDUs */
745 err = l2cap_sar_segment_sdu(chan, msg, len);
746 if (err < 0)
747 goto done;
748 }
749
750 if (chan->mode == L2CAP_MODE_STREAMING) {
751 l2cap_streaming_send(chan);
752 err = len;
753 break;
754 }
755
756 if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
757 (chan->conn_state & L2CAP_CONN_WAIT_F)) {
758 err = len;
759 break;
760 }
761 err = l2cap_ertm_send(chan);
762
763 if (err >= 0)
764 err = len;
765 break;
766
767 default:
768 BT_DBG("bad state %1.1x", chan->mode);
769 err = -EBADFD;
770 }
771
772done:
773 release_sock(sk); 696 release_sock(sk);
774 return err; 697 return err;
775} 698}