OLD | NEW |
1 /* | 1 /* |
2 BlueZ - Bluetooth protocol stack for Linux | 2 BlueZ - Bluetooth protocol stack for Linux |
3 Copyright (C) 2000-2001 Qualcomm Incorporated | 3 Copyright (C) 2000-2001 Qualcomm Incorporated |
4 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org> | 4 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org> |
5 Copyright (C) 2010 Google Inc. | 5 Copyright (C) 2010 Google Inc. |
6 | 6 |
7 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> | 7 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> |
8 | 8 |
9 This program is free software; you can redistribute it and/or modify | 9 This program is free software; you can redistribute it and/or modify |
10 it under the terms of the GNU General Public License version 2 as | 10 it under the terms of the GNU General Public License version 2 as |
(...skipping 1431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1442 { | 1442 { |
1443 struct l2cap_pinfo *pi = l2cap_pi(sk); | 1443 struct l2cap_pinfo *pi = l2cap_pi(sk); |
1444 | 1444 |
1445 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len); | 1445 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len); |
1446 | 1446 |
1447 hci_send_acl(pi->conn->hcon, skb, 0); | 1447 hci_send_acl(pi->conn->hcon, skb, 0); |
1448 } | 1448 } |
1449 | 1449 |
1450 static void l2cap_streaming_send(struct sock *sk) | 1450 static void l2cap_streaming_send(struct sock *sk) |
1451 { | 1451 { |
1452 » struct sk_buff *skb, *tx_skb; | 1452 » struct sk_buff *skb; |
1453 struct l2cap_pinfo *pi = l2cap_pi(sk); | 1453 struct l2cap_pinfo *pi = l2cap_pi(sk); |
1454 u16 control, fcs; | 1454 u16 control, fcs; |
1455 | 1455 |
1456 » while ((skb = sk->sk_send_head)) { | 1456 » while ((skb = skb_dequeue(TX_QUEUE(sk)))) { |
1457 » » tx_skb = skb_clone(skb, GFP_ATOMIC); | 1457 » » control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE); |
1458 | |
1459 » » control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); | |
1460 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; | 1458 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; |
1461 » » put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); | 1459 » » put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE); |
1462 | 1460 |
1463 if (pi->fcs == L2CAP_FCS_CRC16) { | 1461 if (pi->fcs == L2CAP_FCS_CRC16) { |
1464 » » » fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2); | 1462 » » » fcs = crc16(0, (u8 *)skb->data, skb->len - 2); |
1465 » » » put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2); | 1463 » » » put_unaligned_le16(fcs, skb->data + skb->len - 2); |
1466 } | 1464 } |
1467 | 1465 |
1468 » » l2cap_do_send(sk, tx_skb); | 1466 » » l2cap_do_send(sk, skb); |
1469 | 1467 |
1470 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; | 1468 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; |
1471 | |
1472 if (skb_queue_is_last(TX_QUEUE(sk), skb)) | |
1473 sk->sk_send_head = NULL; | |
1474 else | |
1475 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb); | |
1476 | |
1477 skb = skb_dequeue(TX_QUEUE(sk)); | |
1478 kfree_skb(skb); | |
1479 } | 1469 } |
1480 } | 1470 } |
1481 | 1471 |
1482 static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) | 1472 static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) |
1483 { | 1473 { |
1484 struct l2cap_pinfo *pi = l2cap_pi(sk); | 1474 struct l2cap_pinfo *pi = l2cap_pi(sk); |
1485 struct sk_buff *skb, *tx_skb; | 1475 struct sk_buff *skb, *tx_skb; |
1486 u16 control, fcs; | 1476 u16 control, fcs; |
1487 | 1477 |
1488 skb = skb_peek(TX_QUEUE(sk)); | 1478 skb = skb_peek(TX_QUEUE(sk)); |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1961 struct l2cap_options opts; | 1951 struct l2cap_options opts; |
1962 int len, err = 0; | 1952 int len, err = 0; |
1963 u32 opt; | 1953 u32 opt; |
1964 | 1954 |
1965 BT_DBG("sk %p", sk); | 1955 BT_DBG("sk %p", sk); |
1966 | 1956 |
1967 lock_sock(sk); | 1957 lock_sock(sk); |
1968 | 1958 |
1969 switch (optname) { | 1959 switch (optname) { |
1970 case L2CAP_OPTIONS: | 1960 case L2CAP_OPTIONS: |
| 1961 if (sk->sk_state == BT_CONNECTED) { |
| 1962 err = -EINVAL; |
| 1963 break; |
| 1964 } |
| 1965 |
1971 opts.imtu = l2cap_pi(sk)->imtu; | 1966 opts.imtu = l2cap_pi(sk)->imtu; |
1972 opts.omtu = l2cap_pi(sk)->omtu; | 1967 opts.omtu = l2cap_pi(sk)->omtu; |
1973 opts.flush_to = l2cap_pi(sk)->flush_to; | 1968 opts.flush_to = l2cap_pi(sk)->flush_to; |
1974 opts.mode = l2cap_pi(sk)->mode; | 1969 opts.mode = l2cap_pi(sk)->mode; |
1975 opts.fcs = l2cap_pi(sk)->fcs; | 1970 opts.fcs = l2cap_pi(sk)->fcs; |
1976 opts.max_tx = l2cap_pi(sk)->max_tx; | 1971 opts.max_tx = l2cap_pi(sk)->max_tx; |
1977 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win; | 1972 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win; |
1978 | 1973 |
1979 len = min_t(unsigned int, sizeof(opts), optlen); | 1974 len = min_t(unsigned int, sizeof(opts), optlen); |
1980 if (copy_from_user((char *) &opts, optval, len)) { | 1975 if (copy_from_user((char *) &opts, optval, len)) { |
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2776 | 2771 |
2777 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data); | 2772 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data); |
2778 | 2773 |
2779 while (len >= L2CAP_CONF_OPT_SIZE) { | 2774 while (len >= L2CAP_CONF_OPT_SIZE) { |
2780 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); | 2775 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); |
2781 | 2776 |
2782 switch (type) { | 2777 switch (type) { |
2783 case L2CAP_CONF_MTU: | 2778 case L2CAP_CONF_MTU: |
2784 if (val < L2CAP_DEFAULT_MIN_MTU) { | 2779 if (val < L2CAP_DEFAULT_MIN_MTU) { |
2785 *result = L2CAP_CONF_UNACCEPT; | 2780 *result = L2CAP_CONF_UNACCEPT; |
2786 » » » » pi->omtu = L2CAP_DEFAULT_MIN_MTU; | 2781 » » » » pi->imtu = L2CAP_DEFAULT_MIN_MTU; |
2787 } else | 2782 } else |
2788 » » » » pi->omtu = val; | 2783 » » » » pi->imtu = val; |
2789 » » » l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu); | 2784 » » » l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu); |
2790 break; | 2785 break; |
2791 | 2786 |
2792 case L2CAP_CONF_FLUSH_TO: | 2787 case L2CAP_CONF_FLUSH_TO: |
2793 pi->flush_to = val; | 2788 pi->flush_to = val; |
2794 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, | 2789 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, |
2795 2, pi->flush_to); | 2790 2, pi->flush_to); |
2796 break; | 2791 break; |
2797 | 2792 |
2798 case L2CAP_CONF_RFC: | 2793 case L2CAP_CONF_RFC: |
2799 if (olen == sizeof(rfc)) | 2794 if (olen == sizeof(rfc)) |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3076 | 3071 |
3077 default: | 3072 default: |
3078 l2cap_chan_del(sk, ECONNREFUSED); | 3073 l2cap_chan_del(sk, ECONNREFUSED); |
3079 break; | 3074 break; |
3080 } | 3075 } |
3081 | 3076 |
3082 bh_unlock_sock(sk); | 3077 bh_unlock_sock(sk); |
3083 return 0; | 3078 return 0; |
3084 } | 3079 } |
3085 | 3080 |
| 3081 static inline void set_default_fcs(struct l2cap_pinfo *pi) |
| 3082 { |
| 3083 /* FCS is enabled only in ERTM or streaming mode, if one or both |
| 3084 * sides request it. |
| 3085 */ |
| 3086 if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING) |
| 3087 pi->fcs = L2CAP_FCS_NONE; |
| 3088 else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV)) |
| 3089 pi->fcs = L2CAP_FCS_CRC16; |
| 3090 } |
| 3091 |
3086 static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
*cmd, u16 cmd_len, u8 *data) | 3092 static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
*cmd, u16 cmd_len, u8 *data) |
3087 { | 3093 { |
3088 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; | 3094 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; |
3089 u16 dcid, flags; | 3095 u16 dcid, flags; |
3090 u8 rsp[64]; | 3096 u8 rsp[64]; |
3091 struct sock *sk; | 3097 struct sock *sk; |
3092 int len; | 3098 int len; |
3093 | 3099 |
3094 dcid = __le16_to_cpu(req->dcid); | 3100 dcid = __le16_to_cpu(req->dcid); |
3095 flags = __le16_to_cpu(req->flags); | 3101 flags = __le16_to_cpu(req->flags); |
3096 | 3102 |
3097 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags); | 3103 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags); |
3098 | 3104 |
3099 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid); | 3105 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid); |
3100 if (!sk) | 3106 if (!sk) |
3101 return -ENOENT; | 3107 return -ENOENT; |
3102 | 3108 |
3103 » if (sk->sk_state != BT_CONFIG) { | 3109 » if (sk->sk_state == BT_DISCONN) |
3104 » » struct l2cap_cmd_rej rej; | |
3105 | |
3106 » » rej.reason = cpu_to_le16(0x0002); | |
3107 » » l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, | |
3108 » » » » sizeof(rej), &rej); | |
3109 goto unlock; | 3110 goto unlock; |
3110 } | |
3111 | 3111 |
3112 /* Reject if config buffer is too small. */ | 3112 /* Reject if config buffer is too small. */ |
3113 len = cmd_len - sizeof(*req); | 3113 len = cmd_len - sizeof(*req); |
3114 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) { | 3114 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) { |
3115 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | 3115 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, |
3116 l2cap_build_conf_rsp(sk, rsp, | 3116 l2cap_build_conf_rsp(sk, rsp, |
3117 L2CAP_CONF_REJECT, flags), rsp); | 3117 L2CAP_CONF_REJECT, flags), rsp); |
3118 goto unlock; | 3118 goto unlock; |
3119 } | 3119 } |
3120 | 3120 |
(...skipping 19 matching lines...) Expand all Loading... |
3140 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp); | 3140 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp); |
3141 l2cap_pi(sk)->num_conf_rsp++; | 3141 l2cap_pi(sk)->num_conf_rsp++; |
3142 | 3142 |
3143 /* Reset config buffer. */ | 3143 /* Reset config buffer. */ |
3144 l2cap_pi(sk)->conf_len = 0; | 3144 l2cap_pi(sk)->conf_len = 0; |
3145 | 3145 |
3146 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE)) | 3146 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE)) |
3147 goto unlock; | 3147 goto unlock; |
3148 | 3148 |
3149 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) { | 3149 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) { |
3150 » » if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) || | 3150 » » set_default_fcs(l2cap_pi(sk)); |
3151 » » l2cap_pi(sk)->fcs != L2CAP_FCS_NONE) | |
3152 » » » l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; | |
3153 | 3151 |
3154 sk->sk_state = BT_CONNECTED; | 3152 sk->sk_state = BT_CONNECTED; |
3155 | 3153 |
3156 l2cap_pi(sk)->next_tx_seq = 0; | 3154 l2cap_pi(sk)->next_tx_seq = 0; |
3157 l2cap_pi(sk)->expected_tx_seq = 0; | 3155 l2cap_pi(sk)->expected_tx_seq = 0; |
3158 __skb_queue_head_init(TX_QUEUE(sk)); | 3156 __skb_queue_head_init(TX_QUEUE(sk)); |
3159 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) | 3157 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) |
3160 l2cap_ertm_init(sk); | 3158 l2cap_ertm_init(sk); |
3161 | 3159 |
3162 l2cap_chan_ready(sk); | 3160 l2cap_chan_ready(sk); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3230 l2cap_send_disconn_req(conn, sk, ECONNRESET); | 3228 l2cap_send_disconn_req(conn, sk, ECONNRESET); |
3231 goto done; | 3229 goto done; |
3232 } | 3230 } |
3233 | 3231 |
3234 if (flags & 0x01) | 3232 if (flags & 0x01) |
3235 goto done; | 3233 goto done; |
3236 | 3234 |
3237 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE; | 3235 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE; |
3238 | 3236 |
3239 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) { | 3237 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) { |
3240 » » if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) || | 3238 » » set_default_fcs(l2cap_pi(sk)); |
3241 » » l2cap_pi(sk)->fcs != L2CAP_FCS_NONE) | |
3242 » » » l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; | |
3243 | 3239 |
3244 sk->sk_state = BT_CONNECTED; | 3240 sk->sk_state = BT_CONNECTED; |
3245 l2cap_pi(sk)->next_tx_seq = 0; | 3241 l2cap_pi(sk)->next_tx_seq = 0; |
3246 l2cap_pi(sk)->expected_tx_seq = 0; | 3242 l2cap_pi(sk)->expected_tx_seq = 0; |
3247 __skb_queue_head_init(TX_QUEUE(sk)); | 3243 __skb_queue_head_init(TX_QUEUE(sk)); |
3248 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) | 3244 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) |
3249 l2cap_ertm_init(sk); | 3245 l2cap_ertm_init(sk); |
3250 | 3246 |
3251 l2cap_chan_ready(sk); | 3247 l2cap_chan_ready(sk); |
3252 } | 3248 } |
(...skipping 1631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4884 module_exit(l2cap_exit); | 4880 module_exit(l2cap_exit); |
4885 | 4881 |
4886 module_param(disable_ertm, bool, 0644); | 4882 module_param(disable_ertm, bool, 0644); |
4887 MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode"); | 4883 MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode"); |
4888 | 4884 |
4889 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); | 4885 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); |
4890 MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION); | 4886 MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION); |
4891 MODULE_VERSION(VERSION); | 4887 MODULE_VERSION(VERSION); |
4892 MODULE_LICENSE("GPL"); | 4888 MODULE_LICENSE("GPL"); |
4893 MODULE_ALIAS("bt-proto-0"); | 4889 MODULE_ALIAS("bt-proto-0"); |
OLD | NEW |