diff options
Diffstat (limited to 'net/bluetooth/l2cap.c')
-rw-r--r-- | net/bluetooth/l2cap.c | 40 |
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 | ||
3998 | static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt) | 4010 | static 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) { |