aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorGustavo F. Padovan <padovan@profusion.mobi>2010-05-01 15:15:42 -0400
committerMarcel Holtmann <marcel@holtmann.org>2010-05-10 03:28:51 -0400
commitbd3c9e255e76ae232d417e3914ca5d80ca3e9485 (patch)
tree77332e60a295c6ea813efb35b4d77e8e899f3640 /net/bluetooth
parent84fb0a6334af0ccad3544f6972c055d90fbb9fbe (diff)
Bluetooth: Add SOCK_STREAM support to L2CAP
if enable_ertm is true and we have SOCK_STREAM the default mode will be ERTM, otherwise Basic Mode. Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi> Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/l2cap.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 4c007203d66b..1a32562adf46 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -224,7 +224,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so
224 224
225 l2cap_pi(sk)->conn = conn; 225 l2cap_pi(sk)->conn = conn;
226 226
227 if (sk->sk_type == SOCK_SEQPACKET) { 227 if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
228 /* Alloc CID for connection-oriented socket */ 228 /* Alloc CID for connection-oriented socket */
229 l2cap_pi(sk)->scid = l2cap_alloc_cid(l); 229 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
230 } else if (sk->sk_type == SOCK_DGRAM) { 230 } else if (sk->sk_type == SOCK_DGRAM) {
@@ -452,7 +452,8 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
452 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { 452 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
453 bh_lock_sock(sk); 453 bh_lock_sock(sk);
454 454
455 if (sk->sk_type != SOCK_SEQPACKET) { 455 if (sk->sk_type != SOCK_SEQPACKET &&
456 sk->sk_type != SOCK_STREAM) {
456 bh_unlock_sock(sk); 457 bh_unlock_sock(sk);
457 continue; 458 continue;
458 } 459 }
@@ -512,7 +513,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
512 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { 513 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
513 bh_lock_sock(sk); 514 bh_lock_sock(sk);
514 515
515 if (sk->sk_type != SOCK_SEQPACKET) { 516 if (sk->sk_type != SOCK_SEQPACKET &&
517 sk->sk_type != SOCK_STREAM) {
516 l2cap_sock_clear_timer(sk); 518 l2cap_sock_clear_timer(sk);
517 sk->sk_state = BT_CONNECTED; 519 sk->sk_state = BT_CONNECTED;
518 sk->sk_state_change(sk); 520 sk->sk_state_change(sk);
@@ -721,7 +723,8 @@ static void __l2cap_sock_close(struct sock *sk, int reason)
721 723
722 case BT_CONNECTED: 724 case BT_CONNECTED:
723 case BT_CONFIG: 725 case BT_CONFIG:
724 if (sk->sk_type == SOCK_SEQPACKET) { 726 if (sk->sk_type == SOCK_SEQPACKET ||
727 sk->sk_type == SOCK_STREAM) {
725 struct l2cap_conn *conn = l2cap_pi(sk)->conn; 728 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
726 729
727 sk->sk_state = BT_DISCONN; 730 sk->sk_state = BT_DISCONN;
@@ -732,7 +735,8 @@ static void __l2cap_sock_close(struct sock *sk, int reason)
732 break; 735 break;
733 736
734 case BT_CONNECT2: 737 case BT_CONNECT2:
735 if (sk->sk_type == SOCK_SEQPACKET) { 738 if (sk->sk_type == SOCK_SEQPACKET ||
739 sk->sk_type == SOCK_STREAM) {
736 struct l2cap_conn *conn = l2cap_pi(sk)->conn; 740 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
737 struct l2cap_conn_rsp rsp; 741 struct l2cap_conn_rsp rsp;
738 __u16 result; 742 __u16 result;
@@ -795,7 +799,10 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
795 } else { 799 } else {
796 pi->imtu = L2CAP_DEFAULT_MTU; 800 pi->imtu = L2CAP_DEFAULT_MTU;
797 pi->omtu = 0; 801 pi->omtu = 0;
798 pi->mode = L2CAP_MODE_BASIC; 802 if (enable_ertm && sk->sk_type == SOCK_STREAM)
803 pi->mode = L2CAP_MODE_ERTM;
804 else
805 pi->mode = L2CAP_MODE_BASIC;
799 pi->max_tx = max_transmit; 806 pi->max_tx = max_transmit;
800 pi->fcs = L2CAP_FCS_CRC16; 807 pi->fcs = L2CAP_FCS_CRC16;
801 pi->tx_win = tx_window; 808 pi->tx_win = tx_window;
@@ -852,7 +859,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
852 859
853 sock->state = SS_UNCONNECTED; 860 sock->state = SS_UNCONNECTED;
854 861
855 if (sock->type != SOCK_SEQPACKET && 862 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
856 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW) 863 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
857 return -ESOCKTNOSUPPORT; 864 return -ESOCKTNOSUPPORT;
858 865
@@ -1000,7 +1007,8 @@ static int l2cap_do_connect(struct sock *sk)
1000 l2cap_sock_set_timer(sk, sk->sk_sndtimeo); 1007 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
1001 1008
1002 if (hcon->state == BT_CONNECTED) { 1009 if (hcon->state == BT_CONNECTED) {
1003 if (sk->sk_type != SOCK_SEQPACKET) { 1010 if (sk->sk_type != SOCK_SEQPACKET &&
1011 sk->sk_type != SOCK_STREAM) {
1004 l2cap_sock_clear_timer(sk); 1012 l2cap_sock_clear_timer(sk);
1005 sk->sk_state = BT_CONNECTED; 1013 sk->sk_state = BT_CONNECTED;
1006 } else 1014 } else
@@ -1034,7 +1042,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
1034 1042
1035 lock_sock(sk); 1043 lock_sock(sk);
1036 1044
1037 if (sk->sk_type == SOCK_SEQPACKET && !la.l2_psm) { 1045 if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
1046 && !la.l2_psm) {
1038 err = -EINVAL; 1047 err = -EINVAL;
1039 goto done; 1048 goto done;
1040 } 1049 }
@@ -1098,7 +1107,8 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
1098 1107
1099 lock_sock(sk); 1108 lock_sock(sk);
1100 1109
1101 if (sk->sk_state != BT_BOUND || sock->type != SOCK_SEQPACKET) { 1110 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
1111 || sk->sk_state != BT_BOUND) {
1102 err = -EBADFD; 1112 err = -EBADFD;
1103 goto done; 1113 goto done;
1104 } 1114 }
@@ -1857,7 +1867,8 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
1857 1867
1858 switch (optname) { 1868 switch (optname) {
1859 case BT_SECURITY: 1869 case BT_SECURITY:
1860 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) { 1870 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
1871 && sk->sk_type != SOCK_RAW) {
1861 err = -EINVAL; 1872 err = -EINVAL;
1862 break; 1873 break;
1863 } 1874 }
@@ -2007,7 +2018,8 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
2007 2018
2008 switch (optname) { 2019 switch (optname) {
2009 case BT_SECURITY: 2020 case BT_SECURITY:
2010 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) { 2021 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2022 && sk->sk_type != SOCK_RAW) {
2011 err = -EINVAL; 2023 err = -EINVAL;
2012 break; 2024 break;
2013 } 2025 }
@@ -2314,7 +2326,7 @@ static int l2cap_build_conf_req(struct sock *sk, void *data)
2314{ 2326{
2315 struct l2cap_pinfo *pi = l2cap_pi(sk); 2327 struct l2cap_pinfo *pi = l2cap_pi(sk);
2316 struct l2cap_conf_req *req = data; 2328 struct l2cap_conf_req *req = data;
2317 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; 2329 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
2318 void *ptr = req->data; 2330 void *ptr = req->data;
2319 2331
2320 BT_DBG("sk %p", sk); 2332 BT_DBG("sk %p", sk);
@@ -3997,7 +4009,7 @@ static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
3997 4009
3998static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt) 4010static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
3999{ 4011{
4000 if (sk->sk_type != SOCK_SEQPACKET) 4012 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
4001 return; 4013 return;
4002 4014
4003 if (encrypt == 0x00) { 4015 if (encrypt == 0x00) {