blob: cf4481f7f566b7e0161caff14d8ca6be085de867 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth L2CAP core and sockets. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080030#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/errno.h>
32#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/sched.h>
34#include <linux/slab.h>
35#include <linux/poll.h>
36#include <linux/fcntl.h>
37#include <linux/init.h>
38#include <linux/interrupt.h>
39#include <linux/socket.h>
40#include <linux/skbuff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <linux/list.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080042#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010043#include <linux/debugfs.h>
44#include <linux/seq_file.h>
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -030045#include <linux/uaccess.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030046#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <net/sock.h>
48
49#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070050#include <asm/unaligned.h>
51
52#include <net/bluetooth/bluetooth.h>
53#include <net/bluetooth/hci_core.h>
54#include <net/bluetooth/l2cap.h>
55
Marcel Holtmann44dd46d2009-05-02 19:09:01 -070056#define VERSION "2.14"
57
58static int enable_ertm = 0;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020059
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070060static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmanne1027a72009-02-09 09:18:02 +010061static u8 l2cap_fixed_chan[8] = { 0x02, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070062
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080063static const struct proto_ops l2cap_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030065static struct workqueue_struct *_busy_wq;
66
Linus Torvalds1da177e2005-04-16 15:20:36 -070067static struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070068 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070069};
70
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030071static void l2cap_busy_work(struct work_struct *work);
72
Linus Torvalds1da177e2005-04-16 15:20:36 -070073static void __l2cap_sock_close(struct sock *sk, int reason);
74static void l2cap_sock_close(struct sock *sk);
75static void l2cap_sock_kill(struct sock *sk);
76
77static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
78 u8 code, u8 ident, u16 dlen, void *data);
79
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -030080static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
81
Linus Torvalds1da177e2005-04-16 15:20:36 -070082/* ---- L2CAP timers ---- */
83static void l2cap_sock_timeout(unsigned long arg)
84{
85 struct sock *sk = (struct sock *) arg;
Marcel Holtmannb1235d72008-07-14 20:13:54 +020086 int reason;
Linus Torvalds1da177e2005-04-16 15:20:36 -070087
88 BT_DBG("sock %p state %d", sk, sk->sk_state);
89
90 bh_lock_sock(sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +020091
Marcel Holtmannf62e4322009-01-15 21:58:44 +010092 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
93 reason = ECONNREFUSED;
94 else if (sk->sk_state == BT_CONNECT &&
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +010095 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
Marcel Holtmannb1235d72008-07-14 20:13:54 +020096 reason = ECONNREFUSED;
97 else
98 reason = ETIMEDOUT;
99
100 __l2cap_sock_close(sk, reason);
101
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102 bh_unlock_sock(sk);
103
104 l2cap_sock_kill(sk);
105 sock_put(sk);
106}
107
108static void l2cap_sock_set_timer(struct sock *sk, long timeout)
109{
110 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
111 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
112}
113
114static void l2cap_sock_clear_timer(struct sock *sk)
115{
116 BT_DBG("sock %p state %d", sk, sk->sk_state);
117 sk_stop_timer(sk, &sk->sk_timer);
118}
119
Marcel Holtmann01394182006-07-03 10:02:46 +0200120/* ---- L2CAP channels ---- */
121static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
122{
123 struct sock *s;
124 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
125 if (l2cap_pi(s)->dcid == cid)
126 break;
127 }
128 return s;
129}
130
131static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
132{
133 struct sock *s;
134 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
135 if (l2cap_pi(s)->scid == cid)
136 break;
137 }
138 return s;
139}
140
141/* Find channel with given SCID.
142 * Returns locked socket */
143static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
144{
145 struct sock *s;
146 read_lock(&l->lock);
147 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300148 if (s)
149 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200150 read_unlock(&l->lock);
151 return s;
152}
153
154static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
155{
156 struct sock *s;
157 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
158 if (l2cap_pi(s)->ident == ident)
159 break;
160 }
161 return s;
162}
163
164static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
165{
166 struct sock *s;
167 read_lock(&l->lock);
168 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300169 if (s)
170 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200171 read_unlock(&l->lock);
172 return s;
173}
174
175static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
176{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300177 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200178
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300179 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300180 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200181 return cid;
182 }
183
184 return 0;
185}
186
187static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
188{
189 sock_hold(sk);
190
191 if (l->head)
192 l2cap_pi(l->head)->prev_c = sk;
193
194 l2cap_pi(sk)->next_c = l->head;
195 l2cap_pi(sk)->prev_c = NULL;
196 l->head = sk;
197}
198
199static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
200{
201 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
202
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200203 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200204 if (sk == l->head)
205 l->head = next;
206
207 if (next)
208 l2cap_pi(next)->prev_c = prev;
209 if (prev)
210 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200211 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200212
213 __sock_put(sk);
214}
215
216static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
217{
218 struct l2cap_chan_list *l = &conn->chan_list;
219
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300220 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
221 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200222
Marcel Holtmann2950f212009-02-12 14:02:50 +0100223 conn->disc_reason = 0x13;
224
Marcel Holtmann01394182006-07-03 10:02:46 +0200225 l2cap_pi(sk)->conn = conn;
226
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300227 if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200228 /* Alloc CID for connection-oriented socket */
229 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
230 } else if (sk->sk_type == SOCK_DGRAM) {
231 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300232 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
233 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200234 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
235 } else {
236 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300237 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
238 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200239 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
240 }
241
242 __l2cap_chan_link(l, sk);
243
244 if (parent)
245 bt_accept_enqueue(parent, sk);
246}
247
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900248/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200249 * Must be called on the locked socket. */
250static void l2cap_chan_del(struct sock *sk, int err)
251{
252 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
253 struct sock *parent = bt_sk(sk)->parent;
254
255 l2cap_sock_clear_timer(sk);
256
257 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
258
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900259 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200260 /* Unlink from channel list */
261 l2cap_chan_unlink(&conn->chan_list, sk);
262 l2cap_pi(sk)->conn = NULL;
263 hci_conn_put(conn->hcon);
264 }
265
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200266 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200267 sock_set_flag(sk, SOCK_ZAPPED);
268
269 if (err)
270 sk->sk_err = err;
271
272 if (parent) {
273 bt_accept_unlink(sk);
274 parent->sk_data_ready(parent, 0);
275 } else
276 sk->sk_state_change(sk);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300277
278 skb_queue_purge(TX_QUEUE(sk));
279
280 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
281 struct srej_list *l, *tmp;
282
283 del_timer(&l2cap_pi(sk)->retrans_timer);
284 del_timer(&l2cap_pi(sk)->monitor_timer);
285 del_timer(&l2cap_pi(sk)->ack_timer);
286
287 skb_queue_purge(SREJ_QUEUE(sk));
288 skb_queue_purge(BUSY_QUEUE(sk));
289
290 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
291 list_del(&l->list);
292 kfree(l);
293 }
294 }
Marcel Holtmann01394182006-07-03 10:02:46 +0200295}
296
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200297/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100298static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200299{
300 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100301 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200302
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100303 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
304 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
305 auth_type = HCI_AT_NO_BONDING_MITM;
306 else
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300307 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100308
309 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
310 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
311 } else {
312 switch (l2cap_pi(sk)->sec_level) {
313 case BT_SECURITY_HIGH:
314 auth_type = HCI_AT_GENERAL_BONDING_MITM;
315 break;
316 case BT_SECURITY_MEDIUM:
317 auth_type = HCI_AT_GENERAL_BONDING;
318 break;
319 default:
320 auth_type = HCI_AT_NO_BONDING;
321 break;
322 }
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100323 }
324
325 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
326 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200327}
328
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200329static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
330{
331 u8 id;
332
333 /* Get next available identificator.
334 * 1 - 128 are used by kernel.
335 * 129 - 199 are reserved.
336 * 200 - 254 are used by utilities like l2ping, etc.
337 */
338
339 spin_lock_bh(&conn->lock);
340
341 if (++conn->tx_ident > 128)
342 conn->tx_ident = 1;
343
344 id = conn->tx_ident;
345
346 spin_unlock_bh(&conn->lock);
347
348 return id;
349}
350
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300351static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200352{
353 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
354
355 BT_DBG("code 0x%2.2x", code);
356
357 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300358 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200359
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300360 hci_send_acl(conn->hcon, skb, 0);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200361}
362
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300363static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300364{
365 struct sk_buff *skb;
366 struct l2cap_hdr *lh;
367 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300368 struct sock *sk = (struct sock *)pi;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300369 int count, hlen = L2CAP_HDR_SIZE + 2;
370
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300371 if (sk->sk_state != BT_CONNECTED)
372 return;
373
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300374 if (pi->fcs == L2CAP_FCS_CRC16)
375 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300376
377 BT_DBG("pi %p, control 0x%2.2x", pi, control);
378
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300379 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300380 control |= L2CAP_CTRL_FRAME_TYPE;
381
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -0300382 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
383 control |= L2CAP_CTRL_FINAL;
384 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
385 }
386
Gustavo F. Padovanf0946cc2010-05-01 16:15:37 -0300387 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
388 control |= L2CAP_CTRL_POLL;
389 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
390 }
391
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300392 skb = bt_skb_alloc(count, GFP_ATOMIC);
393 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300394 return;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300395
396 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300397 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300398 lh->cid = cpu_to_le16(pi->dcid);
399 put_unaligned_le16(control, skb_put(skb, 2));
400
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300401 if (pi->fcs == L2CAP_FCS_CRC16) {
402 u16 fcs = crc16(0, (u8 *)lh, count - 2);
403 put_unaligned_le16(fcs, skb_put(skb, 2));
404 }
405
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300406 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300407}
408
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300409static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300410{
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300411 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300412 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300413 pi->conn_state |= L2CAP_CONN_RNR_SENT;
414 } else
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300415 control |= L2CAP_SUPER_RCV_READY;
416
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300417 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
418
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300419 l2cap_send_sframe(pi, control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300420}
421
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300422static inline int __l2cap_no_conn_pending(struct sock *sk)
423{
424 return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND);
425}
426
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200427static void l2cap_do_start(struct sock *sk)
428{
429 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
430
431 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100432 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
433 return;
434
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300435 if (l2cap_check_security(sk) && __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200436 struct l2cap_conn_req req;
437 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
438 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200439
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200440 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300441 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200442
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200443 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200444 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200445 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200446 } else {
447 struct l2cap_info_req req;
448 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
449
450 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
451 conn->info_ident = l2cap_get_ident(conn);
452
453 mod_timer(&conn->info_timer, jiffies +
454 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
455
456 l2cap_send_cmd(conn, conn->info_ident,
457 L2CAP_INFO_REQ, sizeof(req), &req);
458 }
459}
460
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300461static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
462{
463 u32 local_feat_mask = l2cap_feat_mask;
464 if (enable_ertm)
465 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
466
467 switch (mode) {
468 case L2CAP_MODE_ERTM:
469 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
470 case L2CAP_MODE_STREAMING:
471 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
472 default:
473 return 0x00;
474 }
475}
476
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300477static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300478{
479 struct l2cap_disconn_req req;
480
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300481 if (!conn)
482 return;
483
484 skb_queue_purge(TX_QUEUE(sk));
485
486 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
487 del_timer(&l2cap_pi(sk)->retrans_timer);
488 del_timer(&l2cap_pi(sk)->monitor_timer);
489 del_timer(&l2cap_pi(sk)->ack_timer);
490 }
491
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300492 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
493 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
494 l2cap_send_cmd(conn, l2cap_get_ident(conn),
495 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300496
497 sk->sk_state = BT_DISCONN;
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300498 sk->sk_err = err;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300499}
500
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200502static void l2cap_conn_start(struct l2cap_conn *conn)
503{
504 struct l2cap_chan_list *l = &conn->chan_list;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300505 struct sock_del_list del, *tmp1, *tmp2;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200506 struct sock *sk;
507
508 BT_DBG("conn %p", conn);
509
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300510 INIT_LIST_HEAD(&del.list);
511
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200512 read_lock(&l->lock);
513
514 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
515 bh_lock_sock(sk);
516
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300517 if (sk->sk_type != SOCK_SEQPACKET &&
518 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200519 bh_unlock_sock(sk);
520 continue;
521 }
522
523 if (sk->sk_state == BT_CONNECT) {
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300524 if (l2cap_check_security(sk) &&
525 __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200526 struct l2cap_conn_req req;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300527
528 if (!l2cap_mode_supported(l2cap_pi(sk)->mode,
529 conn->feat_mask)
530 && l2cap_pi(sk)->conf_state &
531 L2CAP_CONF_STATE2_DEVICE) {
532 tmp1 = kzalloc(sizeof(struct srej_list),
533 GFP_ATOMIC);
534 tmp1->sk = sk;
535 list_add_tail(&tmp1->list, &del.list);
536 bh_unlock_sock(sk);
537 continue;
538 }
539
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200540 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
541 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200542
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200543 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300544 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200545
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200546 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200547 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200548 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200549 } else if (sk->sk_state == BT_CONNECT2) {
550 struct l2cap_conn_rsp rsp;
551 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
552 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
553
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100554 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100555 if (bt_sk(sk)->defer_setup) {
556 struct sock *parent = bt_sk(sk)->parent;
557 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
558 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
559 parent->sk_data_ready(parent, 0);
560
561 } else {
562 sk->sk_state = BT_CONFIG;
563 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
564 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
565 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200566 } else {
567 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
568 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
569 }
570
571 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
572 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
573 }
574
575 bh_unlock_sock(sk);
576 }
577
578 read_unlock(&l->lock);
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300579
580 list_for_each_entry_safe(tmp1, tmp2, &del.list, list) {
581 bh_lock_sock(tmp1->sk);
582 __l2cap_sock_close(tmp1->sk, ECONNRESET);
583 bh_unlock_sock(tmp1->sk);
584 list_del(&tmp1->list);
585 kfree(tmp1);
586 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200587}
588
589static void l2cap_conn_ready(struct l2cap_conn *conn)
590{
591 struct l2cap_chan_list *l = &conn->chan_list;
592 struct sock *sk;
593
594 BT_DBG("conn %p", conn);
595
596 read_lock(&l->lock);
597
598 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
599 bh_lock_sock(sk);
600
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300601 if (sk->sk_type != SOCK_SEQPACKET &&
602 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200603 l2cap_sock_clear_timer(sk);
604 sk->sk_state = BT_CONNECTED;
605 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200606 } else if (sk->sk_state == BT_CONNECT)
607 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200608
609 bh_unlock_sock(sk);
610 }
611
612 read_unlock(&l->lock);
613}
614
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200615/* Notify sockets that we cannot guaranty reliability anymore */
616static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
617{
618 struct l2cap_chan_list *l = &conn->chan_list;
619 struct sock *sk;
620
621 BT_DBG("conn %p", conn);
622
623 read_lock(&l->lock);
624
625 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100626 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200627 sk->sk_err = err;
628 }
629
630 read_unlock(&l->lock);
631}
632
633static void l2cap_info_timeout(unsigned long arg)
634{
635 struct l2cap_conn *conn = (void *) arg;
636
Marcel Holtmann984947d2009-02-06 23:35:19 +0100637 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100638 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100639
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200640 l2cap_conn_start(conn);
641}
642
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
644{
Marcel Holtmann01394182006-07-03 10:02:46 +0200645 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646
Marcel Holtmann01394182006-07-03 10:02:46 +0200647 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648 return conn;
649
Marcel Holtmann01394182006-07-03 10:02:46 +0200650 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
651 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653
654 hcon->l2cap_data = conn;
655 conn->hcon = hcon;
656
Marcel Holtmann01394182006-07-03 10:02:46 +0200657 BT_DBG("hcon %p conn %p", hcon, conn);
658
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659 conn->mtu = hcon->hdev->acl_mtu;
660 conn->src = &hcon->hdev->bdaddr;
661 conn->dst = &hcon->dst;
662
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200663 conn->feat_mask = 0;
664
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 spin_lock_init(&conn->lock);
666 rwlock_init(&conn->chan_list.lock);
667
Dave Young45054dc2009-10-18 20:28:30 +0000668 setup_timer(&conn->info_timer, l2cap_info_timeout,
669 (unsigned long) conn);
670
Marcel Holtmann2950f212009-02-12 14:02:50 +0100671 conn->disc_reason = 0x13;
672
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 return conn;
674}
675
Marcel Holtmann01394182006-07-03 10:02:46 +0200676static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677{
Marcel Holtmann01394182006-07-03 10:02:46 +0200678 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 struct sock *sk;
680
Marcel Holtmann01394182006-07-03 10:02:46 +0200681 if (!conn)
682 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683
684 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
685
Wei Yongjun7585b972009-02-25 18:29:52 +0800686 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687
688 /* Kill channels */
689 while ((sk = conn->chan_list.head)) {
690 bh_lock_sock(sk);
691 l2cap_chan_del(sk, err);
692 bh_unlock_sock(sk);
693 l2cap_sock_kill(sk);
694 }
695
Dave Young8e8440f2008-03-03 12:18:55 -0800696 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
697 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800698
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699 hcon->l2cap_data = NULL;
700 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701}
702
703static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
704{
705 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200706 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200708 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709}
710
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700712static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713{
714 struct sock *sk;
715 struct hlist_node *node;
716 sk_for_each(sk, node, &l2cap_sk_list.head)
717 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
718 goto found;
719 sk = NULL;
720found:
721 return sk;
722}
723
724/* Find socket with psm and source bdaddr.
725 * Returns closest match.
726 */
Al Viro8e036fc2007-07-29 00:16:36 -0700727static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728{
729 struct sock *sk = NULL, *sk1 = NULL;
730 struct hlist_node *node;
731
732 sk_for_each(sk, node, &l2cap_sk_list.head) {
733 if (state && sk->sk_state != state)
734 continue;
735
736 if (l2cap_pi(sk)->psm == psm) {
737 /* Exact match. */
738 if (!bacmp(&bt_sk(sk)->src, src))
739 break;
740
741 /* Closest match */
742 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
743 sk1 = sk;
744 }
745 }
746 return node ? sk : sk1;
747}
748
749/* Find socket with given address (psm, src).
750 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700751static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752{
753 struct sock *s;
754 read_lock(&l2cap_sk_list.lock);
755 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300756 if (s)
757 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758 read_unlock(&l2cap_sk_list.lock);
759 return s;
760}
761
762static void l2cap_sock_destruct(struct sock *sk)
763{
764 BT_DBG("sk %p", sk);
765
766 skb_queue_purge(&sk->sk_receive_queue);
767 skb_queue_purge(&sk->sk_write_queue);
768}
769
770static void l2cap_sock_cleanup_listen(struct sock *parent)
771{
772 struct sock *sk;
773
774 BT_DBG("parent %p", parent);
775
776 /* Close not yet accepted channels */
777 while ((sk = bt_accept_dequeue(parent, NULL)))
778 l2cap_sock_close(sk);
779
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200780 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781 sock_set_flag(parent, SOCK_ZAPPED);
782}
783
784/* Kill socket (only if zapped and orphan)
785 * Must be called on unlocked socket.
786 */
787static void l2cap_sock_kill(struct sock *sk)
788{
789 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
790 return;
791
792 BT_DBG("sk %p state %d", sk, sk->sk_state);
793
794 /* Kill poor orphan */
795 bt_sock_unlink(&l2cap_sk_list, sk);
796 sock_set_flag(sk, SOCK_DEAD);
797 sock_put(sk);
798}
799
800static void __l2cap_sock_close(struct sock *sk, int reason)
801{
802 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
803
804 switch (sk->sk_state) {
805 case BT_LISTEN:
806 l2cap_sock_cleanup_listen(sk);
807 break;
808
809 case BT_CONNECTED:
810 case BT_CONFIG:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300811 if (sk->sk_type == SOCK_SEQPACKET ||
812 sk->sk_type == SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300816 l2cap_send_disconn_req(conn, sk, reason);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200817 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 break;
820
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100821 case BT_CONNECT2:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300822 if (sk->sk_type == SOCK_SEQPACKET ||
823 sk->sk_type == SOCK_STREAM) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100824 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
825 struct l2cap_conn_rsp rsp;
826 __u16 result;
827
828 if (bt_sk(sk)->defer_setup)
829 result = L2CAP_CR_SEC_BLOCK;
830 else
831 result = L2CAP_CR_BAD_PSM;
832
833 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
834 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
835 rsp.result = cpu_to_le16(result);
836 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
837 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
838 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
839 } else
840 l2cap_chan_del(sk, reason);
841 break;
842
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843 case BT_CONNECT:
844 case BT_DISCONN:
845 l2cap_chan_del(sk, reason);
846 break;
847
848 default:
849 sock_set_flag(sk, SOCK_ZAPPED);
850 break;
851 }
852}
853
854/* Must be called on unlocked socket. */
855static void l2cap_sock_close(struct sock *sk)
856{
857 l2cap_sock_clear_timer(sk);
858 lock_sock(sk);
859 __l2cap_sock_close(sk, ECONNRESET);
860 release_sock(sk);
861 l2cap_sock_kill(sk);
862}
863
864static void l2cap_sock_init(struct sock *sk, struct sock *parent)
865{
866 struct l2cap_pinfo *pi = l2cap_pi(sk);
867
868 BT_DBG("sk %p", sk);
869
870 if (parent) {
871 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100872 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
873
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 pi->imtu = l2cap_pi(parent)->imtu;
875 pi->omtu = l2cap_pi(parent)->omtu;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300876 pi->conf_state = l2cap_pi(parent)->conf_state;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700877 pi->mode = l2cap_pi(parent)->mode;
878 pi->fcs = l2cap_pi(parent)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300879 pi->max_tx = l2cap_pi(parent)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -0300880 pi->tx_win = l2cap_pi(parent)->tx_win;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100881 pi->sec_level = l2cap_pi(parent)->sec_level;
882 pi->role_switch = l2cap_pi(parent)->role_switch;
883 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 } else {
885 pi->imtu = L2CAP_DEFAULT_MTU;
886 pi->omtu = 0;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300887 if (enable_ertm && sk->sk_type == SOCK_STREAM) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300888 pi->mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300889 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
890 } else {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300891 pi->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300892 }
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300893 pi->max_tx = L2CAP_DEFAULT_MAX_TX;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700894 pi->fcs = L2CAP_FCS_CRC16;
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300895 pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100896 pi->sec_level = BT_SECURITY_LOW;
897 pi->role_switch = 0;
898 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899 }
900
901 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200902 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000904 skb_queue_head_init(TX_QUEUE(sk));
905 skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300906 skb_queue_head_init(BUSY_QUEUE(sk));
Dave Young45054dc2009-10-18 20:28:30 +0000907 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908}
909
910static struct proto l2cap_proto = {
911 .name = "L2CAP",
912 .owner = THIS_MODULE,
913 .obj_size = sizeof(struct l2cap_pinfo)
914};
915
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700916static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917{
918 struct sock *sk;
919
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700920 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921 if (!sk)
922 return NULL;
923
924 sock_init_data(sock, sk);
925 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
926
927 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200928 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929
930 sock_reset_flag(sk, SOCK_ZAPPED);
931
932 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200933 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200935 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936
937 bt_sock_link(&l2cap_sk_list, sk);
938 return sk;
939}
940
Eric Paris3f378b62009-11-05 22:18:14 -0800941static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
942 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943{
944 struct sock *sk;
945
946 BT_DBG("sock %p", sock);
947
948 sock->state = SS_UNCONNECTED;
949
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300950 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
952 return -ESOCKTNOSUPPORT;
953
Eric Parisc84b3262009-11-05 20:45:52 -0800954 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 return -EPERM;
956
957 sock->ops = &l2cap_sock_ops;
958
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700959 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960 if (!sk)
961 return -ENOMEM;
962
963 l2cap_sock_init(sk, NULL);
964 return 0;
965}
966
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100967static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700968{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100970 struct sockaddr_l2 la;
971 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100973 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974
975 if (!addr || addr->sa_family != AF_BLUETOOTH)
976 return -EINVAL;
977
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100978 memset(&la, 0, sizeof(la));
979 len = min_t(unsigned int, sizeof(la), alen);
980 memcpy(&la, addr, len);
981
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100982 if (la.l2_cid)
983 return -EINVAL;
984
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985 lock_sock(sk);
986
987 if (sk->sk_state != BT_OPEN) {
988 err = -EBADFD;
989 goto done;
990 }
991
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200992 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +0100993 !capable(CAP_NET_BIND_SERVICE)) {
994 err = -EACCES;
995 goto done;
996 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900997
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998 write_lock_bh(&l2cap_sk_list.lock);
999
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001000 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001 err = -EADDRINUSE;
1002 } else {
1003 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001004 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
1005 l2cap_pi(sk)->psm = la.l2_psm;
1006 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001008
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001009 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
1010 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001011 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 }
1013
1014 write_unlock_bh(&l2cap_sk_list.lock);
1015
1016done:
1017 release_sock(sk);
1018 return err;
1019}
1020
1021static int l2cap_do_connect(struct sock *sk)
1022{
1023 bdaddr_t *src = &bt_sk(sk)->src;
1024 bdaddr_t *dst = &bt_sk(sk)->dst;
1025 struct l2cap_conn *conn;
1026 struct hci_conn *hcon;
1027 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001028 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001029 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001031 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
1032 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001034 hdev = hci_get_route(dst, src);
1035 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036 return -EHOSTUNREACH;
1037
1038 hci_dev_lock_bh(hdev);
1039
1040 err = -ENOMEM;
1041
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001042 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001043 switch (l2cap_pi(sk)->sec_level) {
1044 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001045 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001046 break;
1047 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001048 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001049 break;
1050 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001051 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001052 break;
1053 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001054 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001055 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001056 auth_type = HCI_AT_NO_BONDING_MITM;
1057 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001058 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +01001059
1060 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
1061 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001062 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001063 switch (l2cap_pi(sk)->sec_level) {
1064 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001065 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001066 break;
1067 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001068 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001069 break;
1070 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001071 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001072 break;
1073 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001074 }
1075
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001076 hcon = hci_connect(hdev, ACL_LINK, dst,
1077 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078 if (!hcon)
1079 goto done;
1080
1081 conn = l2cap_conn_add(hcon, 0);
1082 if (!conn) {
1083 hci_conn_put(hcon);
1084 goto done;
1085 }
1086
1087 err = 0;
1088
1089 /* Update source addr of the socket */
1090 bacpy(src, conn->src);
1091
1092 l2cap_chan_add(conn, sk, NULL);
1093
1094 sk->sk_state = BT_CONNECT;
1095 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
1096
1097 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001098 if (sk->sk_type != SOCK_SEQPACKET &&
1099 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 l2cap_sock_clear_timer(sk);
1101 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001102 } else
1103 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104 }
1105
1106done:
1107 hci_dev_unlock_bh(hdev);
1108 hci_dev_put(hdev);
1109 return err;
1110}
1111
1112static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1113{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001115 struct sockaddr_l2 la;
1116 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 BT_DBG("sk %p", sk);
1119
Changli Gao6503d962010-03-31 22:58:26 +00001120 if (!addr || alen < sizeof(addr->sa_family) ||
1121 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001122 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001124 memset(&la, 0, sizeof(la));
1125 len = min_t(unsigned int, sizeof(la), alen);
1126 memcpy(&la, addr, len);
1127
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001128 if (la.l2_cid)
1129 return -EINVAL;
1130
1131 lock_sock(sk);
1132
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001133 if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
1134 && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 err = -EINVAL;
1136 goto done;
1137 }
1138
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001139 switch (l2cap_pi(sk)->mode) {
1140 case L2CAP_MODE_BASIC:
1141 break;
1142 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001143 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001144 if (enable_ertm)
1145 break;
1146 /* fall through */
1147 default:
1148 err = -ENOTSUPP;
1149 goto done;
1150 }
1151
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001152 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153 case BT_CONNECT:
1154 case BT_CONNECT2:
1155 case BT_CONFIG:
1156 /* Already connecting */
1157 goto wait;
1158
1159 case BT_CONNECTED:
1160 /* Already connected */
1161 goto done;
1162
1163 case BT_OPEN:
1164 case BT_BOUND:
1165 /* Can connect */
1166 break;
1167
1168 default:
1169 err = -EBADFD;
1170 goto done;
1171 }
1172
1173 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001174 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1175 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001177 err = l2cap_do_connect(sk);
1178 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 goto done;
1180
1181wait:
1182 err = bt_sock_wait_state(sk, BT_CONNECTED,
1183 sock_sndtimeo(sk, flags & O_NONBLOCK));
1184done:
1185 release_sock(sk);
1186 return err;
1187}
1188
1189static int l2cap_sock_listen(struct socket *sock, int backlog)
1190{
1191 struct sock *sk = sock->sk;
1192 int err = 0;
1193
1194 BT_DBG("sk %p backlog %d", sk, backlog);
1195
1196 lock_sock(sk);
1197
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001198 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
1199 || sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200 err = -EBADFD;
1201 goto done;
1202 }
1203
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001204 switch (l2cap_pi(sk)->mode) {
1205 case L2CAP_MODE_BASIC:
1206 break;
1207 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001208 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001209 if (enable_ertm)
1210 break;
1211 /* fall through */
1212 default:
1213 err = -ENOTSUPP;
1214 goto done;
1215 }
1216
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217 if (!l2cap_pi(sk)->psm) {
1218 bdaddr_t *src = &bt_sk(sk)->src;
1219 u16 psm;
1220
1221 err = -EINVAL;
1222
1223 write_lock_bh(&l2cap_sk_list.lock);
1224
1225 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001226 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1227 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1228 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229 err = 0;
1230 break;
1231 }
1232
1233 write_unlock_bh(&l2cap_sk_list.lock);
1234
1235 if (err < 0)
1236 goto done;
1237 }
1238
1239 sk->sk_max_ack_backlog = backlog;
1240 sk->sk_ack_backlog = 0;
1241 sk->sk_state = BT_LISTEN;
1242
1243done:
1244 release_sock(sk);
1245 return err;
1246}
1247
1248static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1249{
1250 DECLARE_WAITQUEUE(wait, current);
1251 struct sock *sk = sock->sk, *nsk;
1252 long timeo;
1253 int err = 0;
1254
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001255 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256
1257 if (sk->sk_state != BT_LISTEN) {
1258 err = -EBADFD;
1259 goto done;
1260 }
1261
1262 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1263
1264 BT_DBG("sk %p timeo %ld", sk, timeo);
1265
1266 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001267 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1269 set_current_state(TASK_INTERRUPTIBLE);
1270 if (!timeo) {
1271 err = -EAGAIN;
1272 break;
1273 }
1274
1275 release_sock(sk);
1276 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001277 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001278
1279 if (sk->sk_state != BT_LISTEN) {
1280 err = -EBADFD;
1281 break;
1282 }
1283
1284 if (signal_pending(current)) {
1285 err = sock_intr_errno(timeo);
1286 break;
1287 }
1288 }
1289 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001290 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001291
1292 if (err)
1293 goto done;
1294
1295 newsock->state = SS_CONNECTED;
1296
1297 BT_DBG("new socket %p", nsk);
1298
1299done:
1300 release_sock(sk);
1301 return err;
1302}
1303
1304static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1305{
1306 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1307 struct sock *sk = sock->sk;
1308
1309 BT_DBG("sock %p, sk %p", sock, sk);
1310
1311 addr->sa_family = AF_BLUETOOTH;
1312 *len = sizeof(struct sockaddr_l2);
1313
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001314 if (peer) {
1315 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001317 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001318 } else {
1319 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001321 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001322 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324 return 0;
1325}
1326
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001327static int __l2cap_wait_ack(struct sock *sk)
1328{
1329 DECLARE_WAITQUEUE(wait, current);
1330 int err = 0;
1331 int timeo = HZ/5;
1332
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001333 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001334 while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
1335 set_current_state(TASK_INTERRUPTIBLE);
1336
1337 if (!timeo)
1338 timeo = HZ/5;
1339
1340 if (signal_pending(current)) {
1341 err = sock_intr_errno(timeo);
1342 break;
1343 }
1344
1345 release_sock(sk);
1346 timeo = schedule_timeout(timeo);
1347 lock_sock(sk);
1348
1349 err = sock_error(sk);
1350 if (err)
1351 break;
1352 }
1353 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001354 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001355 return err;
1356}
1357
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001358static void l2cap_monitor_timeout(unsigned long arg)
1359{
1360 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001361
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001362 BT_DBG("sk %p", sk);
1363
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001364 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001365 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001366 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001367 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001368 return;
1369 }
1370
1371 l2cap_pi(sk)->retry_count++;
1372 __mod_monitor_timer();
1373
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001374 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001375 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001376}
1377
1378static void l2cap_retrans_timeout(unsigned long arg)
1379{
1380 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001381
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001382 BT_DBG("sk %p", sk);
1383
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001384 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001385 l2cap_pi(sk)->retry_count = 1;
1386 __mod_monitor_timer();
1387
1388 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1389
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001390 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001391 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001392}
1393
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001394static void l2cap_drop_acked_frames(struct sock *sk)
1395{
1396 struct sk_buff *skb;
1397
Gustavo F. Padovan812e7372010-05-01 16:15:42 -03001398 while ((skb = skb_peek(TX_QUEUE(sk))) &&
1399 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001400 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1401 break;
1402
1403 skb = skb_dequeue(TX_QUEUE(sk));
1404 kfree_skb(skb);
1405
1406 l2cap_pi(sk)->unacked_frames--;
1407 }
1408
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001409 if (!l2cap_pi(sk)->unacked_frames)
1410 del_timer(&l2cap_pi(sk)->retrans_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001411}
1412
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001413static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001414{
1415 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001416
1417 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1418
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001419 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001420}
1421
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001422static int l2cap_streaming_send(struct sock *sk)
1423{
1424 struct sk_buff *skb, *tx_skb;
1425 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001426 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001427
1428 while ((skb = sk->sk_send_head)) {
1429 tx_skb = skb_clone(skb, GFP_ATOMIC);
1430
1431 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1432 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1433 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1434
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001435 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001436 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1437 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1438 }
1439
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001440 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001441
1442 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1443
1444 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1445 sk->sk_send_head = NULL;
1446 else
1447 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1448
1449 skb = skb_dequeue(TX_QUEUE(sk));
1450 kfree_skb(skb);
1451 }
1452 return 0;
1453}
1454
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001455static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001456{
1457 struct l2cap_pinfo *pi = l2cap_pi(sk);
1458 struct sk_buff *skb, *tx_skb;
1459 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001460
1461 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001462 if (!skb)
1463 return;
1464
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001465 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001466 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001467 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001468
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001469 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1470 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001471
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001472 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001473
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001474 if (pi->remote_max_tx &&
1475 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001476 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001477 return;
1478 }
1479
1480 tx_skb = skb_clone(skb, GFP_ATOMIC);
1481 bt_cb(skb)->retries++;
1482 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001483
1484 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1485 control |= L2CAP_CTRL_FINAL;
1486 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1487 }
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001488
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001489 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1490 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001491
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001492 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1493
1494 if (pi->fcs == L2CAP_FCS_CRC16) {
1495 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1496 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1497 }
1498
1499 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001500}
1501
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001502static int l2cap_ertm_send(struct sock *sk)
1503{
1504 struct sk_buff *skb, *tx_skb;
1505 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001506 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001507 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001508
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001509 if (sk->sk_state != BT_CONNECTED)
1510 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001511
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001512 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001513
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001514 if (pi->remote_max_tx &&
1515 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001516 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001517 break;
1518 }
1519
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001520 tx_skb = skb_clone(skb, GFP_ATOMIC);
1521
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001522 bt_cb(skb)->retries++;
1523
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001524 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001525 control &= L2CAP_CTRL_SAR;
1526
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001527 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1528 control |= L2CAP_CTRL_FINAL;
1529 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1530 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001531 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001532 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1533 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1534
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001535
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001536 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001537 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1538 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1539 }
1540
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001541 l2cap_do_send(sk, tx_skb);
1542
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001543 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001544
1545 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1546 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1547
1548 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001549 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001550
1551 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1552 sk->sk_send_head = NULL;
1553 else
1554 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001555
1556 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001557 }
1558
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001559 return nsent;
1560}
1561
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001562static int l2cap_retransmit_frames(struct sock *sk)
1563{
1564 struct l2cap_pinfo *pi = l2cap_pi(sk);
1565 int ret;
1566
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001567 if (!skb_queue_empty(TX_QUEUE(sk)))
1568 sk->sk_send_head = TX_QUEUE(sk)->next;
1569
1570 pi->next_tx_seq = pi->expected_ack_seq;
1571 ret = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001572 return ret;
1573}
1574
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001575static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001576{
1577 struct sock *sk = (struct sock *)pi;
1578 u16 control = 0;
1579
1580 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1581
1582 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1583 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001584 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001585 l2cap_send_sframe(pi, control);
1586 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001587 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001588
Gustavo F. Padovane0f66212010-06-21 18:50:49 -03001589 if (l2cap_ertm_send(sk) > 0)
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001590 return;
1591
1592 control |= L2CAP_SUPER_RCV_READY;
1593 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001594}
1595
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001596static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001597{
1598 struct srej_list *tail;
1599 u16 control;
1600
1601 control = L2CAP_SUPER_SELECT_REJECT;
1602 control |= L2CAP_CTRL_FINAL;
1603
1604 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1605 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1606
1607 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001608}
1609
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001610static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611{
1612 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001613 struct sk_buff **frag;
1614 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001616 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001617 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618
1619 sent += count;
1620 len -= count;
1621
1622 /* Continuation fragments (no L2CAP header) */
1623 frag = &skb_shinfo(skb)->frag_list;
1624 while (len) {
1625 count = min_t(unsigned int, conn->mtu, len);
1626
1627 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1628 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001629 return -EFAULT;
1630 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1631 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632
1633 sent += count;
1634 len -= count;
1635
1636 frag = &(*frag)->next;
1637 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638
1639 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001640}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001642static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1643{
1644 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1645 struct sk_buff *skb;
1646 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1647 struct l2cap_hdr *lh;
1648
1649 BT_DBG("sk %p len %d", sk, (int)len);
1650
1651 count = min_t(unsigned int, (conn->mtu - hlen), len);
1652 skb = bt_skb_send_alloc(sk, count + hlen,
1653 msg->msg_flags & MSG_DONTWAIT, &err);
1654 if (!skb)
1655 return ERR_PTR(-ENOMEM);
1656
1657 /* Create L2CAP header */
1658 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1659 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1660 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1661 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1662
1663 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1664 if (unlikely(err < 0)) {
1665 kfree_skb(skb);
1666 return ERR_PTR(err);
1667 }
1668 return skb;
1669}
1670
1671static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1672{
1673 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1674 struct sk_buff *skb;
1675 int err, count, hlen = L2CAP_HDR_SIZE;
1676 struct l2cap_hdr *lh;
1677
1678 BT_DBG("sk %p len %d", sk, (int)len);
1679
1680 count = min_t(unsigned int, (conn->mtu - hlen), len);
1681 skb = bt_skb_send_alloc(sk, count + hlen,
1682 msg->msg_flags & MSG_DONTWAIT, &err);
1683 if (!skb)
1684 return ERR_PTR(-ENOMEM);
1685
1686 /* Create L2CAP header */
1687 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1688 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1689 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1690
1691 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1692 if (unlikely(err < 0)) {
1693 kfree_skb(skb);
1694 return ERR_PTR(err);
1695 }
1696 return skb;
1697}
1698
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001699static struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001700{
1701 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1702 struct sk_buff *skb;
1703 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1704 struct l2cap_hdr *lh;
1705
1706 BT_DBG("sk %p len %d", sk, (int)len);
1707
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001708 if (!conn)
1709 return ERR_PTR(-ENOTCONN);
1710
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001711 if (sdulen)
1712 hlen += 2;
1713
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001714 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1715 hlen += 2;
1716
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001717 count = min_t(unsigned int, (conn->mtu - hlen), len);
1718 skb = bt_skb_send_alloc(sk, count + hlen,
1719 msg->msg_flags & MSG_DONTWAIT, &err);
1720 if (!skb)
1721 return ERR_PTR(-ENOMEM);
1722
1723 /* Create L2CAP header */
1724 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1725 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1726 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1727 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001728 if (sdulen)
1729 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001730
1731 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1732 if (unlikely(err < 0)) {
1733 kfree_skb(skb);
1734 return ERR_PTR(err);
1735 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001736
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001737 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1738 put_unaligned_le16(0, skb_put(skb, 2));
1739
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001740 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001741 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742}
1743
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001744static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1745{
1746 struct l2cap_pinfo *pi = l2cap_pi(sk);
1747 struct sk_buff *skb;
1748 struct sk_buff_head sar_queue;
1749 u16 control;
1750 size_t size = 0;
1751
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001752 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001753 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001754 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001755 if (IS_ERR(skb))
1756 return PTR_ERR(skb);
1757
1758 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001759 len -= pi->remote_mps;
1760 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001761
1762 while (len > 0) {
1763 size_t buflen;
1764
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001765 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001766 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001767 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001768 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001769 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001770 buflen = len;
1771 }
1772
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001773 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001774 if (IS_ERR(skb)) {
1775 skb_queue_purge(&sar_queue);
1776 return PTR_ERR(skb);
1777 }
1778
1779 __skb_queue_tail(&sar_queue, skb);
1780 len -= buflen;
1781 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001782 }
1783 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1784 if (sk->sk_send_head == NULL)
1785 sk->sk_send_head = sar_queue.next;
1786
1787 return size;
1788}
1789
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1791{
1792 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001793 struct l2cap_pinfo *pi = l2cap_pi(sk);
1794 struct sk_buff *skb;
1795 u16 control;
1796 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797
1798 BT_DBG("sock %p, sk %p", sock, sk);
1799
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001800 err = sock_error(sk);
1801 if (err)
1802 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803
1804 if (msg->msg_flags & MSG_OOB)
1805 return -EOPNOTSUPP;
1806
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 lock_sock(sk);
1808
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001809 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001811 goto done;
1812 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001814 /* Connectionless channel */
1815 if (sk->sk_type == SOCK_DGRAM) {
1816 skb = l2cap_create_connless_pdu(sk, msg, len);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001817 if (IS_ERR(skb)) {
Dan Carpenter477fffb2010-04-21 23:52:01 +00001818 err = PTR_ERR(skb);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001819 } else {
1820 l2cap_do_send(sk, skb);
1821 err = len;
1822 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001823 goto done;
1824 }
1825
1826 switch (pi->mode) {
1827 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001828 /* Check outgoing MTU */
1829 if (len > pi->omtu) {
1830 err = -EINVAL;
1831 goto done;
1832 }
1833
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001834 /* Create a basic PDU */
1835 skb = l2cap_create_basic_pdu(sk, msg, len);
1836 if (IS_ERR(skb)) {
1837 err = PTR_ERR(skb);
1838 goto done;
1839 }
1840
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001841 l2cap_do_send(sk, skb);
1842 err = len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001843 break;
1844
1845 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001846 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001847 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001848 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001849 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001850 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001851 if (IS_ERR(skb)) {
1852 err = PTR_ERR(skb);
1853 goto done;
1854 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001855 __skb_queue_tail(TX_QUEUE(sk), skb);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001856
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001857 if (sk->sk_send_head == NULL)
1858 sk->sk_send_head = skb;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001859
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001860 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001861 /* Segment SDU into multiples PDUs */
1862 err = l2cap_sar_segment_sdu(sk, msg, len);
1863 if (err < 0)
1864 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001865 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001866
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001867 if (pi->mode == L2CAP_MODE_STREAMING) {
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001868 err = l2cap_streaming_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001869 } else {
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001870 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY &&
1871 pi->conn_state && L2CAP_CONN_WAIT_F) {
1872 err = len;
1873 break;
1874 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001875 err = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001876 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001877
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001878 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001879 err = len;
1880 break;
1881
1882 default:
1883 BT_DBG("bad state %1.1x", pi->mode);
1884 err = -EINVAL;
1885 }
1886
1887done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888 release_sock(sk);
1889 return err;
1890}
1891
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001892static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1893{
1894 struct sock *sk = sock->sk;
1895
1896 lock_sock(sk);
1897
1898 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1899 struct l2cap_conn_rsp rsp;
1900
1901 sk->sk_state = BT_CONFIG;
1902
1903 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1904 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1905 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1906 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1907 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1908 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1909
1910 release_sock(sk);
1911 return 0;
1912 }
1913
1914 release_sock(sk);
1915
1916 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1917}
1918
David S. Millerb7058842009-09-30 16:12:20 -07001919static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920{
1921 struct sock *sk = sock->sk;
1922 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001923 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924 u32 opt;
1925
1926 BT_DBG("sk %p", sk);
1927
1928 lock_sock(sk);
1929
1930 switch (optname) {
1931 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001932 opts.imtu = l2cap_pi(sk)->imtu;
1933 opts.omtu = l2cap_pi(sk)->omtu;
1934 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001935 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001936 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001937 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001938 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001939
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940 len = min_t(unsigned int, sizeof(opts), optlen);
1941 if (copy_from_user((char *) &opts, optval, len)) {
1942 err = -EFAULT;
1943 break;
1944 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001945
Gustavo F. Padovan45d65c42010-06-07 19:21:30 -03001946 if (opts.txwin_size > L2CAP_DEFAULT_TX_WINDOW) {
1947 err = -EINVAL;
1948 break;
1949 }
1950
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001951 l2cap_pi(sk)->mode = opts.mode;
1952 switch (l2cap_pi(sk)->mode) {
1953 case L2CAP_MODE_BASIC:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001954 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE;
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001955 break;
1956 case L2CAP_MODE_ERTM:
1957 case L2CAP_MODE_STREAMING:
1958 if (enable_ertm)
1959 break;
1960 /* fall through */
1961 default:
1962 err = -EINVAL;
1963 break;
1964 }
1965
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001966 l2cap_pi(sk)->imtu = opts.imtu;
1967 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001968 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001969 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001970 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001971 break;
1972
1973 case L2CAP_LM:
1974 if (get_user(opt, (u32 __user *) optval)) {
1975 err = -EFAULT;
1976 break;
1977 }
1978
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001979 if (opt & L2CAP_LM_AUTH)
1980 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1981 if (opt & L2CAP_LM_ENCRYPT)
1982 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1983 if (opt & L2CAP_LM_SECURE)
1984 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1985
1986 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1987 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988 break;
1989
1990 default:
1991 err = -ENOPROTOOPT;
1992 break;
1993 }
1994
1995 release_sock(sk);
1996 return err;
1997}
1998
David S. Millerb7058842009-09-30 16:12:20 -07001999static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002000{
2001 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002002 struct bt_security sec;
2003 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002004 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002005
2006 BT_DBG("sk %p", sk);
2007
2008 if (level == SOL_L2CAP)
2009 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
2010
Marcel Holtmann0588d942009-01-16 10:06:13 +01002011 if (level != SOL_BLUETOOTH)
2012 return -ENOPROTOOPT;
2013
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002014 lock_sock(sk);
2015
2016 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002017 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002018 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2019 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002020 err = -EINVAL;
2021 break;
2022 }
2023
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002024 sec.level = BT_SECURITY_LOW;
2025
2026 len = min_t(unsigned int, sizeof(sec), optlen);
2027 if (copy_from_user((char *) &sec, optval, len)) {
2028 err = -EFAULT;
2029 break;
2030 }
2031
2032 if (sec.level < BT_SECURITY_LOW ||
2033 sec.level > BT_SECURITY_HIGH) {
2034 err = -EINVAL;
2035 break;
2036 }
2037
2038 l2cap_pi(sk)->sec_level = sec.level;
2039 break;
2040
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002041 case BT_DEFER_SETUP:
2042 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2043 err = -EINVAL;
2044 break;
2045 }
2046
2047 if (get_user(opt, (u32 __user *) optval)) {
2048 err = -EFAULT;
2049 break;
2050 }
2051
2052 bt_sk(sk)->defer_setup = opt;
2053 break;
2054
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002055 default:
2056 err = -ENOPROTOOPT;
2057 break;
2058 }
2059
2060 release_sock(sk);
2061 return err;
2062}
2063
2064static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065{
2066 struct sock *sk = sock->sk;
2067 struct l2cap_options opts;
2068 struct l2cap_conninfo cinfo;
2069 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002070 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002071
2072 BT_DBG("sk %p", sk);
2073
2074 if (get_user(len, optlen))
2075 return -EFAULT;
2076
2077 lock_sock(sk);
2078
2079 switch (optname) {
2080 case L2CAP_OPTIONS:
2081 opts.imtu = l2cap_pi(sk)->imtu;
2082 opts.omtu = l2cap_pi(sk)->omtu;
2083 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07002084 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002085 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002086 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002087 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002088
2089 len = min_t(unsigned int, len, sizeof(opts));
2090 if (copy_to_user(optval, (char *) &opts, len))
2091 err = -EFAULT;
2092
2093 break;
2094
2095 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002096 switch (l2cap_pi(sk)->sec_level) {
2097 case BT_SECURITY_LOW:
2098 opt = L2CAP_LM_AUTH;
2099 break;
2100 case BT_SECURITY_MEDIUM:
2101 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
2102 break;
2103 case BT_SECURITY_HIGH:
2104 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
2105 L2CAP_LM_SECURE;
2106 break;
2107 default:
2108 opt = 0;
2109 break;
2110 }
2111
2112 if (l2cap_pi(sk)->role_switch)
2113 opt |= L2CAP_LM_MASTER;
2114
2115 if (l2cap_pi(sk)->force_reliable)
2116 opt |= L2CAP_LM_RELIABLE;
2117
2118 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002119 err = -EFAULT;
2120 break;
2121
2122 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002123 if (sk->sk_state != BT_CONNECTED &&
2124 !(sk->sk_state == BT_CONNECT2 &&
2125 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002126 err = -ENOTCONN;
2127 break;
2128 }
2129
2130 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
2131 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
2132
2133 len = min_t(unsigned int, len, sizeof(cinfo));
2134 if (copy_to_user(optval, (char *) &cinfo, len))
2135 err = -EFAULT;
2136
2137 break;
2138
2139 default:
2140 err = -ENOPROTOOPT;
2141 break;
2142 }
2143
2144 release_sock(sk);
2145 return err;
2146}
2147
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002148static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2149{
2150 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002151 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002152 int len, err = 0;
2153
2154 BT_DBG("sk %p", sk);
2155
2156 if (level == SOL_L2CAP)
2157 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2158
Marcel Holtmann0588d942009-01-16 10:06:13 +01002159 if (level != SOL_BLUETOOTH)
2160 return -ENOPROTOOPT;
2161
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002162 if (get_user(len, optlen))
2163 return -EFAULT;
2164
2165 lock_sock(sk);
2166
2167 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002168 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002169 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2170 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002171 err = -EINVAL;
2172 break;
2173 }
2174
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002175 sec.level = l2cap_pi(sk)->sec_level;
2176
2177 len = min_t(unsigned int, len, sizeof(sec));
2178 if (copy_to_user(optval, (char *) &sec, len))
2179 err = -EFAULT;
2180
2181 break;
2182
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002183 case BT_DEFER_SETUP:
2184 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2185 err = -EINVAL;
2186 break;
2187 }
2188
2189 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2190 err = -EFAULT;
2191
2192 break;
2193
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002194 default:
2195 err = -ENOPROTOOPT;
2196 break;
2197 }
2198
2199 release_sock(sk);
2200 return err;
2201}
2202
Linus Torvalds1da177e2005-04-16 15:20:36 -07002203static int l2cap_sock_shutdown(struct socket *sock, int how)
2204{
2205 struct sock *sk = sock->sk;
2206 int err = 0;
2207
2208 BT_DBG("sock %p, sk %p", sock, sk);
2209
2210 if (!sk)
2211 return 0;
2212
2213 lock_sock(sk);
2214 if (!sk->sk_shutdown) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03002215 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2216 err = __l2cap_wait_ack(sk);
2217
Linus Torvalds1da177e2005-04-16 15:20:36 -07002218 sk->sk_shutdown = SHUTDOWN_MASK;
2219 l2cap_sock_clear_timer(sk);
2220 __l2cap_sock_close(sk, 0);
2221
2222 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002223 err = bt_sock_wait_state(sk, BT_CLOSED,
2224 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002225 }
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002226
2227 if (!err && sk->sk_err)
2228 err = -sk->sk_err;
2229
Linus Torvalds1da177e2005-04-16 15:20:36 -07002230 release_sock(sk);
2231 return err;
2232}
2233
2234static int l2cap_sock_release(struct socket *sock)
2235{
2236 struct sock *sk = sock->sk;
2237 int err;
2238
2239 BT_DBG("sock %p, sk %p", sock, sk);
2240
2241 if (!sk)
2242 return 0;
2243
2244 err = l2cap_sock_shutdown(sock, 2);
2245
2246 sock_orphan(sk);
2247 l2cap_sock_kill(sk);
2248 return err;
2249}
2250
Linus Torvalds1da177e2005-04-16 15:20:36 -07002251static void l2cap_chan_ready(struct sock *sk)
2252{
2253 struct sock *parent = bt_sk(sk)->parent;
2254
2255 BT_DBG("sk %p, parent %p", sk, parent);
2256
2257 l2cap_pi(sk)->conf_state = 0;
2258 l2cap_sock_clear_timer(sk);
2259
2260 if (!parent) {
2261 /* Outgoing channel.
2262 * Wake up socket sleeping on connect.
2263 */
2264 sk->sk_state = BT_CONNECTED;
2265 sk->sk_state_change(sk);
2266 } else {
2267 /* Incoming channel.
2268 * Wake up socket sleeping on accept.
2269 */
2270 parent->sk_data_ready(parent, 0);
2271 }
2272}
2273
2274/* Copy frame to all raw sockets on that connection */
2275static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2276{
2277 struct l2cap_chan_list *l = &conn->chan_list;
2278 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002279 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280
2281 BT_DBG("conn %p", conn);
2282
2283 read_lock(&l->lock);
2284 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2285 if (sk->sk_type != SOCK_RAW)
2286 continue;
2287
2288 /* Don't send frame to the socket it came from */
2289 if (skb->sk == sk)
2290 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002291 nskb = skb_clone(skb, GFP_ATOMIC);
2292 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293 continue;
2294
2295 if (sock_queue_rcv_skb(sk, nskb))
2296 kfree_skb(nskb);
2297 }
2298 read_unlock(&l->lock);
2299}
2300
2301/* ---- L2CAP signalling commands ---- */
2302static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2303 u8 code, u8 ident, u16 dlen, void *data)
2304{
2305 struct sk_buff *skb, **frag;
2306 struct l2cap_cmd_hdr *cmd;
2307 struct l2cap_hdr *lh;
2308 int len, count;
2309
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002310 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2311 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002312
2313 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2314 count = min_t(unsigned int, conn->mtu, len);
2315
2316 skb = bt_skb_alloc(count, GFP_ATOMIC);
2317 if (!skb)
2318 return NULL;
2319
2320 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002321 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002322 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323
2324 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2325 cmd->code = code;
2326 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002327 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328
2329 if (dlen) {
2330 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2331 memcpy(skb_put(skb, count), data, count);
2332 data += count;
2333 }
2334
2335 len -= skb->len;
2336
2337 /* Continuation fragments (no L2CAP header) */
2338 frag = &skb_shinfo(skb)->frag_list;
2339 while (len) {
2340 count = min_t(unsigned int, conn->mtu, len);
2341
2342 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2343 if (!*frag)
2344 goto fail;
2345
2346 memcpy(skb_put(*frag, count), data, count);
2347
2348 len -= count;
2349 data += count;
2350
2351 frag = &(*frag)->next;
2352 }
2353
2354 return skb;
2355
2356fail:
2357 kfree_skb(skb);
2358 return NULL;
2359}
2360
2361static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2362{
2363 struct l2cap_conf_opt *opt = *ptr;
2364 int len;
2365
2366 len = L2CAP_CONF_OPT_SIZE + opt->len;
2367 *ptr += len;
2368
2369 *type = opt->type;
2370 *olen = opt->len;
2371
2372 switch (opt->len) {
2373 case 1:
2374 *val = *((u8 *) opt->val);
2375 break;
2376
2377 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002378 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002379 break;
2380
2381 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002382 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002383 break;
2384
2385 default:
2386 *val = (unsigned long) opt->val;
2387 break;
2388 }
2389
2390 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2391 return len;
2392}
2393
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2395{
2396 struct l2cap_conf_opt *opt = *ptr;
2397
2398 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2399
2400 opt->type = type;
2401 opt->len = len;
2402
2403 switch (len) {
2404 case 1:
2405 *((u8 *) opt->val) = val;
2406 break;
2407
2408 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002409 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002410 break;
2411
2412 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002413 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002414 break;
2415
2416 default:
2417 memcpy(opt->val, (void *) val, len);
2418 break;
2419 }
2420
2421 *ptr += L2CAP_CONF_OPT_SIZE + len;
2422}
2423
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002424static void l2cap_ack_timeout(unsigned long arg)
2425{
2426 struct sock *sk = (void *) arg;
2427
2428 bh_lock_sock(sk);
2429 l2cap_send_ack(l2cap_pi(sk));
2430 bh_unlock_sock(sk);
2431}
2432
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002433static inline void l2cap_ertm_init(struct sock *sk)
2434{
2435 l2cap_pi(sk)->expected_ack_seq = 0;
2436 l2cap_pi(sk)->unacked_frames = 0;
2437 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002438 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002439 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002440
2441 setup_timer(&l2cap_pi(sk)->retrans_timer,
2442 l2cap_retrans_timeout, (unsigned long) sk);
2443 setup_timer(&l2cap_pi(sk)->monitor_timer,
2444 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002445 setup_timer(&l2cap_pi(sk)->ack_timer,
2446 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002447
2448 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002449 __skb_queue_head_init(BUSY_QUEUE(sk));
2450
2451 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03002452
2453 sk->sk_backlog_rcv = l2cap_ertm_data_rcv;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002454}
2455
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002456static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2457{
2458 switch (mode) {
2459 case L2CAP_MODE_STREAMING:
2460 case L2CAP_MODE_ERTM:
2461 if (l2cap_mode_supported(mode, remote_feat_mask))
2462 return mode;
2463 /* fall through */
2464 default:
2465 return L2CAP_MODE_BASIC;
2466 }
2467}
2468
Linus Torvalds1da177e2005-04-16 15:20:36 -07002469static int l2cap_build_conf_req(struct sock *sk, void *data)
2470{
2471 struct l2cap_pinfo *pi = l2cap_pi(sk);
2472 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002473 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002474 void *ptr = req->data;
2475
2476 BT_DBG("sk %p", sk);
2477
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002478 if (pi->num_conf_req || pi->num_conf_rsp)
2479 goto done;
2480
2481 switch (pi->mode) {
2482 case L2CAP_MODE_STREAMING:
2483 case L2CAP_MODE_ERTM:
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002484 if (pi->conf_state & L2CAP_CONF_STATE2_DEVICE)
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002485 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002486
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002487 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002488 default:
2489 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2490 break;
2491 }
2492
2493done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002494 switch (pi->mode) {
2495 case L2CAP_MODE_BASIC:
2496 if (pi->imtu != L2CAP_DEFAULT_MTU)
2497 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002498
2499 rfc.mode = L2CAP_MODE_BASIC;
2500 rfc.txwin_size = 0;
2501 rfc.max_transmit = 0;
2502 rfc.retrans_timeout = 0;
2503 rfc.monitor_timeout = 0;
2504 rfc.max_pdu_size = 0;
2505
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002506 break;
2507
2508 case L2CAP_MODE_ERTM:
2509 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002510 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002511 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002512 rfc.retrans_timeout = 0;
2513 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002514 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002515 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002516 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002517
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002518 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2519 break;
2520
2521 if (pi->fcs == L2CAP_FCS_NONE ||
2522 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2523 pi->fcs = L2CAP_FCS_NONE;
2524 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2525 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002526 break;
2527
2528 case L2CAP_MODE_STREAMING:
2529 rfc.mode = L2CAP_MODE_STREAMING;
2530 rfc.txwin_size = 0;
2531 rfc.max_transmit = 0;
2532 rfc.retrans_timeout = 0;
2533 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002534 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002535 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002536 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002537
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002538 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2539 break;
2540
2541 if (pi->fcs == L2CAP_FCS_NONE ||
2542 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2543 pi->fcs = L2CAP_FCS_NONE;
2544 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2545 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002546 break;
2547 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002549 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2550 (unsigned long) &rfc);
2551
Linus Torvalds1da177e2005-04-16 15:20:36 -07002552 /* FIXME: Need actual value of the flush timeout */
2553 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2554 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2555
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002556 req->dcid = cpu_to_le16(pi->dcid);
2557 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002558
2559 return ptr - data;
2560}
2561
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002562static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002563{
2564 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002565 struct l2cap_conf_rsp *rsp = data;
2566 void *ptr = rsp->data;
2567 void *req = pi->conf_req;
2568 int len = pi->conf_len;
2569 int type, hint, olen;
2570 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002571 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002572 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002573 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002574
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002575 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002576
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002577 while (len >= L2CAP_CONF_OPT_SIZE) {
2578 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002579
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002580 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002581 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002582
2583 switch (type) {
2584 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002585 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002586 break;
2587
2588 case L2CAP_CONF_FLUSH_TO:
2589 pi->flush_to = val;
2590 break;
2591
2592 case L2CAP_CONF_QOS:
2593 break;
2594
Marcel Holtmann6464f352007-10-20 13:39:51 +02002595 case L2CAP_CONF_RFC:
2596 if (olen == sizeof(rfc))
2597 memcpy(&rfc, (void *) val, olen);
2598 break;
2599
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002600 case L2CAP_CONF_FCS:
2601 if (val == L2CAP_FCS_NONE)
2602 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2603
2604 break;
2605
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002606 default:
2607 if (hint)
2608 break;
2609
2610 result = L2CAP_CONF_UNKNOWN;
2611 *((u8 *) ptr++) = type;
2612 break;
2613 }
2614 }
2615
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002616 if (pi->num_conf_rsp || pi->num_conf_req)
2617 goto done;
2618
2619 switch (pi->mode) {
2620 case L2CAP_MODE_STREAMING:
2621 case L2CAP_MODE_ERTM:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002622 if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) {
2623 pi->mode = l2cap_select_mode(rfc.mode,
2624 pi->conn->feat_mask);
2625 break;
2626 }
2627
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03002628 if (pi->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002629 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03002630
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002631 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002632 }
2633
2634done:
2635 if (pi->mode != rfc.mode) {
2636 result = L2CAP_CONF_UNACCEPT;
2637 rfc.mode = pi->mode;
2638
2639 if (pi->num_conf_rsp == 1)
2640 return -ECONNREFUSED;
2641
2642 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2643 sizeof(rfc), (unsigned long) &rfc);
2644 }
2645
2646
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002647 if (result == L2CAP_CONF_SUCCESS) {
2648 /* Configure output options and let the other side know
2649 * which ones we don't like. */
2650
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002651 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2652 result = L2CAP_CONF_UNACCEPT;
2653 else {
2654 pi->omtu = mtu;
2655 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2656 }
2657 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002658
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002659 switch (rfc.mode) {
2660 case L2CAP_MODE_BASIC:
2661 pi->fcs = L2CAP_FCS_NONE;
2662 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2663 break;
2664
2665 case L2CAP_MODE_ERTM:
2666 pi->remote_tx_win = rfc.txwin_size;
2667 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002668 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2669 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2670
2671 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002672
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002673 rfc.retrans_timeout =
2674 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2675 rfc.monitor_timeout =
2676 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002677
2678 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002679
2680 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2681 sizeof(rfc), (unsigned long) &rfc);
2682
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002683 break;
2684
2685 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002686 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2687 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2688
2689 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002690
2691 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002692
2693 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2694 sizeof(rfc), (unsigned long) &rfc);
2695
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002696 break;
2697
2698 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002699 result = L2CAP_CONF_UNACCEPT;
2700
2701 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002702 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002703 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002704
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002705 if (result == L2CAP_CONF_SUCCESS)
2706 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2707 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002708 rsp->scid = cpu_to_le16(pi->dcid);
2709 rsp->result = cpu_to_le16(result);
2710 rsp->flags = cpu_to_le16(0x0000);
2711
2712 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002713}
2714
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002715static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2716{
2717 struct l2cap_pinfo *pi = l2cap_pi(sk);
2718 struct l2cap_conf_req *req = data;
2719 void *ptr = req->data;
2720 int type, olen;
2721 unsigned long val;
2722 struct l2cap_conf_rfc rfc;
2723
2724 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2725
2726 while (len >= L2CAP_CONF_OPT_SIZE) {
2727 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2728
2729 switch (type) {
2730 case L2CAP_CONF_MTU:
2731 if (val < L2CAP_DEFAULT_MIN_MTU) {
2732 *result = L2CAP_CONF_UNACCEPT;
2733 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2734 } else
2735 pi->omtu = val;
2736 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2737 break;
2738
2739 case L2CAP_CONF_FLUSH_TO:
2740 pi->flush_to = val;
2741 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2742 2, pi->flush_to);
2743 break;
2744
2745 case L2CAP_CONF_RFC:
2746 if (olen == sizeof(rfc))
2747 memcpy(&rfc, (void *)val, olen);
2748
2749 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2750 rfc.mode != pi->mode)
2751 return -ECONNREFUSED;
2752
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002753 pi->fcs = 0;
2754
2755 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2756 sizeof(rfc), (unsigned long) &rfc);
2757 break;
2758 }
2759 }
2760
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03002761 if (pi->mode == L2CAP_MODE_BASIC && pi->mode != rfc.mode)
2762 return -ECONNREFUSED;
2763
2764 pi->mode = rfc.mode;
2765
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002766 if (*result == L2CAP_CONF_SUCCESS) {
2767 switch (rfc.mode) {
2768 case L2CAP_MODE_ERTM:
2769 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002770 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2771 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002772 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002773 break;
2774 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002775 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002776 }
2777 }
2778
2779 req->dcid = cpu_to_le16(pi->dcid);
2780 req->flags = cpu_to_le16(0x0000);
2781
2782 return ptr - data;
2783}
2784
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002785static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002786{
2787 struct l2cap_conf_rsp *rsp = data;
2788 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002789
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002790 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002791
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002792 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002793 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002794 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002795
2796 return ptr - data;
2797}
2798
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002799static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2800{
2801 struct l2cap_pinfo *pi = l2cap_pi(sk);
2802 int type, olen;
2803 unsigned long val;
2804 struct l2cap_conf_rfc rfc;
2805
2806 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2807
2808 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2809 return;
2810
2811 while (len >= L2CAP_CONF_OPT_SIZE) {
2812 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2813
2814 switch (type) {
2815 case L2CAP_CONF_RFC:
2816 if (olen == sizeof(rfc))
2817 memcpy(&rfc, (void *)val, olen);
2818 goto done;
2819 }
2820 }
2821
2822done:
2823 switch (rfc.mode) {
2824 case L2CAP_MODE_ERTM:
2825 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002826 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2827 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002828 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2829 break;
2830 case L2CAP_MODE_STREAMING:
2831 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2832 }
2833}
2834
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002835static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2836{
2837 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2838
2839 if (rej->reason != 0x0000)
2840 return 0;
2841
2842 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2843 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002844 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002845
2846 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002847 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002848
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002849 l2cap_conn_start(conn);
2850 }
2851
2852 return 0;
2853}
2854
Linus Torvalds1da177e2005-04-16 15:20:36 -07002855static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2856{
2857 struct l2cap_chan_list *list = &conn->chan_list;
2858 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2859 struct l2cap_conn_rsp rsp;
2860 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002861 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002862
2863 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002864 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865
2866 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2867
2868 /* Check if we have socket listening on psm */
2869 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2870 if (!parent) {
2871 result = L2CAP_CR_BAD_PSM;
2872 goto sendresp;
2873 }
2874
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002875 /* Check if the ACL is secure enough (if not SDP) */
2876 if (psm != cpu_to_le16(0x0001) &&
2877 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002878 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002879 result = L2CAP_CR_SEC_BLOCK;
2880 goto response;
2881 }
2882
Linus Torvalds1da177e2005-04-16 15:20:36 -07002883 result = L2CAP_CR_NO_MEM;
2884
2885 /* Check for backlog size */
2886 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002887 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002888 goto response;
2889 }
2890
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002891 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892 if (!sk)
2893 goto response;
2894
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002895 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002896
2897 /* Check if we already have channel with that dcid */
2898 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002899 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002900 sock_set_flag(sk, SOCK_ZAPPED);
2901 l2cap_sock_kill(sk);
2902 goto response;
2903 }
2904
2905 hci_conn_hold(conn->hcon);
2906
2907 l2cap_sock_init(sk, parent);
2908 bacpy(&bt_sk(sk)->src, conn->src);
2909 bacpy(&bt_sk(sk)->dst, conn->dst);
2910 l2cap_pi(sk)->psm = psm;
2911 l2cap_pi(sk)->dcid = scid;
2912
2913 __l2cap_chan_add(conn, sk, parent);
2914 dcid = l2cap_pi(sk)->scid;
2915
2916 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2917
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918 l2cap_pi(sk)->ident = cmd->ident;
2919
Marcel Holtmann984947d2009-02-06 23:35:19 +01002920 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002921 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002922 if (bt_sk(sk)->defer_setup) {
2923 sk->sk_state = BT_CONNECT2;
2924 result = L2CAP_CR_PEND;
2925 status = L2CAP_CS_AUTHOR_PEND;
2926 parent->sk_data_ready(parent, 0);
2927 } else {
2928 sk->sk_state = BT_CONFIG;
2929 result = L2CAP_CR_SUCCESS;
2930 status = L2CAP_CS_NO_INFO;
2931 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002932 } else {
2933 sk->sk_state = BT_CONNECT2;
2934 result = L2CAP_CR_PEND;
2935 status = L2CAP_CS_AUTHEN_PEND;
2936 }
2937 } else {
2938 sk->sk_state = BT_CONNECT2;
2939 result = L2CAP_CR_PEND;
2940 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002941 }
2942
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002943 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002944
2945response:
2946 bh_unlock_sock(parent);
2947
2948sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002949 rsp.scid = cpu_to_le16(scid);
2950 rsp.dcid = cpu_to_le16(dcid);
2951 rsp.result = cpu_to_le16(result);
2952 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002954
2955 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2956 struct l2cap_info_req info;
2957 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2958
2959 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2960 conn->info_ident = l2cap_get_ident(conn);
2961
2962 mod_timer(&conn->info_timer, jiffies +
2963 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2964
2965 l2cap_send_cmd(conn, conn->info_ident,
2966 L2CAP_INFO_REQ, sizeof(info), &info);
2967 }
2968
Linus Torvalds1da177e2005-04-16 15:20:36 -07002969 return 0;
2970}
2971
2972static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2973{
2974 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2975 u16 scid, dcid, result, status;
2976 struct sock *sk;
2977 u8 req[128];
2978
2979 scid = __le16_to_cpu(rsp->scid);
2980 dcid = __le16_to_cpu(rsp->dcid);
2981 result = __le16_to_cpu(rsp->result);
2982 status = __le16_to_cpu(rsp->status);
2983
2984 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2985
2986 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002987 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2988 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002989 return 0;
2990 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002991 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2992 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002993 return 0;
2994 }
2995
2996 switch (result) {
2997 case L2CAP_CR_SUCCESS:
2998 sk->sk_state = BT_CONFIG;
2999 l2cap_pi(sk)->ident = 0;
3000 l2cap_pi(sk)->dcid = dcid;
3001 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003002 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
3003
Linus Torvalds1da177e2005-04-16 15:20:36 -07003004 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3005 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003006 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003007 break;
3008
3009 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003010 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003011 break;
3012
3013 default:
3014 l2cap_chan_del(sk, ECONNREFUSED);
3015 break;
3016 }
3017
3018 bh_unlock_sock(sk);
3019 return 0;
3020}
3021
Al Viro88219a02007-07-29 00:17:25 -07003022static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003023{
3024 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3025 u16 dcid, flags;
3026 u8 rsp[64];
3027 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003028 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003029
3030 dcid = __le16_to_cpu(req->dcid);
3031 flags = __le16_to_cpu(req->flags);
3032
3033 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3034
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003035 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3036 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003037 return -ENOENT;
3038
Gustavo F. Padovan8cb8e6f2010-06-14 02:26:15 -03003039 if (sk->sk_state != BT_CONFIG) {
3040 struct l2cap_cmd_rej rej;
3041
3042 rej.reason = cpu_to_le16(0x0002);
3043 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
3044 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003045 goto unlock;
Gustavo F. Padovan8cb8e6f2010-06-14 02:26:15 -03003046 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003047
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003048 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003049 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003050 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
3051 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
3052 l2cap_build_conf_rsp(sk, rsp,
3053 L2CAP_CONF_REJECT, flags), rsp);
3054 goto unlock;
3055 }
3056
3057 /* Store config. */
3058 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
3059 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003060
3061 if (flags & 0x0001) {
3062 /* Incomplete config. Send empty response. */
3063 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003064 l2cap_build_conf_rsp(sk, rsp,
3065 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003066 goto unlock;
3067 }
3068
3069 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003070 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003071 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003072 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003073 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003074 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003075
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003076 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003077 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003078
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003079 /* Reset config buffer. */
3080 l2cap_pi(sk)->conf_len = 0;
3081
Marcel Holtmann876d9482007-10-20 13:35:42 +02003082 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
3083 goto unlock;
3084
Linus Torvalds1da177e2005-04-16 15:20:36 -07003085 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003086 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3087 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003088 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3089
Linus Torvalds1da177e2005-04-16 15:20:36 -07003090 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003091
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003092 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003093 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003094 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003095 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3096 l2cap_ertm_init(sk);
3097
Linus Torvalds1da177e2005-04-16 15:20:36 -07003098 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02003099 goto unlock;
3100 }
3101
3102 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003103 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003104 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003105 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003106 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003107 }
3108
3109unlock:
3110 bh_unlock_sock(sk);
3111 return 0;
3112}
3113
3114static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3115{
3116 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3117 u16 scid, flags, result;
3118 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003119 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003120
3121 scid = __le16_to_cpu(rsp->scid);
3122 flags = __le16_to_cpu(rsp->flags);
3123 result = __le16_to_cpu(rsp->result);
3124
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003125 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
3126 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003127
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003128 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3129 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003130 return 0;
3131
3132 switch (result) {
3133 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003134 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003135 break;
3136
3137 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003138 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003139 char req[64];
3140
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003141 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003142 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003143 goto done;
3144 }
3145
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003146 /* throw out any old stored conf requests */
3147 result = L2CAP_CONF_SUCCESS;
3148 len = l2cap_parse_conf_rsp(sk, rsp->data,
3149 len, req, &result);
3150 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003151 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003152 goto done;
3153 }
3154
3155 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3156 L2CAP_CONF_REQ, len, req);
3157 l2cap_pi(sk)->num_conf_req++;
3158 if (result != L2CAP_CONF_SUCCESS)
3159 goto done;
3160 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003161 }
3162
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003163 default:
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003164 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003165 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003166 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003167 goto done;
3168 }
3169
3170 if (flags & 0x01)
3171 goto done;
3172
Linus Torvalds1da177e2005-04-16 15:20:36 -07003173 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3174
3175 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003176 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3177 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003178 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3179
Linus Torvalds1da177e2005-04-16 15:20:36 -07003180 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003181 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003182 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003183 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003184 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3185 l2cap_ertm_init(sk);
3186
Linus Torvalds1da177e2005-04-16 15:20:36 -07003187 l2cap_chan_ready(sk);
3188 }
3189
3190done:
3191 bh_unlock_sock(sk);
3192 return 0;
3193}
3194
3195static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3196{
3197 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3198 struct l2cap_disconn_rsp rsp;
3199 u16 dcid, scid;
3200 struct sock *sk;
3201
3202 scid = __le16_to_cpu(req->scid);
3203 dcid = __le16_to_cpu(req->dcid);
3204
3205 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3206
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003207 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3208 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003209 return 0;
3210
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003211 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3212 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003213 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3214
3215 sk->sk_shutdown = SHUTDOWN_MASK;
3216
3217 l2cap_chan_del(sk, ECONNRESET);
3218 bh_unlock_sock(sk);
3219
3220 l2cap_sock_kill(sk);
3221 return 0;
3222}
3223
3224static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3225{
3226 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3227 u16 dcid, scid;
3228 struct sock *sk;
3229
3230 scid = __le16_to_cpu(rsp->scid);
3231 dcid = __le16_to_cpu(rsp->dcid);
3232
3233 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3234
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003235 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3236 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003237 return 0;
3238
3239 l2cap_chan_del(sk, 0);
3240 bh_unlock_sock(sk);
3241
3242 l2cap_sock_kill(sk);
3243 return 0;
3244}
3245
3246static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3247{
3248 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003249 u16 type;
3250
3251 type = __le16_to_cpu(req->type);
3252
3253 BT_DBG("type 0x%4.4x", type);
3254
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003255 if (type == L2CAP_IT_FEAT_MASK) {
3256 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003257 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003258 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3259 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3260 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003261 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003262 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3263 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003264 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003265 l2cap_send_cmd(conn, cmd->ident,
3266 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003267 } else if (type == L2CAP_IT_FIXED_CHAN) {
3268 u8 buf[12];
3269 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3270 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3271 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3272 memcpy(buf + 4, l2cap_fixed_chan, 8);
3273 l2cap_send_cmd(conn, cmd->ident,
3274 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003275 } else {
3276 struct l2cap_info_rsp rsp;
3277 rsp.type = cpu_to_le16(type);
3278 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3279 l2cap_send_cmd(conn, cmd->ident,
3280 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3281 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003282
3283 return 0;
3284}
3285
3286static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3287{
3288 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3289 u16 type, result;
3290
3291 type = __le16_to_cpu(rsp->type);
3292 result = __le16_to_cpu(rsp->result);
3293
3294 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3295
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003296 del_timer(&conn->info_timer);
3297
Marcel Holtmann984947d2009-02-06 23:35:19 +01003298 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003299 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003300
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003301 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003302 struct l2cap_info_req req;
3303 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3304
3305 conn->info_ident = l2cap_get_ident(conn);
3306
3307 l2cap_send_cmd(conn, conn->info_ident,
3308 L2CAP_INFO_REQ, sizeof(req), &req);
3309 } else {
3310 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3311 conn->info_ident = 0;
3312
3313 l2cap_conn_start(conn);
3314 }
3315 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003316 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003317 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003318
3319 l2cap_conn_start(conn);
3320 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003321
Linus Torvalds1da177e2005-04-16 15:20:36 -07003322 return 0;
3323}
3324
3325static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3326{
3327 u8 *data = skb->data;
3328 int len = skb->len;
3329 struct l2cap_cmd_hdr cmd;
3330 int err = 0;
3331
3332 l2cap_raw_recv(conn, skb);
3333
3334 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003335 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003336 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3337 data += L2CAP_CMD_HDR_SIZE;
3338 len -= L2CAP_CMD_HDR_SIZE;
3339
Al Viro88219a02007-07-29 00:17:25 -07003340 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003341
Al Viro88219a02007-07-29 00:17:25 -07003342 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len, cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003343
Al Viro88219a02007-07-29 00:17:25 -07003344 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003345 BT_DBG("corrupted command");
3346 break;
3347 }
3348
3349 switch (cmd.code) {
3350 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003351 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003352 break;
3353
3354 case L2CAP_CONN_REQ:
3355 err = l2cap_connect_req(conn, &cmd, data);
3356 break;
3357
3358 case L2CAP_CONN_RSP:
3359 err = l2cap_connect_rsp(conn, &cmd, data);
3360 break;
3361
3362 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003363 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003364 break;
3365
3366 case L2CAP_CONF_RSP:
3367 err = l2cap_config_rsp(conn, &cmd, data);
3368 break;
3369
3370 case L2CAP_DISCONN_REQ:
3371 err = l2cap_disconnect_req(conn, &cmd, data);
3372 break;
3373
3374 case L2CAP_DISCONN_RSP:
3375 err = l2cap_disconnect_rsp(conn, &cmd, data);
3376 break;
3377
3378 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003379 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003380 break;
3381
3382 case L2CAP_ECHO_RSP:
3383 break;
3384
3385 case L2CAP_INFO_REQ:
3386 err = l2cap_information_req(conn, &cmd, data);
3387 break;
3388
3389 case L2CAP_INFO_RSP:
3390 err = l2cap_information_rsp(conn, &cmd, data);
3391 break;
3392
3393 default:
3394 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3395 err = -EINVAL;
3396 break;
3397 }
3398
3399 if (err) {
3400 struct l2cap_cmd_rej rej;
3401 BT_DBG("error %d", err);
3402
3403 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003404 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003405 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3406 }
3407
Al Viro88219a02007-07-29 00:17:25 -07003408 data += cmd_len;
3409 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003410 }
3411
3412 kfree_skb(skb);
3413}
3414
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003415static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3416{
3417 u16 our_fcs, rcv_fcs;
3418 int hdr_size = L2CAP_HDR_SIZE + 2;
3419
3420 if (pi->fcs == L2CAP_FCS_CRC16) {
3421 skb_trim(skb, skb->len - 2);
3422 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3423 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3424
3425 if (our_fcs != rcv_fcs)
3426 return -EINVAL;
3427 }
3428 return 0;
3429}
3430
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003431static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3432{
3433 struct l2cap_pinfo *pi = l2cap_pi(sk);
3434 u16 control = 0;
3435
3436 pi->frames_sent = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003437
3438 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3439
3440 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan64988862010-05-10 14:54:14 -03003441 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003442 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003443 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003444 }
3445
Gustavo F. Padovan4ea727e2010-06-03 16:34:20 -03003446 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
3447 l2cap_retransmit_frames(sk);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003448
3449 l2cap_ertm_send(sk);
3450
3451 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3452 pi->frames_sent == 0) {
3453 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003454 l2cap_send_sframe(pi, control);
3455 }
3456}
3457
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003458static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003459{
3460 struct sk_buff *next_skb;
João Paulo Rechi Vitabfbacc112010-05-31 18:35:44 -03003461 struct l2cap_pinfo *pi = l2cap_pi(sk);
3462 int tx_seq_offset, next_tx_seq_offset;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003463
3464 bt_cb(skb)->tx_seq = tx_seq;
3465 bt_cb(skb)->sar = sar;
3466
3467 next_skb = skb_peek(SREJ_QUEUE(sk));
3468 if (!next_skb) {
3469 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003470 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003471 }
3472
João Paulo Rechi Vitabfbacc112010-05-31 18:35:44 -03003473 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3474 if (tx_seq_offset < 0)
3475 tx_seq_offset += 64;
3476
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003477 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003478 if (bt_cb(next_skb)->tx_seq == tx_seq)
3479 return -EINVAL;
3480
João Paulo Rechi Vitabfbacc112010-05-31 18:35:44 -03003481 next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
3482 pi->buffer_seq) % 64;
3483 if (next_tx_seq_offset < 0)
3484 next_tx_seq_offset += 64;
3485
3486 if (next_tx_seq_offset > tx_seq_offset) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003487 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003488 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003489 }
3490
3491 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3492 break;
3493
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003494 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003495
3496 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003497
3498 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003499}
3500
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003501static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3502{
3503 struct l2cap_pinfo *pi = l2cap_pi(sk);
3504 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003505 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003506
3507 switch (control & L2CAP_CTRL_SAR) {
3508 case L2CAP_SDU_UNSEGMENTED:
3509 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3510 goto drop;
3511
3512 err = sock_queue_rcv_skb(sk, skb);
3513 if (!err)
3514 return err;
3515
3516 break;
3517
3518 case L2CAP_SDU_START:
3519 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3520 goto drop;
3521
3522 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003523
3524 if (pi->sdu_len > pi->imtu)
3525 goto disconnect;
3526
3527 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003528 if (!pi->sdu)
3529 return -ENOMEM;
3530
3531 /* pull sdu_len bytes only after alloc, because of Local Busy
3532 * condition we have to be sure that this will be executed
3533 * only once, i.e., when alloc does not fail */
3534 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003535
3536 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3537
3538 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3539 pi->partial_sdu_len = skb->len;
3540 break;
3541
3542 case L2CAP_SDU_CONTINUE:
3543 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3544 goto disconnect;
3545
3546 if (!pi->sdu)
3547 goto disconnect;
3548
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003549 pi->partial_sdu_len += skb->len;
3550 if (pi->partial_sdu_len > pi->sdu_len)
3551 goto drop;
3552
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003553 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3554
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003555 break;
3556
3557 case L2CAP_SDU_END:
3558 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3559 goto disconnect;
3560
3561 if (!pi->sdu)
3562 goto disconnect;
3563
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003564 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003565 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003566
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003567 if (pi->partial_sdu_len > pi->imtu)
3568 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003569
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003570 if (pi->partial_sdu_len != pi->sdu_len)
3571 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003572
3573 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003574 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003575
3576 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003577 if (!_skb) {
3578 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3579 return -ENOMEM;
3580 }
3581
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003582 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003583 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003584 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003585 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3586 return err;
3587 }
3588
3589 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
3590 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003591
3592 kfree_skb(pi->sdu);
3593 break;
3594 }
3595
3596 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003597 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003598
3599drop:
3600 kfree_skb(pi->sdu);
3601 pi->sdu = NULL;
3602
3603disconnect:
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003604 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003605 kfree_skb(skb);
3606 return 0;
3607}
3608
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003609static void l2cap_busy_work(struct work_struct *work)
3610{
3611 DECLARE_WAITQUEUE(wait, current);
3612 struct l2cap_pinfo *pi =
3613 container_of(work, struct l2cap_pinfo, busy_work);
3614 struct sock *sk = (struct sock *)pi;
3615 int n_tries = 0, timeo = HZ/5, err;
3616 struct sk_buff *skb;
3617 u16 control;
3618
3619 lock_sock(sk);
3620
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003621 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003622 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
3623 set_current_state(TASK_INTERRUPTIBLE);
3624
3625 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
3626 err = -EBUSY;
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003627 l2cap_send_disconn_req(pi->conn, sk, EBUSY);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003628 goto done;
3629 }
3630
3631 if (!timeo)
3632 timeo = HZ/5;
3633
3634 if (signal_pending(current)) {
3635 err = sock_intr_errno(timeo);
3636 goto done;
3637 }
3638
3639 release_sock(sk);
3640 timeo = schedule_timeout(timeo);
3641 lock_sock(sk);
3642
3643 err = sock_error(sk);
3644 if (err)
3645 goto done;
3646
3647 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
3648 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3649 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3650 if (err < 0) {
3651 skb_queue_head(BUSY_QUEUE(sk), skb);
3652 break;
3653 }
3654
3655 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3656 }
3657
3658 if (!skb)
3659 break;
3660 }
3661
3662 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
3663 goto done;
3664
3665 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3666 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
3667 l2cap_send_sframe(pi, control);
3668 l2cap_pi(sk)->retry_count = 1;
3669
3670 del_timer(&pi->retrans_timer);
3671 __mod_monitor_timer();
3672
3673 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
3674
3675done:
3676 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
3677 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
3678
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003679 BT_DBG("sk %p, Exit local busy", sk);
3680
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003681 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003682 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003683
3684 release_sock(sk);
3685}
3686
3687static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
3688{
3689 struct l2cap_pinfo *pi = l2cap_pi(sk);
3690 int sctrl, err;
3691
3692 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3693 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3694 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3695 return -EBUSY;
3696 }
3697
3698 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3699 if (err >= 0) {
3700 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3701 return err;
3702 }
3703
3704 /* Busy Condition */
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003705 BT_DBG("sk %p, Enter local busy", sk);
3706
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003707 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
3708 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3709 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3710
3711 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3712 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3713 l2cap_send_sframe(pi, sctrl);
3714
3715 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3716
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003717 del_timer(&pi->ack_timer);
3718
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003719 queue_work(_busy_wq, &pi->busy_work);
3720
3721 return err;
3722}
3723
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003724static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003725{
3726 struct l2cap_pinfo *pi = l2cap_pi(sk);
3727 struct sk_buff *_skb;
3728 int err = -EINVAL;
3729
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003730 /*
3731 * TODO: We have to notify the userland if some data is lost with the
3732 * Streaming Mode.
3733 */
3734
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003735 switch (control & L2CAP_CTRL_SAR) {
3736 case L2CAP_SDU_UNSEGMENTED:
3737 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3738 kfree_skb(pi->sdu);
3739 break;
3740 }
3741
3742 err = sock_queue_rcv_skb(sk, skb);
3743 if (!err)
3744 return 0;
3745
3746 break;
3747
3748 case L2CAP_SDU_START:
3749 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3750 kfree_skb(pi->sdu);
3751 break;
3752 }
3753
3754 pi->sdu_len = get_unaligned_le16(skb->data);
3755 skb_pull(skb, 2);
3756
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003757 if (pi->sdu_len > pi->imtu) {
3758 err = -EMSGSIZE;
3759 break;
3760 }
3761
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003762 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3763 if (!pi->sdu) {
3764 err = -ENOMEM;
3765 break;
3766 }
3767
3768 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3769
3770 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3771 pi->partial_sdu_len = skb->len;
3772 err = 0;
3773 break;
3774
3775 case L2CAP_SDU_CONTINUE:
3776 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3777 break;
3778
3779 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3780
3781 pi->partial_sdu_len += skb->len;
3782 if (pi->partial_sdu_len > pi->sdu_len)
3783 kfree_skb(pi->sdu);
3784 else
3785 err = 0;
3786
3787 break;
3788
3789 case L2CAP_SDU_END:
3790 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3791 break;
3792
3793 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3794
3795 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3796 pi->partial_sdu_len += skb->len;
3797
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003798 if (pi->partial_sdu_len > pi->imtu)
3799 goto drop;
3800
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003801 if (pi->partial_sdu_len == pi->sdu_len) {
3802 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3803 err = sock_queue_rcv_skb(sk, _skb);
3804 if (err < 0)
3805 kfree_skb(_skb);
3806 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003807 err = 0;
3808
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003809drop:
3810 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003811 break;
3812 }
3813
3814 kfree_skb(skb);
3815 return err;
3816}
3817
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003818static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3819{
3820 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003821 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003822
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003823 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003824 if (bt_cb(skb)->tx_seq != tx_seq)
3825 break;
3826
3827 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003828 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003829 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003830 l2cap_pi(sk)->buffer_seq_srej =
3831 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003832 tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003833 }
3834}
3835
3836static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3837{
3838 struct l2cap_pinfo *pi = l2cap_pi(sk);
3839 struct srej_list *l, *tmp;
3840 u16 control;
3841
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003842 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003843 if (l->tx_seq == tx_seq) {
3844 list_del(&l->list);
3845 kfree(l);
3846 return;
3847 }
3848 control = L2CAP_SUPER_SELECT_REJECT;
3849 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3850 l2cap_send_sframe(pi, control);
3851 list_del(&l->list);
3852 list_add_tail(&l->list, SREJ_LIST(sk));
3853 }
3854}
3855
3856static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3857{
3858 struct l2cap_pinfo *pi = l2cap_pi(sk);
3859 struct srej_list *new;
3860 u16 control;
3861
3862 while (tx_seq != pi->expected_tx_seq) {
3863 control = L2CAP_SUPER_SELECT_REJECT;
3864 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3865 l2cap_send_sframe(pi, control);
3866
3867 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003868 new->tx_seq = pi->expected_tx_seq;
3869 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003870 list_add_tail(&new->list, SREJ_LIST(sk));
3871 }
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003872 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003873}
3874
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003875static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3876{
3877 struct l2cap_pinfo *pi = l2cap_pi(sk);
3878 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003879 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003880 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03003881 int tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003882 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003883 int err = 0;
3884
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003885 BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq,
3886 rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003887
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003888 if (L2CAP_CTRL_FINAL & rx_control &&
3889 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003890 del_timer(&pi->monitor_timer);
3891 if (pi->unacked_frames > 0)
3892 __mod_retrans_timer();
3893 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3894 }
3895
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003896 pi->expected_ack_seq = req_seq;
3897 l2cap_drop_acked_frames(sk);
3898
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003899 if (tx_seq == pi->expected_tx_seq)
3900 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003901
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003902 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3903 if (tx_seq_offset < 0)
3904 tx_seq_offset += 64;
3905
3906 /* invalid tx_seq */
3907 if (tx_seq_offset >= pi->tx_win) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003908 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003909 goto drop;
3910 }
3911
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003912 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3913 goto drop;
3914
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003915 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3916 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003917
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003918 first = list_first_entry(SREJ_LIST(sk),
3919 struct srej_list, list);
3920 if (tx_seq == first->tx_seq) {
3921 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3922 l2cap_check_srej_gap(sk, tx_seq);
3923
3924 list_del(&first->list);
3925 kfree(first);
3926
3927 if (list_empty(SREJ_LIST(sk))) {
3928 pi->buffer_seq = pi->buffer_seq_srej;
3929 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666c2010-05-01 16:15:40 -03003930 l2cap_send_ack(pi);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003931 BT_DBG("sk %p, Exit SREJ_SENT", sk);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003932 }
3933 } else {
3934 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003935
3936 /* duplicated tx_seq */
3937 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3938 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003939
3940 list_for_each_entry(l, SREJ_LIST(sk), list) {
3941 if (l->tx_seq == tx_seq) {
3942 l2cap_resend_srejframe(sk, tx_seq);
3943 return 0;
3944 }
3945 }
3946 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003947 }
3948 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003949 expected_tx_seq_offset =
3950 (pi->expected_tx_seq - pi->buffer_seq) % 64;
3951 if (expected_tx_seq_offset < 0)
3952 expected_tx_seq_offset += 64;
3953
3954 /* duplicated tx_seq */
3955 if (tx_seq_offset < expected_tx_seq_offset)
3956 goto drop;
3957
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003958 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003959
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003960 BT_DBG("sk %p, Enter SREJ", sk);
3961
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003962 INIT_LIST_HEAD(SREJ_LIST(sk));
3963 pi->buffer_seq_srej = pi->buffer_seq;
3964
3965 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003966 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003967 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3968
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003969 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3970
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003971 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003972
3973 del_timer(&pi->ack_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003974 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003975 return 0;
3976
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003977expected:
3978 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3979
3980 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003981 bt_cb(skb)->tx_seq = tx_seq;
3982 bt_cb(skb)->sar = sar;
3983 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003984 return 0;
3985 }
3986
Gustavo F. Padovan2ece3682010-06-16 17:21:44 -03003987 err = l2cap_push_rx_skb(sk, skb, rx_control);
3988 if (err < 0)
3989 return 0;
3990
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003991 if (rx_control & L2CAP_CTRL_FINAL) {
3992 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3993 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003994 else
3995 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003996 }
3997
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003998 __mod_ack_timer();
3999
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03004000 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
4001 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03004002 l2cap_send_ack(pi);
4003
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004004 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004005
4006drop:
4007 kfree_skb(skb);
4008 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004009}
4010
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004011static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004012{
4013 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03004014
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004015 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control),
4016 rx_control);
4017
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03004018 pi->expected_ack_seq = __get_reqseq(rx_control);
4019 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004020
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004021 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004022 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03004023 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
4024 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
4025 (pi->unacked_frames > 0))
4026 __mod_retrans_timer();
4027
4028 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4029 l2cap_send_srejtail(sk);
4030 } else {
4031 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03004032 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004033
4034 } else if (rx_control & L2CAP_CTRL_FINAL) {
4035 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004036
4037 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4038 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004039 else
4040 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004041
4042 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004043 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
4044 (pi->unacked_frames > 0))
4045 __mod_retrans_timer();
4046
4047 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004048 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004049 l2cap_send_ack(pi);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004050 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004051 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004052 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004053 }
4054}
4055
4056static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
4057{
4058 struct l2cap_pinfo *pi = l2cap_pi(sk);
4059 u8 tx_seq = __get_reqseq(rx_control);
4060
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004061 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4062
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004063 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4064
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03004065 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004066 l2cap_drop_acked_frames(sk);
4067
4068 if (rx_control & L2CAP_CTRL_FINAL) {
4069 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4070 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004071 else
4072 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004073 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004074 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004075
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03004076 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004077 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004078 }
4079}
4080static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
4081{
4082 struct l2cap_pinfo *pi = l2cap_pi(sk);
4083 u8 tx_seq = __get_reqseq(rx_control);
4084
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004085 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4086
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004087 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4088
4089 if (rx_control & L2CAP_CTRL_POLL) {
4090 pi->expected_ack_seq = tx_seq;
4091 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004092
4093 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004094 l2cap_retransmit_one_frame(sk, tx_seq);
4095
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004096 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004097
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004098 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4099 pi->srej_save_reqseq = tx_seq;
4100 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4101 }
4102 } else if (rx_control & L2CAP_CTRL_FINAL) {
4103 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
4104 pi->srej_save_reqseq == tx_seq)
4105 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
4106 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004107 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004108 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004109 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004110 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4111 pi->srej_save_reqseq = tx_seq;
4112 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4113 }
4114 }
4115}
4116
4117static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
4118{
4119 struct l2cap_pinfo *pi = l2cap_pi(sk);
4120 u8 tx_seq = __get_reqseq(rx_control);
4121
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004122 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4123
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004124 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
4125 pi->expected_ack_seq = tx_seq;
4126 l2cap_drop_acked_frames(sk);
4127
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004128 if (rx_control & L2CAP_CTRL_POLL)
4129 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
4130
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004131 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
4132 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03004133 if (rx_control & L2CAP_CTRL_POLL)
4134 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004135 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004136 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004137
4138 if (rx_control & L2CAP_CTRL_POLL)
4139 l2cap_send_srejtail(sk);
4140 else
4141 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004142}
4143
4144static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
4145{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004146 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
4147
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03004148 if (L2CAP_CTRL_FINAL & rx_control &&
4149 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004150 del_timer(&l2cap_pi(sk)->monitor_timer);
4151 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004152 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004153 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004154 }
4155
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004156 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
4157 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004158 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004159 break;
4160
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004161 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004162 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004163 break;
4164
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004165 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004166 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004167 break;
4168
4169 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004170 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004171 break;
4172 }
4173
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03004174 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004175 return 0;
4176}
4177
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004178static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
4179{
4180 struct l2cap_pinfo *pi = l2cap_pi(sk);
4181 u16 control;
4182 u8 req_seq;
4183 int len, next_tx_seq_offset, req_seq_offset;
4184
4185 control = get_unaligned_le16(skb->data);
4186 skb_pull(skb, 2);
4187 len = skb->len;
4188
4189 /*
4190 * We can just drop the corrupted I-frame here.
4191 * Receiver will miss it and start proper recovery
4192 * procedures and ask retransmission.
4193 */
4194 if (l2cap_check_fcs(pi, skb))
4195 goto drop;
4196
4197 if (__is_sar_start(control) && __is_iframe(control))
4198 len -= 2;
4199
4200 if (pi->fcs == L2CAP_FCS_CRC16)
4201 len -= 2;
4202
4203 if (len > pi->mps) {
4204 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4205 goto drop;
4206 }
4207
4208 req_seq = __get_reqseq(control);
4209 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
4210 if (req_seq_offset < 0)
4211 req_seq_offset += 64;
4212
4213 next_tx_seq_offset =
4214 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
4215 if (next_tx_seq_offset < 0)
4216 next_tx_seq_offset += 64;
4217
4218 /* check for invalid req-seq */
4219 if (req_seq_offset > next_tx_seq_offset) {
4220 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4221 goto drop;
4222 }
4223
4224 if (__is_iframe(control)) {
4225 if (len < 0) {
4226 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4227 goto drop;
4228 }
4229
4230 l2cap_data_channel_iframe(sk, control, skb);
4231 } else {
4232 if (len != 0) {
4233 BT_ERR("%d", len);
4234 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4235 goto drop;
4236 }
4237
4238 l2cap_data_channel_sframe(sk, control, skb);
4239 }
4240
4241 return 0;
4242
4243drop:
4244 kfree_skb(skb);
4245 return 0;
4246}
4247
Linus Torvalds1da177e2005-04-16 15:20:36 -07004248static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
4249{
4250 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004251 struct l2cap_pinfo *pi;
Nathan Holstein51893f82010-06-09 15:46:25 -04004252 u16 control;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004253 u8 tx_seq;
4254 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004255
4256 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4257 if (!sk) {
4258 BT_DBG("unknown cid 0x%4.4x", cid);
4259 goto drop;
4260 }
4261
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004262 pi = l2cap_pi(sk);
4263
Linus Torvalds1da177e2005-04-16 15:20:36 -07004264 BT_DBG("sk %p, len %d", sk, skb->len);
4265
4266 if (sk->sk_state != BT_CONNECTED)
4267 goto drop;
4268
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004269 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004270 case L2CAP_MODE_BASIC:
4271 /* If socket recv buffers overflows we drop data here
4272 * which is *bad* because L2CAP has to be reliable.
4273 * But we don't have any other choice. L2CAP doesn't
4274 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004275
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004276 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004277 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004278
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004279 if (!sock_queue_rcv_skb(sk, skb))
4280 goto done;
4281 break;
4282
4283 case L2CAP_MODE_ERTM:
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004284 if (!sock_owned_by_user(sk)) {
4285 l2cap_ertm_data_rcv(sk, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004286 } else {
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004287 if (sk_add_backlog(sk, skb))
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004288 goto drop;
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004289 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004290
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004291 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004292
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004293 case L2CAP_MODE_STREAMING:
4294 control = get_unaligned_le16(skb->data);
4295 skb_pull(skb, 2);
4296 len = skb->len;
4297
Gustavo F. Padovan26000082010-05-11 22:02:00 -03004298 if (l2cap_check_fcs(pi, skb))
4299 goto drop;
4300
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004301 if (__is_sar_start(control))
4302 len -= 2;
4303
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004304 if (pi->fcs == L2CAP_FCS_CRC16)
4305 len -= 2;
4306
Nathan Holstein51893f82010-06-09 15:46:25 -04004307 if (len > pi->mps || len < 0 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004308 goto drop;
4309
4310 tx_seq = __get_txseq(control);
4311
4312 if (pi->expected_tx_seq == tx_seq)
4313 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4314 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03004315 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004316
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004317 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004318
4319 goto done;
4320
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004321 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03004322 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004323 break;
4324 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004325
4326drop:
4327 kfree_skb(skb);
4328
4329done:
Marcel Holtmann01394182006-07-03 10:02:46 +02004330 if (sk)
4331 bh_unlock_sock(sk);
4332
Linus Torvalds1da177e2005-04-16 15:20:36 -07004333 return 0;
4334}
4335
Al Viro8e036fc2007-07-29 00:16:36 -07004336static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004337{
4338 struct sock *sk;
4339
4340 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
4341 if (!sk)
4342 goto drop;
4343
4344 BT_DBG("sk %p, len %d", sk, skb->len);
4345
4346 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
4347 goto drop;
4348
4349 if (l2cap_pi(sk)->imtu < skb->len)
4350 goto drop;
4351
4352 if (!sock_queue_rcv_skb(sk, skb))
4353 goto done;
4354
4355drop:
4356 kfree_skb(skb);
4357
4358done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004359 if (sk)
4360 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004361 return 0;
4362}
4363
4364static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
4365{
4366 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07004367 u16 cid, len;
4368 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004369
4370 skb_pull(skb, L2CAP_HDR_SIZE);
4371 cid = __le16_to_cpu(lh->cid);
4372 len = __le16_to_cpu(lh->len);
4373
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004374 if (len != skb->len) {
4375 kfree_skb(skb);
4376 return;
4377 }
4378
Linus Torvalds1da177e2005-04-16 15:20:36 -07004379 BT_DBG("len %d, cid 0x%4.4x", len, cid);
4380
4381 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004382 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004383 l2cap_sig_channel(conn, skb);
4384 break;
4385
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004386 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004387 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004388 skb_pull(skb, 2);
4389 l2cap_conless_channel(conn, psm, skb);
4390 break;
4391
4392 default:
4393 l2cap_data_channel(conn, cid, skb);
4394 break;
4395 }
4396}
4397
4398/* ---- L2CAP interface with lower layer (HCI) ---- */
4399
4400static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
4401{
4402 int exact = 0, lm1 = 0, lm2 = 0;
4403 register struct sock *sk;
4404 struct hlist_node *node;
4405
4406 if (type != ACL_LINK)
4407 return 0;
4408
4409 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
4410
4411 /* Find listening sockets and check their link_mode */
4412 read_lock(&l2cap_sk_list.lock);
4413 sk_for_each(sk, node, &l2cap_sk_list.head) {
4414 if (sk->sk_state != BT_LISTEN)
4415 continue;
4416
4417 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004418 lm1 |= HCI_LM_ACCEPT;
4419 if (l2cap_pi(sk)->role_switch)
4420 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004421 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004422 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
4423 lm2 |= HCI_LM_ACCEPT;
4424 if (l2cap_pi(sk)->role_switch)
4425 lm2 |= HCI_LM_MASTER;
4426 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004427 }
4428 read_unlock(&l2cap_sk_list.lock);
4429
4430 return exact ? lm1 : lm2;
4431}
4432
4433static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
4434{
Marcel Holtmann01394182006-07-03 10:02:46 +02004435 struct l2cap_conn *conn;
4436
Linus Torvalds1da177e2005-04-16 15:20:36 -07004437 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
4438
4439 if (hcon->type != ACL_LINK)
4440 return 0;
4441
4442 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004443 conn = l2cap_conn_add(hcon, status);
4444 if (conn)
4445 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004446 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004447 l2cap_conn_del(hcon, bt_err(status));
4448
4449 return 0;
4450}
4451
Marcel Holtmann2950f212009-02-12 14:02:50 +01004452static int l2cap_disconn_ind(struct hci_conn *hcon)
4453{
4454 struct l2cap_conn *conn = hcon->l2cap_data;
4455
4456 BT_DBG("hcon %p", hcon);
4457
4458 if (hcon->type != ACL_LINK || !conn)
4459 return 0x13;
4460
4461 return conn->disc_reason;
4462}
4463
4464static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004465{
4466 BT_DBG("hcon %p reason %d", hcon, reason);
4467
4468 if (hcon->type != ACL_LINK)
4469 return 0;
4470
4471 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004472
Linus Torvalds1da177e2005-04-16 15:20:36 -07004473 return 0;
4474}
4475
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004476static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4477{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004478 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004479 return;
4480
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004481 if (encrypt == 0x00) {
4482 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4483 l2cap_sock_clear_timer(sk);
4484 l2cap_sock_set_timer(sk, HZ * 5);
4485 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4486 __l2cap_sock_close(sk, ECONNREFUSED);
4487 } else {
4488 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4489 l2cap_sock_clear_timer(sk);
4490 }
4491}
4492
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004493static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004494{
4495 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004496 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004497 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004498
Marcel Holtmann01394182006-07-03 10:02:46 +02004499 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004500 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004501
Linus Torvalds1da177e2005-04-16 15:20:36 -07004502 l = &conn->chan_list;
4503
4504 BT_DBG("conn %p", conn);
4505
4506 read_lock(&l->lock);
4507
4508 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4509 bh_lock_sock(sk);
4510
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004511 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4512 bh_unlock_sock(sk);
4513 continue;
4514 }
4515
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004516 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004517 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004518 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004519 bh_unlock_sock(sk);
4520 continue;
4521 }
4522
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004523 if (sk->sk_state == BT_CONNECT) {
4524 if (!status) {
4525 struct l2cap_conn_req req;
4526 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4527 req.psm = l2cap_pi(sk)->psm;
4528
4529 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03004530 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004531
4532 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4533 L2CAP_CONN_REQ, sizeof(req), &req);
4534 } else {
4535 l2cap_sock_clear_timer(sk);
4536 l2cap_sock_set_timer(sk, HZ / 10);
4537 }
4538 } else if (sk->sk_state == BT_CONNECT2) {
4539 struct l2cap_conn_rsp rsp;
4540 __u16 result;
4541
4542 if (!status) {
4543 sk->sk_state = BT_CONFIG;
4544 result = L2CAP_CR_SUCCESS;
4545 } else {
4546 sk->sk_state = BT_DISCONN;
4547 l2cap_sock_set_timer(sk, HZ / 10);
4548 result = L2CAP_CR_SEC_BLOCK;
4549 }
4550
4551 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4552 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4553 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004554 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004555 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4556 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004557 }
4558
Linus Torvalds1da177e2005-04-16 15:20:36 -07004559 bh_unlock_sock(sk);
4560 }
4561
4562 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004563
Linus Torvalds1da177e2005-04-16 15:20:36 -07004564 return 0;
4565}
4566
4567static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4568{
4569 struct l2cap_conn *conn = hcon->l2cap_data;
4570
4571 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4572 goto drop;
4573
4574 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4575
4576 if (flags & ACL_START) {
4577 struct l2cap_hdr *hdr;
4578 int len;
4579
4580 if (conn->rx_len) {
4581 BT_ERR("Unexpected start frame (len %d)", skb->len);
4582 kfree_skb(conn->rx_skb);
4583 conn->rx_skb = NULL;
4584 conn->rx_len = 0;
4585 l2cap_conn_unreliable(conn, ECOMM);
4586 }
4587
4588 if (skb->len < 2) {
4589 BT_ERR("Frame is too short (len %d)", skb->len);
4590 l2cap_conn_unreliable(conn, ECOMM);
4591 goto drop;
4592 }
4593
4594 hdr = (struct l2cap_hdr *) skb->data;
4595 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4596
4597 if (len == skb->len) {
4598 /* Complete frame received */
4599 l2cap_recv_frame(conn, skb);
4600 return 0;
4601 }
4602
4603 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4604
4605 if (skb->len > len) {
4606 BT_ERR("Frame is too long (len %d, expected len %d)",
4607 skb->len, len);
4608 l2cap_conn_unreliable(conn, ECOMM);
4609 goto drop;
4610 }
4611
4612 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004613 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4614 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004615 goto drop;
4616
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004617 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004618 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004619 conn->rx_len = len - skb->len;
4620 } else {
4621 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4622
4623 if (!conn->rx_len) {
4624 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4625 l2cap_conn_unreliable(conn, ECOMM);
4626 goto drop;
4627 }
4628
4629 if (skb->len > conn->rx_len) {
4630 BT_ERR("Fragment is too long (len %d, expected %d)",
4631 skb->len, conn->rx_len);
4632 kfree_skb(conn->rx_skb);
4633 conn->rx_skb = NULL;
4634 conn->rx_len = 0;
4635 l2cap_conn_unreliable(conn, ECOMM);
4636 goto drop;
4637 }
4638
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004639 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004640 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004641 conn->rx_len -= skb->len;
4642
4643 if (!conn->rx_len) {
4644 /* Complete frame received */
4645 l2cap_recv_frame(conn, conn->rx_skb);
4646 conn->rx_skb = NULL;
4647 }
4648 }
4649
4650drop:
4651 kfree_skb(skb);
4652 return 0;
4653}
4654
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004655static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004656{
4657 struct sock *sk;
4658 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004659
4660 read_lock_bh(&l2cap_sk_list.lock);
4661
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004662 sk_for_each(sk, node, &l2cap_sk_list.head) {
4663 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004664
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004665 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4666 batostr(&bt_sk(sk)->src),
4667 batostr(&bt_sk(sk)->dst),
4668 sk->sk_state, __le16_to_cpu(pi->psm),
4669 pi->scid, pi->dcid,
4670 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004671 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004672
Linus Torvalds1da177e2005-04-16 15:20:36 -07004673 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004674
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004675 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004676}
4677
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004678static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4679{
4680 return single_open(file, l2cap_debugfs_show, inode->i_private);
4681}
4682
4683static const struct file_operations l2cap_debugfs_fops = {
4684 .open = l2cap_debugfs_open,
4685 .read = seq_read,
4686 .llseek = seq_lseek,
4687 .release = single_release,
4688};
4689
4690static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004691
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004692static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004693 .family = PF_BLUETOOTH,
4694 .owner = THIS_MODULE,
4695 .release = l2cap_sock_release,
4696 .bind = l2cap_sock_bind,
4697 .connect = l2cap_sock_connect,
4698 .listen = l2cap_sock_listen,
4699 .accept = l2cap_sock_accept,
4700 .getname = l2cap_sock_getname,
4701 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004702 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004703 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004704 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004705 .mmap = sock_no_mmap,
4706 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004707 .shutdown = l2cap_sock_shutdown,
4708 .setsockopt = l2cap_sock_setsockopt,
4709 .getsockopt = l2cap_sock_getsockopt
4710};
4711
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004712static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004713 .family = PF_BLUETOOTH,
4714 .owner = THIS_MODULE,
4715 .create = l2cap_sock_create,
4716};
4717
4718static struct hci_proto l2cap_hci_proto = {
4719 .name = "L2CAP",
4720 .id = HCI_PROTO_L2CAP,
4721 .connect_ind = l2cap_connect_ind,
4722 .connect_cfm = l2cap_connect_cfm,
4723 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004724 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004725 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004726 .recv_acldata = l2cap_recv_acldata
4727};
4728
4729static int __init l2cap_init(void)
4730{
4731 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004732
Linus Torvalds1da177e2005-04-16 15:20:36 -07004733 err = proto_register(&l2cap_proto, 0);
4734 if (err < 0)
4735 return err;
4736
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004737 _busy_wq = create_singlethread_workqueue("l2cap");
4738 if (!_busy_wq)
4739 goto error;
4740
Linus Torvalds1da177e2005-04-16 15:20:36 -07004741 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4742 if (err < 0) {
4743 BT_ERR("L2CAP socket registration failed");
4744 goto error;
4745 }
4746
4747 err = hci_register_proto(&l2cap_hci_proto);
4748 if (err < 0) {
4749 BT_ERR("L2CAP protocol registration failed");
4750 bt_sock_unregister(BTPROTO_L2CAP);
4751 goto error;
4752 }
4753
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004754 if (bt_debugfs) {
4755 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4756 bt_debugfs, NULL, &l2cap_debugfs_fops);
4757 if (!l2cap_debugfs)
4758 BT_ERR("Failed to create L2CAP debug file");
4759 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004760
4761 BT_INFO("L2CAP ver %s", VERSION);
4762 BT_INFO("L2CAP socket layer initialized");
4763
4764 return 0;
4765
4766error:
4767 proto_unregister(&l2cap_proto);
4768 return err;
4769}
4770
4771static void __exit l2cap_exit(void)
4772{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004773 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004774
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004775 flush_workqueue(_busy_wq);
4776 destroy_workqueue(_busy_wq);
4777
Linus Torvalds1da177e2005-04-16 15:20:36 -07004778 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4779 BT_ERR("L2CAP socket unregistration failed");
4780
4781 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4782 BT_ERR("L2CAP protocol unregistration failed");
4783
4784 proto_unregister(&l2cap_proto);
4785}
4786
4787void l2cap_load(void)
4788{
4789 /* Dummy function to trigger automatic L2CAP module loading by
4790 * other modules that use L2CAP sockets but don't use any other
4791 * symbols from it. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004792}
4793EXPORT_SYMBOL(l2cap_load);
4794
4795module_init(l2cap_init);
4796module_exit(l2cap_exit);
4797
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004798module_param(enable_ertm, bool, 0644);
4799MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4800
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004801MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004802MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4803MODULE_VERSION(VERSION);
4804MODULE_LICENSE("GPL");
4805MODULE_ALIAS("bt-proto-0");