blob: 2277ed504283720a2310a122b774a46abd4289a0 [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
Gustavo F. Padovance5706b2010-07-13 11:57:11 -03004 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
Gustavo F. Padovan5d8868f2010-07-16 16:18:39 -03005 Copyright (C) 2010 Google Inc.
Gustavo F. Padovan590051d2011-12-18 13:39:33 -02006 Copyright (C) 2011 ProFUSION Embedded Systems
Mat Martineau422e9252012-04-27 16:50:55 -07007 Copyright (c) 2012 Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07008
9 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License version 2 as
13 published by the Free Software Foundation;
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
18 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090019 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090024 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
25 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 SOFTWARE IS DISCLAIMED.
27*/
28
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020029/* Bluetooth L2CAP core. */
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/module.h>
32
Marcel Holtmannaef7d972010-03-21 05:27:45 +010033#include <linux/debugfs.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030034#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#include <net/bluetooth/bluetooth.h>
37#include <net/bluetooth/hci_core.h>
38#include <net/bluetooth/l2cap.h>
Anderson Brigliab501d6a2011-06-07 18:46:31 -030039#include <net/bluetooth/smp.h>
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +030040#include <net/bluetooth/a2mp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041
Mat Martineaud1de6d42012-05-17 20:53:55 -070042bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020043
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070044static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Mat Martineau50a147c2011-11-02 16:18:34 -070045static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
Johannes Bergb5ad8b72011-06-01 08:54:45 +020047static LIST_HEAD(chan_list);
48static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
Linus Torvalds1da177e2005-04-16 15:20:36 -070050static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010051 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030052static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010053 void *data);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -030054static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030055static void l2cap_send_disconn_req(struct l2cap_conn *conn,
Gustavo Padovanc5daa682012-05-16 12:17:10 -030056 struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Gustavo Padovand6603662012-05-21 13:58:22 -030058static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010059 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070060
Marcel Holtmann01394182006-07-03 10:02:46 +020061/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030062
Gustavo Padovan2d792812012-10-06 10:07:01 +010063static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
64 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020065{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020066 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030067
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020068 list_for_each_entry(c, &conn->chan_l, list) {
69 if (c->dcid == cid)
70 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020071 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020072 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020073}
74
Gustavo Padovan2d792812012-10-06 10:07:01 +010075static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
76 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020077{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020078 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030079
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020080 list_for_each_entry(c, &conn->chan_l, list) {
81 if (c->scid == cid)
82 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020083 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020084 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020085}
86
87/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -070088 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +010089static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
90 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020091{
Gustavo F. Padovan48454072011-03-25 00:22:30 -030092 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030093
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020094 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030095 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -070096 if (c)
97 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020098 mutex_unlock(&conn->chan_lock);
99
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300100 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200101}
102
Mat Martineaub1a130b2012-10-23 15:24:09 -0700103/* Find channel with given DCID.
104 * Returns locked channel.
105 */
106static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
107 u16 cid)
108{
109 struct l2cap_chan *c;
110
111 mutex_lock(&conn->chan_lock);
112 c = __l2cap_get_chan_by_dcid(conn, cid);
113 if (c)
114 l2cap_chan_lock(c);
115 mutex_unlock(&conn->chan_lock);
116
117 return c;
118}
119
Gustavo Padovan2d792812012-10-06 10:07:01 +0100120static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
121 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200122{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200123 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300124
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200125 list_for_each_entry(c, &conn->chan_l, list) {
126 if (c->ident == ident)
127 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200128 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200129 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200130}
131
Mat Martineau5b155ef2012-10-23 15:24:14 -0700132static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
133 u8 ident)
134{
135 struct l2cap_chan *c;
136
137 mutex_lock(&conn->chan_lock);
138 c = __l2cap_get_chan_by_ident(conn, ident);
139 if (c)
140 l2cap_chan_lock(c);
141 mutex_unlock(&conn->chan_lock);
142
143 return c;
144}
145
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300146static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300147{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300148 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300149
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300150 list_for_each_entry(c, &chan_list, global_l) {
151 if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100152 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300153 }
Szymon Janc250938c2011-11-16 09:32:22 +0100154 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300155}
156
157int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
158{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300159 int err;
160
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200161 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300162
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300163 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300164 err = -EADDRINUSE;
165 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300166 }
167
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300168 if (psm) {
169 chan->psm = psm;
170 chan->sport = psm;
171 err = 0;
172 } else {
173 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300174
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300175 err = -EINVAL;
176 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300177 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300178 chan->psm = cpu_to_le16(p);
179 chan->sport = cpu_to_le16(p);
180 err = 0;
181 break;
182 }
183 }
184
185done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200186 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300187 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300188}
189
190int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
191{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200192 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300193
194 chan->scid = scid;
195
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200196 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300197
198 return 0;
199}
200
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300201static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200202{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300203 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200204
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300205 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300206 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200207 return cid;
208 }
209
210 return 0;
211}
212
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200213static void __l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300214{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200215 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100216 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200217
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300218 chan->state = state;
Gustavo Padovan80b98022012-05-27 22:27:51 -0300219 chan->ops->state_change(chan, state);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300220}
221
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200222static void l2cap_state_change(struct l2cap_chan *chan, int state)
223{
224 struct sock *sk = chan->sk;
225
226 lock_sock(sk);
227 __l2cap_state_change(chan, state);
228 release_sock(sk);
229}
230
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200231static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
232{
233 struct sock *sk = chan->sk;
234
235 sk->sk_err = err;
236}
237
238static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
239{
240 struct sock *sk = chan->sk;
241
242 lock_sock(sk);
243 __l2cap_chan_set_err(chan, err);
244 release_sock(sk);
245}
246
Mat Martineau4239d162012-05-17 20:53:49 -0700247static void __set_retrans_timer(struct l2cap_chan *chan)
248{
249 if (!delayed_work_pending(&chan->monitor_timer) &&
250 chan->retrans_timeout) {
251 l2cap_set_timer(chan, &chan->retrans_timer,
252 msecs_to_jiffies(chan->retrans_timeout));
253 }
254}
255
256static void __set_monitor_timer(struct l2cap_chan *chan)
257{
258 __clear_retrans_timer(chan);
259 if (chan->monitor_timeout) {
260 l2cap_set_timer(chan, &chan->monitor_timer,
261 msecs_to_jiffies(chan->monitor_timeout));
262 }
263}
264
Mat Martineau608bcc62012-05-17 20:53:32 -0700265static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
266 u16 seq)
267{
268 struct sk_buff *skb;
269
270 skb_queue_walk(head, skb) {
271 if (bt_cb(skb)->control.txseq == seq)
272 return skb;
273 }
274
275 return NULL;
276}
277
Mat Martineau3c588192012-04-11 10:48:42 -0700278/* ---- L2CAP sequence number lists ---- */
279
280/* For ERTM, ordered lists of sequence numbers must be tracked for
281 * SREJ requests that are received and for frames that are to be
282 * retransmitted. These seq_list functions implement a singly-linked
283 * list in an array, where membership in the list can also be checked
284 * in constant time. Items can also be added to the tail of the list
285 * and removed from the head in constant time, without further memory
286 * allocs or frees.
287 */
288
289static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
290{
291 size_t alloc_size, i;
292
293 /* Allocated size is a power of 2 to map sequence numbers
294 * (which may be up to 14 bits) in to a smaller array that is
295 * sized for the negotiated ERTM transmit windows.
296 */
297 alloc_size = roundup_pow_of_two(size);
298
299 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
300 if (!seq_list->list)
301 return -ENOMEM;
302
303 seq_list->mask = alloc_size - 1;
304 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
305 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
306 for (i = 0; i < alloc_size; i++)
307 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
308
309 return 0;
310}
311
312static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
313{
314 kfree(seq_list->list);
315}
316
317static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
318 u16 seq)
319{
320 /* Constant-time check for list membership */
321 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
322}
323
324static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
325{
326 u16 mask = seq_list->mask;
327
328 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
329 /* In case someone tries to pop the head of an empty list */
330 return L2CAP_SEQ_LIST_CLEAR;
331 } else if (seq_list->head == seq) {
332 /* Head can be removed in constant time */
333 seq_list->head = seq_list->list[seq & mask];
334 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
335
336 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
337 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
338 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
339 }
340 } else {
341 /* Walk the list to find the sequence number */
342 u16 prev = seq_list->head;
343 while (seq_list->list[prev & mask] != seq) {
344 prev = seq_list->list[prev & mask];
345 if (prev == L2CAP_SEQ_LIST_TAIL)
346 return L2CAP_SEQ_LIST_CLEAR;
347 }
348
349 /* Unlink the number from the list and clear it */
350 seq_list->list[prev & mask] = seq_list->list[seq & mask];
351 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
352 if (seq_list->tail == seq)
353 seq_list->tail = prev;
354 }
355 return seq;
356}
357
358static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
359{
360 /* Remove the head in constant time */
361 return l2cap_seq_list_remove(seq_list, seq_list->head);
362}
363
364static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
365{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300366 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700367
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300368 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
369 return;
370
371 for (i = 0; i <= seq_list->mask; i++)
372 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
373
374 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
375 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700376}
377
378static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
379{
380 u16 mask = seq_list->mask;
381
382 /* All appends happen in constant time */
383
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300384 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
385 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700386
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300387 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
388 seq_list->head = seq;
389 else
390 seq_list->list[seq_list->tail & mask] = seq;
391
392 seq_list->tail = seq;
393 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700394}
395
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300396static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300397{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300398 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100399 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200400 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300401 int reason;
402
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200403 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300404
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200405 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200406 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300407
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300408 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300409 reason = ECONNREFUSED;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300410 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100411 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300412 reason = ECONNREFUSED;
413 else
414 reason = ETIMEDOUT;
415
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300416 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300417
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200418 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300419
Gustavo Padovan80b98022012-05-27 22:27:51 -0300420 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200421 mutex_unlock(&conn->chan_lock);
422
Ulisses Furquim371fd832011-12-21 20:02:36 -0200423 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300424}
425
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300426struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200427{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300428 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200429
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300430 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
431 if (!chan)
432 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200433
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200434 mutex_init(&chan->lock);
435
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200436 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300437 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200438 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300439
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300440 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300441
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300442 chan->state = BT_OPEN;
443
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530444 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300445
Mat Martineau28270112012-05-17 21:14:09 -0700446 /* This flag is cleared in l2cap_chan_ready() */
447 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
448
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300449 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100450
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300451 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200452}
453
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530454static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300455{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530456 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
457
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530458 BT_DBG("chan %p", chan);
459
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200460 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300461 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200462 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300463
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530464 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300465}
466
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530467void l2cap_chan_hold(struct l2cap_chan *c)
468{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530469 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530470
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530471 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530472}
473
474void l2cap_chan_put(struct l2cap_chan *c)
475{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530476 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530477
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530478 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530479}
480
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300481void l2cap_chan_set_defaults(struct l2cap_chan *chan)
482{
483 chan->fcs = L2CAP_FCS_CRC16;
484 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
485 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
486 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700487 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300488 chan->sec_level = BT_SECURITY_LOW;
489
490 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
491}
492
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300493void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200494{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300495 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200496 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200497
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200498 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100499
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300500 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200501
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200502 switch (chan->chan_type) {
503 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300504 if (conn->hcon->type == LE_LINK) {
505 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300506 chan->omtu = L2CAP_DEFAULT_MTU;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300507 chan->scid = L2CAP_CID_LE_DATA;
508 chan->dcid = L2CAP_CID_LE_DATA;
Ville Tervob62f3282011-02-10 22:38:50 -0300509 } else {
510 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300511 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300512 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300513 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200514 break;
515
516 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200517 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300518 chan->scid = L2CAP_CID_CONN_LESS;
519 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300520 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200521 break;
522
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300523 case L2CAP_CHAN_CONN_FIX_A2MP:
524 chan->scid = L2CAP_CID_A2MP;
525 chan->dcid = L2CAP_CID_A2MP;
526 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
527 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
528 break;
529
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200530 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200531 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300532 chan->scid = L2CAP_CID_SIGNALING;
533 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300534 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200535 }
536
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300537 chan->local_id = L2CAP_BESTEFFORT_ID;
538 chan->local_stype = L2CAP_SERV_BESTEFFORT;
539 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
540 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
541 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300542 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300543
Ulisses Furquim371fd832011-12-21 20:02:36 -0200544 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300545
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200546 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200547}
548
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300549void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200550{
551 mutex_lock(&conn->chan_lock);
552 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200553 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200554}
555
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300556void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200557{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300558 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200559
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300560 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200561
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300562 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200563
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900564 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300565 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300566 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200567 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200568
Ulisses Furquim371fd832011-12-21 20:02:36 -0200569 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300570
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300571 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300572
573 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
574 hci_conn_put(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300575
576 if (mgr && mgr->bredr_chan == chan)
577 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200578 }
579
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100580 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200581
Mat Martineau28270112012-05-17 21:14:09 -0700582 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300583 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300584
Gustavo Padovanee556f62012-05-18 20:22:38 -0300585 switch(chan->mode) {
586 case L2CAP_MODE_BASIC:
587 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300588
Gustavo Padovanee556f62012-05-18 20:22:38 -0300589 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300590 __clear_retrans_timer(chan);
591 __clear_monitor_timer(chan);
592 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300593
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300594 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300595
Mat Martineau3c588192012-04-11 10:48:42 -0700596 l2cap_seq_list_free(&chan->srej_list);
597 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300598
599 /* fall through */
600
601 case L2CAP_MODE_STREAMING:
602 skb_queue_purge(&chan->tx_q);
603 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300604 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300605
606 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200607}
608
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300609void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300610{
611 struct l2cap_conn *conn = chan->conn;
612 struct sock *sk = chan->sk;
613
Gustavo Padovan2d792812012-10-06 10:07:01 +0100614 BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state),
615 sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300616
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300617 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300618 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100619 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300620 break;
621
622 case BT_CONNECTED:
623 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300624 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100625 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300626 __set_chan_timer(chan, sk->sk_sndtimeo);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300627 l2cap_send_disconn_req(conn, chan, reason);
628 } else
629 l2cap_chan_del(chan, reason);
630 break;
631
632 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300633 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100634 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300635 struct l2cap_conn_rsp rsp;
636 __u16 result;
637
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300638 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300639 result = L2CAP_CR_SEC_BLOCK;
640 else
641 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300642 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300643
644 rsp.scid = cpu_to_le16(chan->dcid);
645 rsp.dcid = cpu_to_le16(chan->scid);
646 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300647 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300648 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100649 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300650 }
651
652 l2cap_chan_del(chan, reason);
653 break;
654
655 case BT_CONNECT:
656 case BT_DISCONN:
657 l2cap_chan_del(chan, reason);
658 break;
659
660 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100661 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300662 break;
663 }
664}
665
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300666static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530667{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300668 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300669 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530670 case BT_SECURITY_HIGH:
671 return HCI_AT_DEDICATED_BONDING_MITM;
672 case BT_SECURITY_MEDIUM:
673 return HCI_AT_DEDICATED_BONDING;
674 default:
675 return HCI_AT_NO_BONDING;
676 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300677 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300678 if (chan->sec_level == BT_SECURITY_LOW)
679 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530680
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300681 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530682 return HCI_AT_NO_BONDING_MITM;
683 else
684 return HCI_AT_NO_BONDING;
685 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300686 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530687 case BT_SECURITY_HIGH:
688 return HCI_AT_GENERAL_BONDING_MITM;
689 case BT_SECURITY_MEDIUM:
690 return HCI_AT_GENERAL_BONDING;
691 default:
692 return HCI_AT_NO_BONDING;
693 }
694 }
695}
696
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200697/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200698int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200699{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300700 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100701 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200702
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300703 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100704
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300705 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200706}
707
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200708static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200709{
710 u8 id;
711
712 /* Get next available identificator.
713 * 1 - 128 are used by kernel.
714 * 129 - 199 are reserved.
715 * 200 - 254 are used by utilities like l2ping, etc.
716 */
717
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200718 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200719
720 if (++conn->tx_ident > 128)
721 conn->tx_ident = 1;
722
723 id = conn->tx_ident;
724
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200725 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200726
727 return id;
728}
729
Gustavo Padovan2d792812012-10-06 10:07:01 +0100730static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
731 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200732{
733 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200734 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200735
736 BT_DBG("code 0x%2.2x", code);
737
738 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300739 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200740
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200741 if (lmp_no_flush_capable(conn->hcon->hdev))
742 flags = ACL_START_NO_FLUSH;
743 else
744 flags = ACL_START;
745
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700746 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200747 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700748
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200749 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200750}
751
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700752static bool __chan_is_moving(struct l2cap_chan *chan)
753{
754 return chan->move_state != L2CAP_MOVE_STABLE &&
755 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
756}
757
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200758static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
759{
760 struct hci_conn *hcon = chan->conn->hcon;
761 u16 flags;
762
763 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100764 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200765
766 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100767 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200768 flags = ACL_START_NO_FLUSH;
769 else
770 flags = ACL_START;
771
772 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
773 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774}
775
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700776static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
777{
778 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
779 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
780
781 if (enh & L2CAP_CTRL_FRAME_TYPE) {
782 /* S-Frame */
783 control->sframe = 1;
784 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
785 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
786
787 control->sar = 0;
788 control->txseq = 0;
789 } else {
790 /* I-Frame */
791 control->sframe = 0;
792 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
793 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
794
795 control->poll = 0;
796 control->super = 0;
797 }
798}
799
800static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
801{
802 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
803 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
804
805 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
806 /* S-Frame */
807 control->sframe = 1;
808 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
809 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
810
811 control->sar = 0;
812 control->txseq = 0;
813 } else {
814 /* I-Frame */
815 control->sframe = 0;
816 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
817 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
818
819 control->poll = 0;
820 control->super = 0;
821 }
822}
823
824static inline void __unpack_control(struct l2cap_chan *chan,
825 struct sk_buff *skb)
826{
827 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
828 __unpack_extended_control(get_unaligned_le32(skb->data),
829 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700830 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700831 } else {
832 __unpack_enhanced_control(get_unaligned_le16(skb->data),
833 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700834 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700835 }
836}
837
838static u32 __pack_extended_control(struct l2cap_ctrl *control)
839{
840 u32 packed;
841
842 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
843 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
844
845 if (control->sframe) {
846 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
847 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
848 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
849 } else {
850 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
851 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
852 }
853
854 return packed;
855}
856
857static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
858{
859 u16 packed;
860
861 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
862 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
863
864 if (control->sframe) {
865 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
866 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
867 packed |= L2CAP_CTRL_FRAME_TYPE;
868 } else {
869 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
870 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
871 }
872
873 return packed;
874}
875
876static inline void __pack_control(struct l2cap_chan *chan,
877 struct l2cap_ctrl *control,
878 struct sk_buff *skb)
879{
880 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
881 put_unaligned_le32(__pack_extended_control(control),
882 skb->data + L2CAP_HDR_SIZE);
883 } else {
884 put_unaligned_le16(__pack_enhanced_control(control),
885 skb->data + L2CAP_HDR_SIZE);
886 }
887}
888
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300889static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
890{
891 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
892 return L2CAP_EXT_HDR_SIZE;
893 else
894 return L2CAP_ENH_HDR_SIZE;
895}
896
Mat Martineaua67d7f62012-05-17 20:53:35 -0700897static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
898 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300899{
900 struct sk_buff *skb;
901 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300902 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300903
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300904 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300905 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300906
Mat Martineaua67d7f62012-05-17 20:53:35 -0700907 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300908
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300909 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700910 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300911
912 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300913 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300914 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300915
Mat Martineaua67d7f62012-05-17 20:53:35 -0700916 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
917 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
918 else
919 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300920
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300921 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700922 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300923 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300924 }
925
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200926 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700927 return skb;
928}
929
930static void l2cap_send_sframe(struct l2cap_chan *chan,
931 struct l2cap_ctrl *control)
932{
933 struct sk_buff *skb;
934 u32 control_field;
935
936 BT_DBG("chan %p, control %p", chan, control);
937
938 if (!control->sframe)
939 return;
940
941 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
942 !control->poll)
943 control->final = 1;
944
945 if (control->super == L2CAP_SUPER_RR)
946 clear_bit(CONN_RNR_SENT, &chan->conn_state);
947 else if (control->super == L2CAP_SUPER_RNR)
948 set_bit(CONN_RNR_SENT, &chan->conn_state);
949
950 if (control->super != L2CAP_SUPER_SREJ) {
951 chan->last_acked_seq = control->reqseq;
952 __clear_ack_timer(chan);
953 }
954
955 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
956 control->final, control->poll, control->super);
957
958 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
959 control_field = __pack_extended_control(control);
960 else
961 control_field = __pack_enhanced_control(control);
962
963 skb = l2cap_create_sframe_pdu(chan, control_field);
964 if (!IS_ERR(skb))
965 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300966}
967
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700968static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300969{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700970 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300971
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700972 BT_DBG("chan %p, poll %d", chan, poll);
973
974 memset(&control, 0, sizeof(control));
975 control.sframe = 1;
976 control.poll = poll;
977
978 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
979 control.super = L2CAP_SUPER_RNR;
980 else
981 control.super = L2CAP_SUPER_RR;
982
983 control.reqseq = chan->buffer_seq;
984 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300985}
986
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300987static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300988{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -0300989 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300990}
991
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300992static bool __amp_capable(struct l2cap_chan *chan)
993{
994 struct l2cap_conn *conn = chan->conn;
995
996 if (enable_hs &&
997 chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED &&
998 conn->fixed_chan_mask & L2CAP_FC_A2MP)
999 return true;
1000 else
1001 return false;
1002}
1003
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001004void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001005{
1006 struct l2cap_conn *conn = chan->conn;
1007 struct l2cap_conn_req req;
1008
1009 req.scid = cpu_to_le16(chan->scid);
1010 req.psm = chan->psm;
1011
1012 chan->ident = l2cap_get_ident(conn);
1013
1014 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1015
1016 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1017}
1018
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001019static void l2cap_move_setup(struct l2cap_chan *chan)
1020{
1021 struct sk_buff *skb;
1022
1023 BT_DBG("chan %p", chan);
1024
1025 if (chan->mode != L2CAP_MODE_ERTM)
1026 return;
1027
1028 __clear_retrans_timer(chan);
1029 __clear_monitor_timer(chan);
1030 __clear_ack_timer(chan);
1031
1032 chan->retry_count = 0;
1033 skb_queue_walk(&chan->tx_q, skb) {
1034 if (bt_cb(skb)->control.retries)
1035 bt_cb(skb)->control.retries = 1;
1036 else
1037 break;
1038 }
1039
1040 chan->expected_tx_seq = chan->buffer_seq;
1041
1042 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1043 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1044 l2cap_seq_list_clear(&chan->retrans_list);
1045 l2cap_seq_list_clear(&chan->srej_list);
1046 skb_queue_purge(&chan->srej_q);
1047
1048 chan->tx_state = L2CAP_TX_STATE_XMIT;
1049 chan->rx_state = L2CAP_RX_STATE_MOVE;
1050
1051 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1052}
1053
Mat Martineau5f3847a2012-10-23 15:24:12 -07001054static void l2cap_move_done(struct l2cap_chan *chan)
1055{
1056 u8 move_role = chan->move_role;
1057 BT_DBG("chan %p", chan);
1058
1059 chan->move_state = L2CAP_MOVE_STABLE;
1060 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1061
1062 if (chan->mode != L2CAP_MODE_ERTM)
1063 return;
1064
1065 switch (move_role) {
1066 case L2CAP_MOVE_ROLE_INITIATOR:
1067 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1068 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1069 break;
1070 case L2CAP_MOVE_ROLE_RESPONDER:
1071 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1072 break;
1073 }
1074}
1075
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001076static void l2cap_chan_ready(struct l2cap_chan *chan)
1077{
Mat Martineau28270112012-05-17 21:14:09 -07001078 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001079 chan->conf_state = 0;
1080 __clear_chan_timer(chan);
1081
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001082 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001083
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001084 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001085}
1086
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001087static void l2cap_start_connection(struct l2cap_chan *chan)
1088{
1089 if (__amp_capable(chan)) {
1090 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1091 a2mp_discover_amp(chan);
1092 } else {
1093 l2cap_send_conn_req(chan);
1094 }
1095}
1096
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001097static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001098{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001099 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001100
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001101 if (conn->hcon->type == LE_LINK) {
1102 l2cap_chan_ready(chan);
1103 return;
1104 }
1105
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001106 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001107 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1108 return;
1109
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001110 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001111 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001112 l2cap_start_connection(chan);
1113 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001114 } else {
1115 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001116 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001117
1118 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1119 conn->info_ident = l2cap_get_ident(conn);
1120
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001121 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001122
Gustavo Padovan2d792812012-10-06 10:07:01 +01001123 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1124 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001125 }
1126}
1127
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001128static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1129{
1130 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001131 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001132 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1133
1134 switch (mode) {
1135 case L2CAP_MODE_ERTM:
1136 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1137 case L2CAP_MODE_STREAMING:
1138 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1139 default:
1140 return 0x00;
1141 }
1142}
1143
Gustavo Padovan2d792812012-10-06 10:07:01 +01001144static void l2cap_send_disconn_req(struct l2cap_conn *conn,
1145 struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001146{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001147 struct sock *sk = chan->sk;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001148 struct l2cap_disconn_req req;
1149
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001150 if (!conn)
1151 return;
1152
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001153 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001154 __clear_retrans_timer(chan);
1155 __clear_monitor_timer(chan);
1156 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001157 }
1158
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001159 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001160 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001161 return;
1162 }
1163
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001164 req.dcid = cpu_to_le16(chan->dcid);
1165 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001166 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1167 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001168
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001169 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001170 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001171 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001172 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001173}
1174
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001176static void l2cap_conn_start(struct l2cap_conn *conn)
1177{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001178 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001179
1180 BT_DBG("conn %p", conn);
1181
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001182 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001183
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001184 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001185 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001186
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001187 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001188
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001189 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001190 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001191 continue;
1192 }
1193
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001194 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001195 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001196 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001197 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001198 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001199 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001200
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001201 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001202 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001203 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001204 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001205 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001206 continue;
1207 }
1208
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001209 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001210
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001211 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001212 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001213 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001214 rsp.scid = cpu_to_le16(chan->dcid);
1215 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001216
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001217 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001218 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001219 if (test_bit(BT_SK_DEFER_SETUP,
1220 &bt_sk(sk)->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001221 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1222 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001223 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001224
1225 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001226 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001227 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1228 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001229 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001230 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001231 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001232 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1233 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001234 }
1235
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001236 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001237 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001238
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001239 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001240 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001241 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001242 continue;
1243 }
1244
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001245 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001246 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001247 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001248 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001249 }
1250
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001251 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001252 }
1253
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001254 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001255}
1256
Ido Yarivc2287682012-04-20 15:46:07 -03001257/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001258 * Returns closest match, locked.
1259 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001260static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001261 bdaddr_t *src,
1262 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001263{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001264 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001265
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001266 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001267
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001268 list_for_each_entry(c, &chan_list, global_l) {
1269 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001270
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001271 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001272 continue;
1273
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001274 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001275 int src_match, dst_match;
1276 int src_any, dst_any;
1277
Ville Tervob62f3282011-02-10 22:38:50 -03001278 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001279 src_match = !bacmp(&bt_sk(sk)->src, src);
1280 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1281 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001282 read_unlock(&chan_list_lock);
1283 return c;
1284 }
Ville Tervob62f3282011-02-10 22:38:50 -03001285
1286 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001287 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1288 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1289 if ((src_match && dst_any) || (src_any && dst_match) ||
1290 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001291 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001292 }
1293 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001294
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001295 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001296
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001297 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001298}
1299
1300static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1301{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001302 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001303 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001304
1305 BT_DBG("");
1306
1307 /* Check if we have socket listening on cid */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001308 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
Ido Yarivc2287682012-04-20 15:46:07 -03001309 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001310 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001311 return;
1312
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001313 parent = pchan->sk;
1314
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001315 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001316
Gustavo Padovan80b98022012-05-27 22:27:51 -03001317 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001318 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001319 goto clean;
1320
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001321 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001322
Ville Tervob62f3282011-02-10 22:38:50 -03001323 hci_conn_hold(conn->hcon);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001324 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
Ville Tervob62f3282011-02-10 22:38:50 -03001325
Ville Tervob62f3282011-02-10 22:38:50 -03001326 bacpy(&bt_sk(sk)->src, conn->src);
1327 bacpy(&bt_sk(sk)->dst, conn->dst);
1328
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001329 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001330
Gustavo Padovan6754e0d2012-05-25 09:30:56 -03001331 l2cap_chan_ready(chan);
Ville Tervob62f3282011-02-10 22:38:50 -03001332
Ville Tervob62f3282011-02-10 22:38:50 -03001333clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001334 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001335}
1336
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001337static void l2cap_conn_ready(struct l2cap_conn *conn)
1338{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001339 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001340 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001341
1342 BT_DBG("conn %p", conn);
1343
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001344 if (!hcon->out && hcon->type == LE_LINK)
Ville Tervob62f3282011-02-10 22:38:50 -03001345 l2cap_le_conn_ready(conn);
1346
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001347 if (hcon->out && hcon->type == LE_LINK)
1348 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001349
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001350 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001351
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001352 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001353
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001354 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001355
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001356 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1357 l2cap_chan_unlock(chan);
1358 continue;
1359 }
1360
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001361 if (hcon->type == LE_LINK) {
1362 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001363 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001364
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001365 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001366 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001367 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001368 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001369 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001370 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001371 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001372
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001373 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001374 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001375
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001376 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001377 }
1378
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001379 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001380}
1381
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001382/* Notify sockets that we cannot guaranty reliability anymore */
1383static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1384{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001385 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001386
1387 BT_DBG("conn %p", conn);
1388
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001389 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001390
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001391 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001392 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001393 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001394 }
1395
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001396 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001397}
1398
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001399static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001400{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001401 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001402 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001403
Marcel Holtmann984947d2009-02-06 23:35:19 +01001404 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001405 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001406
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001407 l2cap_conn_start(conn);
1408}
1409
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001410static void l2cap_conn_del(struct hci_conn *hcon, int err)
1411{
1412 struct l2cap_conn *conn = hcon->l2cap_data;
1413 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001414
1415 if (!conn)
1416 return;
1417
1418 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1419
1420 kfree_skb(conn->rx_skb);
1421
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001422 mutex_lock(&conn->chan_lock);
1423
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001424 /* Kill channels */
1425 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001426 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001427 l2cap_chan_lock(chan);
1428
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001429 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001430
1431 l2cap_chan_unlock(chan);
1432
Gustavo Padovan80b98022012-05-27 22:27:51 -03001433 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001434 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001435 }
1436
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001437 mutex_unlock(&conn->chan_lock);
1438
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001439 hci_chan_del(conn->hchan);
1440
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001441 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001442 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001443
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001444 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001445 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001446 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001447 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001448
1449 hcon->l2cap_data = NULL;
1450 kfree(conn);
1451}
1452
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001453static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001454{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001455 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001456 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001457
Johan Hedbergd06cc412012-06-06 18:44:11 +08001458 BT_DBG("conn %p", conn);
1459
1460 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1461 smp_chan_destroy(conn);
1462 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1463 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001464}
1465
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1467{
Marcel Holtmann01394182006-07-03 10:02:46 +02001468 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001469 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470
Marcel Holtmann01394182006-07-03 10:02:46 +02001471 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472 return conn;
1473
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001474 hchan = hci_chan_create(hcon);
1475 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001478 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001479 if (!conn) {
1480 hci_chan_del(hchan);
1481 return NULL;
1482 }
1483
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484 hcon->l2cap_data = conn;
1485 conn->hcon = hcon;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001486 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001488 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001489
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001490 switch (hcon->type) {
1491 case AMP_LINK:
1492 conn->mtu = hcon->hdev->block_mtu;
1493 break;
1494
1495 case LE_LINK:
1496 if (hcon->hdev->le_mtu) {
1497 conn->mtu = hcon->hdev->le_mtu;
1498 break;
1499 }
1500 /* fall through */
1501
1502 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001503 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001504 break;
1505 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001506
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507 conn->src = &hcon->hdev->bdaddr;
1508 conn->dst = &hcon->dst;
1509
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001510 conn->feat_mask = 0;
1511
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001513 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001514
1515 INIT_LIST_HEAD(&conn->chan_l);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001517 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001518 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001519 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001520 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001521
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001522 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001523
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524 return conn;
1525}
1526
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528
Ido Yarivc2287682012-04-20 15:46:07 -03001529/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530 * Returns closest match.
1531 */
Ido Yarivc2287682012-04-20 15:46:07 -03001532static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1533 bdaddr_t *src,
1534 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001536 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001538 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001539
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001540 list_for_each_entry(c, &chan_list, global_l) {
1541 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001542
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001543 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544 continue;
1545
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001546 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001547 int src_match, dst_match;
1548 int src_any, dst_any;
1549
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001551 src_match = !bacmp(&bt_sk(sk)->src, src);
1552 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1553 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001554 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001555 return c;
1556 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557
1558 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001559 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1560 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1561 if ((src_match && dst_any) || (src_any && dst_match) ||
1562 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001563 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564 }
1565 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001567 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001568
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001569 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001570}
1571
Andre Guedes8e9f9892012-04-24 21:02:55 -03001572int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1573 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001575 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 struct l2cap_conn *conn;
1578 struct hci_conn *hcon;
1579 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001580 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001581 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001583 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301584 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001586 hdev = hci_get_route(dst, src);
1587 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588 return -EHOSTUNREACH;
1589
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001590 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001592 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001593
1594 /* PSM must be odd and lsb of upper byte must be 0 */
1595 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001596 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001597 err = -EINVAL;
1598 goto done;
1599 }
1600
1601 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1602 err = -EINVAL;
1603 goto done;
1604 }
1605
1606 switch (chan->mode) {
1607 case L2CAP_MODE_BASIC:
1608 break;
1609 case L2CAP_MODE_ERTM:
1610 case L2CAP_MODE_STREAMING:
1611 if (!disable_ertm)
1612 break;
1613 /* fall through */
1614 default:
1615 err = -ENOTSUPP;
1616 goto done;
1617 }
1618
Gustavo Padovan0797e012012-05-27 22:27:54 -03001619 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001620 case BT_CONNECT:
1621 case BT_CONNECT2:
1622 case BT_CONFIG:
1623 /* Already connecting */
1624 err = 0;
1625 goto done;
1626
1627 case BT_CONNECTED:
1628 /* Already connected */
1629 err = -EISCONN;
1630 goto done;
1631
1632 case BT_OPEN:
1633 case BT_BOUND:
1634 /* Can connect */
1635 break;
1636
1637 default:
1638 err = -EBADFD;
1639 goto done;
1640 }
1641
1642 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001643 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001644 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001645 release_sock(sk);
1646
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001647 chan->psm = psm;
1648 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001650 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001651
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001652 if (chan->dcid == L2CAP_CID_LE_DATA)
Andre Guedes8e9f9892012-04-24 21:02:55 -03001653 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001654 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001655 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001656 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001657 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001658
Ville Tervo30e76272011-02-22 16:10:53 -03001659 if (IS_ERR(hcon)) {
1660 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001662 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663
1664 conn = l2cap_conn_add(hcon, 0);
1665 if (!conn) {
1666 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001667 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668 goto done;
1669 }
1670
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001671 if (hcon->type == LE_LINK) {
1672 err = 0;
1673
1674 if (!list_empty(&conn->chan_l)) {
1675 err = -EBUSY;
1676 hci_conn_put(hcon);
1677 }
1678
1679 if (err)
1680 goto done;
1681 }
1682
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 /* Update source addr of the socket */
1684 bacpy(src, conn->src);
1685
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001686 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001687 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001688 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001689
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001690 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001691 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692
1693 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001694 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001695 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001696 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001697 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001698 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001699 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 }
1701
Ville Tervo30e76272011-02-22 16:10:53 -03001702 err = 0;
1703
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001705 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001706 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 hci_dev_put(hdev);
1708 return err;
1709}
1710
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001711int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001712{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001713 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001714 DECLARE_WAITQUEUE(wait, current);
1715 int err = 0;
1716 int timeo = HZ/5;
1717
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001718 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001719 set_current_state(TASK_INTERRUPTIBLE);
1720 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001721 if (!timeo)
1722 timeo = HZ/5;
1723
1724 if (signal_pending(current)) {
1725 err = sock_intr_errno(timeo);
1726 break;
1727 }
1728
1729 release_sock(sk);
1730 timeo = schedule_timeout(timeo);
1731 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001732 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001733
1734 err = sock_error(sk);
1735 if (err)
1736 break;
1737 }
1738 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001739 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001740 return err;
1741}
1742
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001743static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001744{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001745 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001746 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001747
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001748 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001749
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001750 l2cap_chan_lock(chan);
1751
Mat Martineau80909e02012-05-17 20:53:50 -07001752 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001753 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001754 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001755 return;
1756 }
1757
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001758 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001759
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001760 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001761 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001762}
1763
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001764static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001765{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001766 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001767 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001768
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001769 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001770
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001771 l2cap_chan_lock(chan);
1772
Mat Martineau80909e02012-05-17 20:53:50 -07001773 if (!chan->conn) {
1774 l2cap_chan_unlock(chan);
1775 l2cap_chan_put(chan);
1776 return;
1777 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001778
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001779 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001780 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001781 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001782}
1783
Gustavo Padovand6603662012-05-21 13:58:22 -03001784static void l2cap_streaming_send(struct l2cap_chan *chan,
1785 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001786{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001787 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001788 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001789
Mat Martineau37339372012-05-17 20:53:33 -07001790 BT_DBG("chan %p, skbs %p", chan, skbs);
1791
Mat Martineau37339372012-05-17 20:53:33 -07001792 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1793
1794 while (!skb_queue_empty(&chan->tx_q)) {
1795
1796 skb = skb_dequeue(&chan->tx_q);
1797
1798 bt_cb(skb)->control.retries = 1;
1799 control = &bt_cb(skb)->control;
1800
1801 control->reqseq = 0;
1802 control->txseq = chan->next_tx_seq;
1803
1804 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001805
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001806 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001807 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1808 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001809 }
1810
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001811 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001812
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001813 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001814
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001815 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001816 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001817 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001818}
1819
Szymon Janc67c9e842011-07-28 16:24:33 +02001820static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001821{
1822 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001823 struct l2cap_ctrl *control;
1824 int sent = 0;
1825
1826 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001827
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001828 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001829 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001830
Mat Martineau94122bb2012-05-02 09:42:02 -07001831 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1832 return 0;
1833
Mat Martineau18a48e72012-05-17 20:53:34 -07001834 while (chan->tx_send_head &&
1835 chan->unacked_frames < chan->remote_tx_win &&
1836 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001837
Mat Martineau18a48e72012-05-17 20:53:34 -07001838 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001839
Mat Martineau18a48e72012-05-17 20:53:34 -07001840 bt_cb(skb)->control.retries = 1;
1841 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001842
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001843 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001844 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001845
Mat Martineau18a48e72012-05-17 20:53:34 -07001846 control->reqseq = chan->buffer_seq;
1847 chan->last_acked_seq = chan->buffer_seq;
1848 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001849
Mat Martineau18a48e72012-05-17 20:53:34 -07001850 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001851
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001852 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001853 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1854 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001855 }
1856
Mat Martineau18a48e72012-05-17 20:53:34 -07001857 /* Clone after data has been modified. Data is assumed to be
1858 read-only (for locking purposes) on cloned sk_buffs.
1859 */
1860 tx_skb = skb_clone(skb, GFP_KERNEL);
1861
1862 if (!tx_skb)
1863 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001864
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001865 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001866
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001867 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001868 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001869 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001870 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001871
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001872 if (skb_queue_is_last(&chan->tx_q, skb))
1873 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001874 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001875 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001876
1877 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001878 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001879 }
1880
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001881 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
1882 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07001883
1884 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001885}
1886
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001887static void l2cap_ertm_resend(struct l2cap_chan *chan)
1888{
1889 struct l2cap_ctrl control;
1890 struct sk_buff *skb;
1891 struct sk_buff *tx_skb;
1892 u16 seq;
1893
1894 BT_DBG("chan %p", chan);
1895
1896 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1897 return;
1898
1899 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1900 seq = l2cap_seq_list_pop(&chan->retrans_list);
1901
1902 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1903 if (!skb) {
1904 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01001905 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001906 continue;
1907 }
1908
1909 bt_cb(skb)->control.retries++;
1910 control = bt_cb(skb)->control;
1911
1912 if (chan->max_tx != 0 &&
1913 bt_cb(skb)->control.retries > chan->max_tx) {
1914 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
1915 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
1916 l2cap_seq_list_clear(&chan->retrans_list);
1917 break;
1918 }
1919
1920 control.reqseq = chan->buffer_seq;
1921 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
1922 control.final = 1;
1923 else
1924 control.final = 0;
1925
1926 if (skb_cloned(skb)) {
1927 /* Cloned sk_buffs are read-only, so we need a
1928 * writeable copy
1929 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001930 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001931 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001932 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001933 }
1934
1935 if (!tx_skb) {
1936 l2cap_seq_list_clear(&chan->retrans_list);
1937 break;
1938 }
1939
1940 /* Update skb contents */
1941 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1942 put_unaligned_le32(__pack_extended_control(&control),
1943 tx_skb->data + L2CAP_HDR_SIZE);
1944 } else {
1945 put_unaligned_le16(__pack_enhanced_control(&control),
1946 tx_skb->data + L2CAP_HDR_SIZE);
1947 }
1948
1949 if (chan->fcs == L2CAP_FCS_CRC16) {
1950 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
1951 put_unaligned_le16(fcs, skb_put(tx_skb,
1952 L2CAP_FCS_SIZE));
1953 }
1954
1955 l2cap_do_send(chan, tx_skb);
1956
1957 BT_DBG("Resent txseq %d", control.txseq);
1958
1959 chan->last_acked_seq = chan->buffer_seq;
1960 }
1961}
1962
Mat Martineauf80842a2012-05-17 20:53:46 -07001963static void l2cap_retransmit(struct l2cap_chan *chan,
1964 struct l2cap_ctrl *control)
1965{
1966 BT_DBG("chan %p, control %p", chan, control);
1967
1968 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
1969 l2cap_ertm_resend(chan);
1970}
1971
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001972static void l2cap_retransmit_all(struct l2cap_chan *chan,
1973 struct l2cap_ctrl *control)
1974{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001975 struct sk_buff *skb;
1976
1977 BT_DBG("chan %p, control %p", chan, control);
1978
1979 if (control->poll)
1980 set_bit(CONN_SEND_FBIT, &chan->conn_state);
1981
1982 l2cap_seq_list_clear(&chan->retrans_list);
1983
1984 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1985 return;
1986
1987 if (chan->unacked_frames) {
1988 skb_queue_walk(&chan->tx_q, skb) {
1989 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001990 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001991 break;
1992 }
1993
1994 skb_queue_walk_from(&chan->tx_q, skb) {
1995 if (skb == chan->tx_send_head)
1996 break;
1997
1998 l2cap_seq_list_append(&chan->retrans_list,
1999 bt_cb(skb)->control.txseq);
2000 }
2001
2002 l2cap_ertm_resend(chan);
2003 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002004}
2005
Szymon Jancb17e73b2012-01-11 10:59:47 +01002006static void l2cap_send_ack(struct l2cap_chan *chan)
2007{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002008 struct l2cap_ctrl control;
2009 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2010 chan->last_acked_seq);
2011 int threshold;
2012
2013 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2014 chan, chan->last_acked_seq, chan->buffer_seq);
2015
2016 memset(&control, 0, sizeof(control));
2017 control.sframe = 1;
2018
2019 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2020 chan->rx_state == L2CAP_RX_STATE_RECV) {
2021 __clear_ack_timer(chan);
2022 control.super = L2CAP_SUPER_RNR;
2023 control.reqseq = chan->buffer_seq;
2024 l2cap_send_sframe(chan, &control);
2025 } else {
2026 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2027 l2cap_ertm_send(chan);
2028 /* If any i-frames were sent, they included an ack */
2029 if (chan->buffer_seq == chan->last_acked_seq)
2030 frames_to_ack = 0;
2031 }
2032
Mat Martineauc20f8e32012-07-10 05:47:07 -07002033 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002034 * Calculate without mul or div
2035 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002036 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002037 threshold += threshold << 1;
2038 threshold >>= 2;
2039
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002040 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002041 threshold);
2042
2043 if (frames_to_ack >= threshold) {
2044 __clear_ack_timer(chan);
2045 control.super = L2CAP_SUPER_RR;
2046 control.reqseq = chan->buffer_seq;
2047 l2cap_send_sframe(chan, &control);
2048 frames_to_ack = 0;
2049 }
2050
2051 if (frames_to_ack)
2052 __set_ack_timer(chan);
2053 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002054}
2055
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002056static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2057 struct msghdr *msg, int len,
2058 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002059{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002060 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002061 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002062 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002063
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002064 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002065 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002066
2067 sent += count;
2068 len -= count;
2069
2070 /* Continuation fragments (no L2CAP header) */
2071 frag = &skb_shinfo(skb)->frag_list;
2072 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002073 struct sk_buff *tmp;
2074
Linus Torvalds1da177e2005-04-16 15:20:36 -07002075 count = min_t(unsigned int, conn->mtu, len);
2076
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002077 tmp = chan->ops->alloc_skb(chan, count,
2078 msg->msg_flags & MSG_DONTWAIT);
2079 if (IS_ERR(tmp))
2080 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002081
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002082 *frag = tmp;
2083
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002084 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2085 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002087 (*frag)->priority = skb->priority;
2088
Linus Torvalds1da177e2005-04-16 15:20:36 -07002089 sent += count;
2090 len -= count;
2091
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002092 skb->len += (*frag)->len;
2093 skb->data_len += (*frag)->len;
2094
Linus Torvalds1da177e2005-04-16 15:20:36 -07002095 frag = &(*frag)->next;
2096 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097
2098 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002099}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002100
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002101static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002102 struct msghdr *msg, size_t len,
2103 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002104{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002105 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002106 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002107 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002108 struct l2cap_hdr *lh;
2109
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002110 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002111
2112 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002113
2114 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002115 msg->msg_flags & MSG_DONTWAIT);
2116 if (IS_ERR(skb))
2117 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002118
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002119 skb->priority = priority;
2120
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002121 /* Create L2CAP header */
2122 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002123 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002124 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
2125 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002126
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002127 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002128 if (unlikely(err < 0)) {
2129 kfree_skb(skb);
2130 return ERR_PTR(err);
2131 }
2132 return skb;
2133}
2134
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002135static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002136 struct msghdr *msg, size_t len,
2137 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002138{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002139 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002140 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002141 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002142 struct l2cap_hdr *lh;
2143
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002144 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002145
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002146 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002147
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002148 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002149 msg->msg_flags & MSG_DONTWAIT);
2150 if (IS_ERR(skb))
2151 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002152
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002153 skb->priority = priority;
2154
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002155 /* Create L2CAP header */
2156 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002157 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002158 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002159
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002160 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002161 if (unlikely(err < 0)) {
2162 kfree_skb(skb);
2163 return ERR_PTR(err);
2164 }
2165 return skb;
2166}
2167
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002168static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002169 struct msghdr *msg, size_t len,
2170 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002171{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002172 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002173 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002174 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002175 struct l2cap_hdr *lh;
2176
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002177 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002178
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002179 if (!conn)
2180 return ERR_PTR(-ENOTCONN);
2181
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002182 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002183
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002184 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002185 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002186
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002187 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002188 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002189
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002190 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002191
2192 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002193 msg->msg_flags & MSG_DONTWAIT);
2194 if (IS_ERR(skb))
2195 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002196
2197 /* Create L2CAP header */
2198 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002199 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002200 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002201
Mat Martineau18a48e72012-05-17 20:53:34 -07002202 /* Control header is populated later */
2203 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2204 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2205 else
2206 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002207
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002208 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002209 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002210
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002211 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002212 if (unlikely(err < 0)) {
2213 kfree_skb(skb);
2214 return ERR_PTR(err);
2215 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002216
Mat Martineau18a48e72012-05-17 20:53:34 -07002217 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002218 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002219 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002220}
2221
Mat Martineau94122bb2012-05-02 09:42:02 -07002222static int l2cap_segment_sdu(struct l2cap_chan *chan,
2223 struct sk_buff_head *seg_queue,
2224 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002225{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002226 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002227 u16 sdu_len;
2228 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002229 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002230
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002231 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002232
Mat Martineau94122bb2012-05-02 09:42:02 -07002233 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2234 * so fragmented skbs are not used. The HCI layer's handling
2235 * of fragmented skbs is not compatible with ERTM's queueing.
2236 */
2237
2238 /* PDU size is derived from the HCI MTU */
2239 pdu_len = chan->conn->mtu;
2240
2241 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
2242
2243 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002244 if (chan->fcs)
2245 pdu_len -= L2CAP_FCS_SIZE;
2246
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002247 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002248
2249 /* Remote device may have requested smaller PDUs */
2250 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2251
2252 if (len <= pdu_len) {
2253 sar = L2CAP_SAR_UNSEGMENTED;
2254 sdu_len = 0;
2255 pdu_len = len;
2256 } else {
2257 sar = L2CAP_SAR_START;
2258 sdu_len = len;
2259 pdu_len -= L2CAP_SDULEN_SIZE;
2260 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002261
2262 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002263 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002264
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002265 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002266 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002267 return PTR_ERR(skb);
2268 }
2269
Mat Martineau94122bb2012-05-02 09:42:02 -07002270 bt_cb(skb)->control.sar = sar;
2271 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002272
Mat Martineau94122bb2012-05-02 09:42:02 -07002273 len -= pdu_len;
2274 if (sdu_len) {
2275 sdu_len = 0;
2276 pdu_len += L2CAP_SDULEN_SIZE;
2277 }
2278
2279 if (len <= pdu_len) {
2280 sar = L2CAP_SAR_END;
2281 pdu_len = len;
2282 } else {
2283 sar = L2CAP_SAR_CONTINUE;
2284 }
2285 }
2286
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002287 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002288}
2289
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002290int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002291 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002292{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002293 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002294 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002295 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002296
2297 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002298 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002299 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002300 if (IS_ERR(skb))
2301 return PTR_ERR(skb);
2302
2303 l2cap_do_send(chan, skb);
2304 return len;
2305 }
2306
2307 switch (chan->mode) {
2308 case L2CAP_MODE_BASIC:
2309 /* Check outgoing MTU */
2310 if (len > chan->omtu)
2311 return -EMSGSIZE;
2312
2313 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002314 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002315 if (IS_ERR(skb))
2316 return PTR_ERR(skb);
2317
2318 l2cap_do_send(chan, skb);
2319 err = len;
2320 break;
2321
2322 case L2CAP_MODE_ERTM:
2323 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002324 /* Check outgoing MTU */
2325 if (len > chan->omtu) {
2326 err = -EMSGSIZE;
2327 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002328 }
2329
Mat Martineau94122bb2012-05-02 09:42:02 -07002330 __skb_queue_head_init(&seg_queue);
2331
2332 /* Do segmentation before calling in to the state machine,
2333 * since it's possible to block while waiting for memory
2334 * allocation.
2335 */
2336 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2337
2338 /* The channel could have been closed while segmenting,
2339 * check that it is still connected.
2340 */
2341 if (chan->state != BT_CONNECTED) {
2342 __skb_queue_purge(&seg_queue);
2343 err = -ENOTCONN;
2344 }
2345
2346 if (err)
2347 break;
2348
Mat Martineau37339372012-05-17 20:53:33 -07002349 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002350 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002351 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002352 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002353
Gustavo Padovand6603662012-05-21 13:58:22 -03002354 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002355
Mat Martineau94122bb2012-05-02 09:42:02 -07002356 /* If the skbs were not queued for sending, they'll still be in
2357 * seg_queue and need to be purged.
2358 */
2359 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002360 break;
2361
2362 default:
2363 BT_DBG("bad state %1.1x", chan->mode);
2364 err = -EBADFD;
2365 }
2366
2367 return err;
2368}
2369
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002370static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2371{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002372 struct l2cap_ctrl control;
2373 u16 seq;
2374
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002375 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002376
2377 memset(&control, 0, sizeof(control));
2378 control.sframe = 1;
2379 control.super = L2CAP_SUPER_SREJ;
2380
2381 for (seq = chan->expected_tx_seq; seq != txseq;
2382 seq = __next_seq(chan, seq)) {
2383 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2384 control.reqseq = seq;
2385 l2cap_send_sframe(chan, &control);
2386 l2cap_seq_list_append(&chan->srej_list, seq);
2387 }
2388 }
2389
2390 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002391}
2392
2393static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2394{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002395 struct l2cap_ctrl control;
2396
2397 BT_DBG("chan %p", chan);
2398
2399 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2400 return;
2401
2402 memset(&control, 0, sizeof(control));
2403 control.sframe = 1;
2404 control.super = L2CAP_SUPER_SREJ;
2405 control.reqseq = chan->srej_list.tail;
2406 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002407}
2408
2409static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2410{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002411 struct l2cap_ctrl control;
2412 u16 initial_head;
2413 u16 seq;
2414
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002415 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002416
2417 memset(&control, 0, sizeof(control));
2418 control.sframe = 1;
2419 control.super = L2CAP_SUPER_SREJ;
2420
2421 /* Capture initial list head to allow only one pass through the list. */
2422 initial_head = chan->srej_list.head;
2423
2424 do {
2425 seq = l2cap_seq_list_pop(&chan->srej_list);
2426 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2427 break;
2428
2429 control.reqseq = seq;
2430 l2cap_send_sframe(chan, &control);
2431 l2cap_seq_list_append(&chan->srej_list, seq);
2432 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002433}
2434
Mat Martineau608bcc62012-05-17 20:53:32 -07002435static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2436{
2437 struct sk_buff *acked_skb;
2438 u16 ackseq;
2439
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002440 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002441
2442 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2443 return;
2444
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002445 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002446 chan->expected_ack_seq, chan->unacked_frames);
2447
2448 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2449 ackseq = __next_seq(chan, ackseq)) {
2450
2451 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2452 if (acked_skb) {
2453 skb_unlink(acked_skb, &chan->tx_q);
2454 kfree_skb(acked_skb);
2455 chan->unacked_frames--;
2456 }
2457 }
2458
2459 chan->expected_ack_seq = reqseq;
2460
2461 if (chan->unacked_frames == 0)
2462 __clear_retrans_timer(chan);
2463
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002464 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002465}
2466
2467static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2468{
2469 BT_DBG("chan %p", chan);
2470
2471 chan->expected_tx_seq = chan->buffer_seq;
2472 l2cap_seq_list_clear(&chan->srej_list);
2473 skb_queue_purge(&chan->srej_q);
2474 chan->rx_state = L2CAP_RX_STATE_RECV;
2475}
2476
Gustavo Padovand6603662012-05-21 13:58:22 -03002477static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2478 struct l2cap_ctrl *control,
2479 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002480{
Mat Martineau608bcc62012-05-17 20:53:32 -07002481 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2482 event);
2483
2484 switch (event) {
2485 case L2CAP_EV_DATA_REQUEST:
2486 if (chan->tx_send_head == NULL)
2487 chan->tx_send_head = skb_peek(skbs);
2488
2489 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2490 l2cap_ertm_send(chan);
2491 break;
2492 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2493 BT_DBG("Enter LOCAL_BUSY");
2494 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2495
2496 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2497 /* The SREJ_SENT state must be aborted if we are to
2498 * enter the LOCAL_BUSY state.
2499 */
2500 l2cap_abort_rx_srej_sent(chan);
2501 }
2502
2503 l2cap_send_ack(chan);
2504
2505 break;
2506 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2507 BT_DBG("Exit LOCAL_BUSY");
2508 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2509
2510 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2511 struct l2cap_ctrl local_control;
2512
2513 memset(&local_control, 0, sizeof(local_control));
2514 local_control.sframe = 1;
2515 local_control.super = L2CAP_SUPER_RR;
2516 local_control.poll = 1;
2517 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002518 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002519
2520 chan->retry_count = 1;
2521 __set_monitor_timer(chan);
2522 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2523 }
2524 break;
2525 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2526 l2cap_process_reqseq(chan, control->reqseq);
2527 break;
2528 case L2CAP_EV_EXPLICIT_POLL:
2529 l2cap_send_rr_or_rnr(chan, 1);
2530 chan->retry_count = 1;
2531 __set_monitor_timer(chan);
2532 __clear_ack_timer(chan);
2533 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2534 break;
2535 case L2CAP_EV_RETRANS_TO:
2536 l2cap_send_rr_or_rnr(chan, 1);
2537 chan->retry_count = 1;
2538 __set_monitor_timer(chan);
2539 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2540 break;
2541 case L2CAP_EV_RECV_FBIT:
2542 /* Nothing to process */
2543 break;
2544 default:
2545 break;
2546 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002547}
2548
Gustavo Padovand6603662012-05-21 13:58:22 -03002549static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2550 struct l2cap_ctrl *control,
2551 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002552{
Mat Martineau608bcc62012-05-17 20:53:32 -07002553 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2554 event);
2555
2556 switch (event) {
2557 case L2CAP_EV_DATA_REQUEST:
2558 if (chan->tx_send_head == NULL)
2559 chan->tx_send_head = skb_peek(skbs);
2560 /* Queue data, but don't send. */
2561 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2562 break;
2563 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2564 BT_DBG("Enter LOCAL_BUSY");
2565 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2566
2567 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2568 /* The SREJ_SENT state must be aborted if we are to
2569 * enter the LOCAL_BUSY state.
2570 */
2571 l2cap_abort_rx_srej_sent(chan);
2572 }
2573
2574 l2cap_send_ack(chan);
2575
2576 break;
2577 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2578 BT_DBG("Exit LOCAL_BUSY");
2579 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2580
2581 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2582 struct l2cap_ctrl local_control;
2583 memset(&local_control, 0, sizeof(local_control));
2584 local_control.sframe = 1;
2585 local_control.super = L2CAP_SUPER_RR;
2586 local_control.poll = 1;
2587 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002588 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002589
2590 chan->retry_count = 1;
2591 __set_monitor_timer(chan);
2592 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2593 }
2594 break;
2595 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2596 l2cap_process_reqseq(chan, control->reqseq);
2597
2598 /* Fall through */
2599
2600 case L2CAP_EV_RECV_FBIT:
2601 if (control && control->final) {
2602 __clear_monitor_timer(chan);
2603 if (chan->unacked_frames > 0)
2604 __set_retrans_timer(chan);
2605 chan->retry_count = 0;
2606 chan->tx_state = L2CAP_TX_STATE_XMIT;
2607 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2608 }
2609 break;
2610 case L2CAP_EV_EXPLICIT_POLL:
2611 /* Ignore */
2612 break;
2613 case L2CAP_EV_MONITOR_TO:
2614 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2615 l2cap_send_rr_or_rnr(chan, 1);
2616 __set_monitor_timer(chan);
2617 chan->retry_count++;
2618 } else {
2619 l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
2620 }
2621 break;
2622 default:
2623 break;
2624 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002625}
2626
Gustavo Padovand6603662012-05-21 13:58:22 -03002627static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2628 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002629{
Mat Martineau608bcc62012-05-17 20:53:32 -07002630 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2631 chan, control, skbs, event, chan->tx_state);
2632
2633 switch (chan->tx_state) {
2634 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002635 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002636 break;
2637 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002638 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002639 break;
2640 default:
2641 /* Ignore event */
2642 break;
2643 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002644}
2645
Mat Martineau4b51dae92012-05-17 20:53:37 -07002646static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2647 struct l2cap_ctrl *control)
2648{
2649 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002650 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002651}
2652
Mat Martineauf80842a2012-05-17 20:53:46 -07002653static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2654 struct l2cap_ctrl *control)
2655{
2656 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002657 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002658}
2659
Linus Torvalds1da177e2005-04-16 15:20:36 -07002660/* Copy frame to all raw sockets on that connection */
2661static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2662{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002664 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002665
2666 BT_DBG("conn %p", conn);
2667
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002668 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002669
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002670 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002671 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002672 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002673 continue;
2674
2675 /* Don't send frame to the socket it came from */
2676 if (skb->sk == sk)
2677 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002678 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002679 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002680 continue;
2681
Gustavo Padovan80b98022012-05-27 22:27:51 -03002682 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002683 kfree_skb(nskb);
2684 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002685
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002686 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002687}
2688
2689/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002690static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2691 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002692{
2693 struct sk_buff *skb, **frag;
2694 struct l2cap_cmd_hdr *cmd;
2695 struct l2cap_hdr *lh;
2696 int len, count;
2697
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002698 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2699 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002700
2701 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2702 count = min_t(unsigned int, conn->mtu, len);
2703
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002704 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002705 if (!skb)
2706 return NULL;
2707
2708 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002709 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002710
2711 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002712 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002713 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002714 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002715
2716 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2717 cmd->code = code;
2718 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002719 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002720
2721 if (dlen) {
2722 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2723 memcpy(skb_put(skb, count), data, count);
2724 data += count;
2725 }
2726
2727 len -= skb->len;
2728
2729 /* Continuation fragments (no L2CAP header) */
2730 frag = &skb_shinfo(skb)->frag_list;
2731 while (len) {
2732 count = min_t(unsigned int, conn->mtu, len);
2733
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002734 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002735 if (!*frag)
2736 goto fail;
2737
2738 memcpy(skb_put(*frag, count), data, count);
2739
2740 len -= count;
2741 data += count;
2742
2743 frag = &(*frag)->next;
2744 }
2745
2746 return skb;
2747
2748fail:
2749 kfree_skb(skb);
2750 return NULL;
2751}
2752
Gustavo Padovan2d792812012-10-06 10:07:01 +01002753static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2754 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002755{
2756 struct l2cap_conf_opt *opt = *ptr;
2757 int len;
2758
2759 len = L2CAP_CONF_OPT_SIZE + opt->len;
2760 *ptr += len;
2761
2762 *type = opt->type;
2763 *olen = opt->len;
2764
2765 switch (opt->len) {
2766 case 1:
2767 *val = *((u8 *) opt->val);
2768 break;
2769
2770 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002771 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002772 break;
2773
2774 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002775 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002776 break;
2777
2778 default:
2779 *val = (unsigned long) opt->val;
2780 break;
2781 }
2782
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002783 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002784 return len;
2785}
2786
Linus Torvalds1da177e2005-04-16 15:20:36 -07002787static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2788{
2789 struct l2cap_conf_opt *opt = *ptr;
2790
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002791 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002792
2793 opt->type = type;
2794 opt->len = len;
2795
2796 switch (len) {
2797 case 1:
2798 *((u8 *) opt->val) = val;
2799 break;
2800
2801 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002802 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002803 break;
2804
2805 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002806 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002807 break;
2808
2809 default:
2810 memcpy(opt->val, (void *) val, len);
2811 break;
2812 }
2813
2814 *ptr += L2CAP_CONF_OPT_SIZE + len;
2815}
2816
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002817static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2818{
2819 struct l2cap_conf_efs efs;
2820
Szymon Janc1ec918c2011-11-16 09:32:21 +01002821 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002822 case L2CAP_MODE_ERTM:
2823 efs.id = chan->local_id;
2824 efs.stype = chan->local_stype;
2825 efs.msdu = cpu_to_le16(chan->local_msdu);
2826 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002827 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002828 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002829 break;
2830
2831 case L2CAP_MODE_STREAMING:
2832 efs.id = 1;
2833 efs.stype = L2CAP_SERV_BESTEFFORT;
2834 efs.msdu = cpu_to_le16(chan->local_msdu);
2835 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2836 efs.acc_lat = 0;
2837 efs.flush_to = 0;
2838 break;
2839
2840 default:
2841 return;
2842 }
2843
2844 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002845 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002846}
2847
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002848static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002849{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002850 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07002851 ack_timer.work);
2852 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002853
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02002854 BT_DBG("chan %p", chan);
2855
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002856 l2cap_chan_lock(chan);
2857
Mat Martineau03625202012-05-17 20:53:51 -07002858 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2859 chan->last_acked_seq);
2860
2861 if (frames_to_ack)
2862 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002863
2864 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01002865 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002866}
2867
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03002868int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002869{
Mat Martineau3c588192012-04-11 10:48:42 -07002870 int err;
2871
Mat Martineau105bdf92012-04-27 16:50:48 -07002872 chan->next_tx_seq = 0;
2873 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002874 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002875 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002876 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002877 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07002878 chan->last_acked_seq = 0;
2879 chan->sdu = NULL;
2880 chan->sdu_last_frag = NULL;
2881 chan->sdu_len = 0;
2882
Mat Martineaud34c34f2012-05-14 14:49:27 -07002883 skb_queue_head_init(&chan->tx_q);
2884
Mat Martineau08333282012-10-23 15:24:06 -07002885 chan->local_amp_id = 0;
2886 chan->move_id = 0;
2887 chan->move_state = L2CAP_MOVE_STABLE;
2888 chan->move_role = L2CAP_MOVE_ROLE_NONE;
2889
Mat Martineau105bdf92012-04-27 16:50:48 -07002890 if (chan->mode != L2CAP_MODE_ERTM)
2891 return 0;
2892
2893 chan->rx_state = L2CAP_RX_STATE_RECV;
2894 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002895
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002896 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
2897 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
2898 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002899
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03002900 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002901
Mat Martineau3c588192012-04-11 10:48:42 -07002902 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
2903 if (err < 0)
2904 return err;
2905
Mat Martineau9dc9aff2012-05-17 16:20:14 -07002906 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
2907 if (err < 0)
2908 l2cap_seq_list_free(&chan->srej_list);
2909
2910 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002911}
2912
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002913static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2914{
2915 switch (mode) {
2916 case L2CAP_MODE_STREAMING:
2917 case L2CAP_MODE_ERTM:
2918 if (l2cap_mode_supported(mode, remote_feat_mask))
2919 return mode;
2920 /* fall through */
2921 default:
2922 return L2CAP_MODE_BASIC;
2923 }
2924}
2925
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002926static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
2927{
2928 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
2929}
2930
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002931static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
2932{
2933 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
2934}
2935
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002936static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
2937{
2938 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01002939 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002940 /* use extended control field */
2941 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002942 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
2943 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002944 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002945 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002946 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
2947 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07002948 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002949}
2950
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03002951static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002954 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002955 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002956 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002957
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03002958 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002959
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002960 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002961 goto done;
2962
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002963 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002964 case L2CAP_MODE_STREAMING:
2965 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002966 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002967 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002968
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002969 if (__l2cap_efs_supported(chan))
2970 set_bit(FLAG_EFS_ENABLE, &chan->flags);
2971
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002972 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002973 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002974 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002975 break;
2976 }
2977
2978done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002979 if (chan->imtu != L2CAP_DEFAULT_MTU)
2980 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02002981
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002982 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002983 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002984 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01002985 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002986 break;
2987
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002988 rfc.mode = L2CAP_MODE_BASIC;
2989 rfc.txwin_size = 0;
2990 rfc.max_transmit = 0;
2991 rfc.retrans_timeout = 0;
2992 rfc.monitor_timeout = 0;
2993 rfc.max_pdu_size = 0;
2994
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002995 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01002996 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002997 break;
2998
2999 case L2CAP_MODE_ERTM:
3000 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003001 rfc.max_transmit = chan->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003002 rfc.retrans_timeout = 0;
3003 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003004
3005 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003006 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3007 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003008 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003009
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003010 l2cap_txwin_setup(chan);
3011
3012 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003013 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003014
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003015 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003016 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003017
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003018 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3019 l2cap_add_opt_efs(&ptr, chan);
3020
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003021 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003022 break;
3023
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003024 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01003025 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003026 chan->fcs = L2CAP_FCS_NONE;
3027 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003028 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003029
3030 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3031 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003032 chan->tx_win);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003033 break;
3034
3035 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003036 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003037 rfc.mode = L2CAP_MODE_STREAMING;
3038 rfc.txwin_size = 0;
3039 rfc.max_transmit = 0;
3040 rfc.retrans_timeout = 0;
3041 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003042
3043 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003044 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3045 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003046 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003047
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003048 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003049 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003050
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003051 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3052 l2cap_add_opt_efs(&ptr, chan);
3053
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003054 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003055 break;
3056
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003057 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01003058 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003059 chan->fcs = L2CAP_FCS_NONE;
3060 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003061 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003062 break;
3063 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003064
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003065 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003066 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003067
3068 return ptr - data;
3069}
3070
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003071static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003072{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003073 struct l2cap_conf_rsp *rsp = data;
3074 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003075 void *req = chan->conf_req;
3076 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003077 int type, hint, olen;
3078 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003079 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003080 struct l2cap_conf_efs efs;
3081 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003082 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003083 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003084 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003085
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003086 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003087
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003088 while (len >= L2CAP_CONF_OPT_SIZE) {
3089 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003090
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003091 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003092 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003093
3094 switch (type) {
3095 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003096 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003097 break;
3098
3099 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003100 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003101 break;
3102
3103 case L2CAP_CONF_QOS:
3104 break;
3105
Marcel Holtmann6464f352007-10-20 13:39:51 +02003106 case L2CAP_CONF_RFC:
3107 if (olen == sizeof(rfc))
3108 memcpy(&rfc, (void *) val, olen);
3109 break;
3110
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003111 case L2CAP_CONF_FCS:
3112 if (val == L2CAP_FCS_NONE)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003113 set_bit(CONF_NO_FCS_RECV, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003114 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003115
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003116 case L2CAP_CONF_EFS:
3117 remote_efs = 1;
3118 if (olen == sizeof(efs))
3119 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003120 break;
3121
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003122 case L2CAP_CONF_EWS:
3123 if (!enable_hs)
3124 return -ECONNREFUSED;
3125
3126 set_bit(FLAG_EXT_CTRL, &chan->flags);
3127 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003128 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003129 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003130 break;
3131
3132 default:
3133 if (hint)
3134 break;
3135
3136 result = L2CAP_CONF_UNKNOWN;
3137 *((u8 *) ptr++) = type;
3138 break;
3139 }
3140 }
3141
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003142 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003143 goto done;
3144
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003145 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003146 case L2CAP_MODE_STREAMING:
3147 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003148 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003149 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003150 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003151 break;
3152 }
3153
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003154 if (remote_efs) {
3155 if (__l2cap_efs_supported(chan))
3156 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3157 else
3158 return -ECONNREFUSED;
3159 }
3160
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003161 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003162 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003163
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003164 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003165 }
3166
3167done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003168 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003169 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003170 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003171
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003172 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003173 return -ECONNREFUSED;
3174
Gustavo Padovan2d792812012-10-06 10:07:01 +01003175 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3176 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003177 }
3178
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003179 if (result == L2CAP_CONF_SUCCESS) {
3180 /* Configure output options and let the other side know
3181 * which ones we don't like. */
3182
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003183 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3184 result = L2CAP_CONF_UNACCEPT;
3185 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003186 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003187 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003188 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003189 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003190
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003191 if (remote_efs) {
3192 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003193 efs.stype != L2CAP_SERV_NOTRAFIC &&
3194 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003195
3196 result = L2CAP_CONF_UNACCEPT;
3197
3198 if (chan->num_conf_req >= 1)
3199 return -ECONNREFUSED;
3200
3201 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003202 sizeof(efs),
3203 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003204 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003205 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003206 result = L2CAP_CONF_PENDING;
3207 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003208 }
3209 }
3210
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003211 switch (rfc.mode) {
3212 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003213 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003214 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003215 break;
3216
3217 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003218 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3219 chan->remote_tx_win = rfc.txwin_size;
3220 else
3221 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3222
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003223 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003224
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003225 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003226 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3227 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003228 rfc.max_pdu_size = cpu_to_le16(size);
3229 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003230
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003231 rfc.retrans_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003232 __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003233 rfc.monitor_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003234 __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003235
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003236 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003237
3238 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003239 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003240
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003241 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3242 chan->remote_id = efs.id;
3243 chan->remote_stype = efs.stype;
3244 chan->remote_msdu = le16_to_cpu(efs.msdu);
3245 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003246 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003247 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003248 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003249 chan->remote_sdu_itime =
3250 le32_to_cpu(efs.sdu_itime);
3251 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003252 sizeof(efs),
3253 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003254 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003255 break;
3256
3257 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003258 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003259 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3260 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003261 rfc.max_pdu_size = cpu_to_le16(size);
3262 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003263
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003264 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003265
Gustavo Padovan2d792812012-10-06 10:07:01 +01003266 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3267 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003268
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003269 break;
3270
3271 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003272 result = L2CAP_CONF_UNACCEPT;
3273
3274 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003275 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003276 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003277
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003278 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003279 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003280 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003281 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003282 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003283 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003284
3285 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003286}
3287
Gustavo Padovan2d792812012-10-06 10:07:01 +01003288static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3289 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003290{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003291 struct l2cap_conf_req *req = data;
3292 void *ptr = req->data;
3293 int type, olen;
3294 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003295 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003296 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003297
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003298 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003299
3300 while (len >= L2CAP_CONF_OPT_SIZE) {
3301 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3302
3303 switch (type) {
3304 case L2CAP_CONF_MTU:
3305 if (val < L2CAP_DEFAULT_MIN_MTU) {
3306 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003307 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003308 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003309 chan->imtu = val;
3310 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003311 break;
3312
3313 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003314 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003315 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003316 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003317 break;
3318
3319 case L2CAP_CONF_RFC:
3320 if (olen == sizeof(rfc))
3321 memcpy(&rfc, (void *)val, olen);
3322
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003323 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003324 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003325 return -ECONNREFUSED;
3326
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003327 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003328
3329 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003330 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003331 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003332
3333 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003334 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003335 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003336 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003337 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003338
3339 case L2CAP_CONF_EFS:
3340 if (olen == sizeof(efs))
3341 memcpy(&efs, (void *)val, olen);
3342
3343 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003344 efs.stype != L2CAP_SERV_NOTRAFIC &&
3345 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003346 return -ECONNREFUSED;
3347
Gustavo Padovan2d792812012-10-06 10:07:01 +01003348 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3349 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003350 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003351 }
3352 }
3353
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003354 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003355 return -ECONNREFUSED;
3356
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003357 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003358
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003359 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003360 switch (rfc.mode) {
3361 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003362 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3363 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3364 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003365 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3366 chan->ack_win = min_t(u16, chan->ack_win,
3367 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003368
3369 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3370 chan->local_msdu = le16_to_cpu(efs.msdu);
3371 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003372 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003373 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3374 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003375 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003376 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003377 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003378
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003379 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003380 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003381 }
3382 }
3383
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003384 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003385 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003386
3387 return ptr - data;
3388}
3389
Gustavo Padovan2d792812012-10-06 10:07:01 +01003390static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3391 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003392{
3393 struct l2cap_conf_rsp *rsp = data;
3394 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003395
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003396 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003397
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003398 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003399 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003400 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003401
3402 return ptr - data;
3403}
3404
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003405void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003406{
3407 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003408 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003409 u8 buf[128];
3410
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003411 rsp.scid = cpu_to_le16(chan->dcid);
3412 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003413 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3414 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo Padovan2d792812012-10-06 10:07:01 +01003415 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003416
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003417 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003418 return;
3419
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003420 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003421 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003422 chan->num_conf_req++;
3423}
3424
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003425static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003426{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003427 int type, olen;
3428 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003429 /* Use sane default values in case a misbehaving remote device
3430 * did not send an RFC or extended window size option.
3431 */
3432 u16 txwin_ext = chan->ack_win;
3433 struct l2cap_conf_rfc rfc = {
3434 .mode = chan->mode,
3435 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3436 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3437 .max_pdu_size = cpu_to_le16(chan->imtu),
3438 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3439 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003440
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003441 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003442
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003443 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003444 return;
3445
3446 while (len >= L2CAP_CONF_OPT_SIZE) {
3447 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3448
Mat Martineauc20f8e32012-07-10 05:47:07 -07003449 switch (type) {
3450 case L2CAP_CONF_RFC:
3451 if (olen == sizeof(rfc))
3452 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003453 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003454 case L2CAP_CONF_EWS:
3455 txwin_ext = val;
3456 break;
3457 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003458 }
3459
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003460 switch (rfc.mode) {
3461 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003462 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3463 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003464 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3465 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3466 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3467 else
3468 chan->ack_win = min_t(u16, chan->ack_win,
3469 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003470 break;
3471 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003472 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003473 }
3474}
3475
Gustavo Padovan2d792812012-10-06 10:07:01 +01003476static inline int l2cap_command_rej(struct l2cap_conn *conn,
3477 struct l2cap_cmd_hdr *cmd, u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003478{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003479 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003480
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003481 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003482 return 0;
3483
3484 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003485 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003486 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003487
3488 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003489 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003490
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003491 l2cap_conn_start(conn);
3492 }
3493
3494 return 0;
3495}
3496
Mat Martineau17009152012-10-23 15:24:07 -07003497static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3498 struct l2cap_cmd_hdr *cmd,
3499 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003500{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003501 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3502 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003503 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003504 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003505 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003506
3507 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003508 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003509
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003510 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003511
3512 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003513 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003514 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003515 result = L2CAP_CR_BAD_PSM;
3516 goto sendresp;
3517 }
3518
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003519 parent = pchan->sk;
3520
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003521 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003522 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003523
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003524 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003525 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003526 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003527 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003528 result = L2CAP_CR_SEC_BLOCK;
3529 goto response;
3530 }
3531
Linus Torvalds1da177e2005-04-16 15:20:36 -07003532 result = L2CAP_CR_NO_MEM;
3533
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003534 /* Check if we already have channel with that dcid */
3535 if (__l2cap_get_chan_by_dcid(conn, scid))
3536 goto response;
3537
Gustavo Padovan80b98022012-05-27 22:27:51 -03003538 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003539 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003540 goto response;
3541
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003542 sk = chan->sk;
3543
Linus Torvalds1da177e2005-04-16 15:20:36 -07003544 hci_conn_hold(conn->hcon);
3545
Linus Torvalds1da177e2005-04-16 15:20:36 -07003546 bacpy(&bt_sk(sk)->src, conn->src);
3547 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003548 chan->psm = psm;
3549 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003550 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003551
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003552 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003553
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003554 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003555
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003556 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003557
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003558 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003559
Marcel Holtmann984947d2009-02-06 23:35:19 +01003560 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003561 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003562 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003563 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003564 result = L2CAP_CR_PEND;
3565 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003566 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003567 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003568 /* Force pending result for AMP controllers.
3569 * The connection will succeed after the
3570 * physical link is up.
3571 */
3572 if (amp_id) {
3573 __l2cap_state_change(chan, BT_CONNECT2);
3574 result = L2CAP_CR_PEND;
3575 } else {
3576 __l2cap_state_change(chan, BT_CONFIG);
3577 result = L2CAP_CR_SUCCESS;
3578 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003579 status = L2CAP_CS_NO_INFO;
3580 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003581 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003582 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003583 result = L2CAP_CR_PEND;
3584 status = L2CAP_CS_AUTHEN_PEND;
3585 }
3586 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003587 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003588 result = L2CAP_CR_PEND;
3589 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003590 }
3591
Linus Torvalds1da177e2005-04-16 15:20:36 -07003592response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003593 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003594 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003595
3596sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003597 rsp.scid = cpu_to_le16(scid);
3598 rsp.dcid = cpu_to_le16(dcid);
3599 rsp.result = cpu_to_le16(result);
3600 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003601 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003602
3603 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3604 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003605 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003606
3607 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3608 conn->info_ident = l2cap_get_ident(conn);
3609
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003610 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003611
Gustavo Padovan2d792812012-10-06 10:07:01 +01003612 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3613 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003614 }
3615
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003616 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003617 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003618 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003619 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003620 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003621 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003622 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003623 }
Mat Martineau17009152012-10-23 15:24:07 -07003624
3625 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003626}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003627
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003628static int l2cap_connect_req(struct l2cap_conn *conn,
3629 struct l2cap_cmd_hdr *cmd, u8 *data)
3630{
Gustavo Padovan300229f2012-10-12 19:40:40 +08003631 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003632 return 0;
3633}
3634
Mat Martineau5909cf32012-10-23 15:24:08 -07003635static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003636 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003637{
3638 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3639 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003640 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003641 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003642 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003643
3644 scid = __le16_to_cpu(rsp->scid);
3645 dcid = __le16_to_cpu(rsp->dcid);
3646 result = __le16_to_cpu(rsp->result);
3647 status = __le16_to_cpu(rsp->status);
3648
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003649 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x",
Gustavo Padovan2d792812012-10-06 10:07:01 +01003650 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003651
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003652 mutex_lock(&conn->chan_lock);
3653
Linus Torvalds1da177e2005-04-16 15:20:36 -07003654 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003655 chan = __l2cap_get_chan_by_scid(conn, scid);
3656 if (!chan) {
3657 err = -EFAULT;
3658 goto unlock;
3659 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003660 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003661 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3662 if (!chan) {
3663 err = -EFAULT;
3664 goto unlock;
3665 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003666 }
3667
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003668 err = 0;
3669
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003670 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003671
Linus Torvalds1da177e2005-04-16 15:20:36 -07003672 switch (result) {
3673 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003674 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003675 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003676 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003677 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003678
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003679 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003680 break;
3681
Linus Torvalds1da177e2005-04-16 15:20:36 -07003682 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003683 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003684 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003685 break;
3686
3687 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003688 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003689 break;
3690
3691 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003692 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003693 break;
3694 }
3695
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003696 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003697
3698unlock:
3699 mutex_unlock(&conn->chan_lock);
3700
3701 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003702}
3703
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003704static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003705{
3706 /* FCS is enabled only in ERTM or streaming mode, if one or both
3707 * sides request it.
3708 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003709 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003710 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003711 else if (!test_bit(CONF_NO_FCS_RECV, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003712 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003713}
3714
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003715static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3716 u8 ident, u16 flags)
3717{
3718 struct l2cap_conn *conn = chan->conn;
3719
3720 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3721 flags);
3722
3723 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3724 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3725
3726 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3727 l2cap_build_conf_rsp(chan, data,
3728 L2CAP_CONF_SUCCESS, flags), data);
3729}
3730
Gustavo Padovan2d792812012-10-06 10:07:01 +01003731static inline int l2cap_config_req(struct l2cap_conn *conn,
3732 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3733 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003734{
3735 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3736 u16 dcid, flags;
3737 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003738 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003739 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003740
3741 dcid = __le16_to_cpu(req->dcid);
3742 flags = __le16_to_cpu(req->flags);
3743
3744 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3745
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003746 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003747 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003748 return -ENOENT;
3749
David S. Miller033b1142011-07-21 13:38:42 -07003750 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003751 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003752
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003753 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003754 rej.scid = cpu_to_le16(chan->scid);
3755 rej.dcid = cpu_to_le16(chan->dcid);
3756
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003757 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003758 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003759 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003760 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003761
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003762 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003763 len = cmd_len - sizeof(*req);
Dan Rosenberg7ac28812011-06-24 08:38:05 -04003764 if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003765 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003766 l2cap_build_conf_rsp(chan, rsp,
3767 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003768 goto unlock;
3769 }
3770
3771 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003772 memcpy(chan->conf_req + chan->conf_len, req->data, len);
3773 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003774
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003775 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003776 /* Incomplete config. Send empty response. */
3777 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003778 l2cap_build_conf_rsp(chan, rsp,
3779 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003780 goto unlock;
3781 }
3782
3783 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003784 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003785 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003786 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003787 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003788 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003789
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003790 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003791 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003792
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003793 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003794 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003795
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003796 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02003797 goto unlock;
3798
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003799 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003800 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003801
Mat Martineau105bdf92012-04-27 16:50:48 -07003802 if (chan->mode == L2CAP_MODE_ERTM ||
3803 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003804 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003805
Mat Martineau3c588192012-04-11 10:48:42 -07003806 if (err < 0)
3807 l2cap_send_disconn_req(chan->conn, chan, -err);
3808 else
3809 l2cap_chan_ready(chan);
3810
Marcel Holtmann876d9482007-10-20 13:35:42 +02003811 goto unlock;
3812 }
3813
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003814 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003815 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003816 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003817 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003818 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003819 }
3820
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003821 /* Got Conf Rsp PENDING from remote side and asume we sent
3822 Conf Rsp PENDING in the code above */
3823 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003824 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003825
3826 /* check compatibility */
3827
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03003828 /* Send rsp for BR/EDR channel */
3829 if (!chan->ctrl_id)
3830 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
3831 else
3832 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003833 }
3834
Linus Torvalds1da177e2005-04-16 15:20:36 -07003835unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003836 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003837 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003838}
3839
Gustavo Padovan2d792812012-10-06 10:07:01 +01003840static inline int l2cap_config_rsp(struct l2cap_conn *conn,
3841 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003842{
3843 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3844 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003845 struct l2cap_chan *chan;
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003846 int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07003847 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003848
3849 scid = __le16_to_cpu(rsp->scid);
3850 flags = __le16_to_cpu(rsp->flags);
3851 result = __le16_to_cpu(rsp->result);
3852
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003853 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
3854 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003855
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003856 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003857 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003858 return 0;
3859
3860 switch (result) {
3861 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003862 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003863 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003864 break;
3865
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003866 case L2CAP_CONF_PENDING:
3867 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
3868
3869 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3870 char buf[64];
3871
3872 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003873 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003874 if (len < 0) {
3875 l2cap_send_disconn_req(conn, chan, ECONNRESET);
3876 goto done;
3877 }
3878
3879 /* check compatibility */
3880
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03003881 if (!chan->ctrl_id)
3882 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
3883 0);
3884 else
3885 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003886 }
3887 goto done;
3888
Linus Torvalds1da177e2005-04-16 15:20:36 -07003889 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003890 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003891 char req[64];
3892
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003893 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003894 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003895 goto done;
3896 }
3897
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003898 /* throw out any old stored conf requests */
3899 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003900 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003901 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003902 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003903 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003904 goto done;
3905 }
3906
3907 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003908 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003909 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003910 if (result != L2CAP_CONF_SUCCESS)
3911 goto done;
3912 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003913 }
3914
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003915 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003916 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02003917
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003918 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003919 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003920 goto done;
3921 }
3922
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003923 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003924 goto done;
3925
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003926 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003927
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003928 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003929 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003930
Mat Martineau105bdf92012-04-27 16:50:48 -07003931 if (chan->mode == L2CAP_MODE_ERTM ||
3932 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003933 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003934
Mat Martineau3c588192012-04-11 10:48:42 -07003935 if (err < 0)
3936 l2cap_send_disconn_req(chan->conn, chan, -err);
3937 else
3938 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003939 }
3940
3941done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003942 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003943 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003944}
3945
Gustavo Padovan2d792812012-10-06 10:07:01 +01003946static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
3947 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003948{
3949 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3950 struct l2cap_disconn_rsp rsp;
3951 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003952 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003953 struct sock *sk;
3954
3955 scid = __le16_to_cpu(req->scid);
3956 dcid = __le16_to_cpu(req->dcid);
3957
3958 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3959
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003960 mutex_lock(&conn->chan_lock);
3961
3962 chan = __l2cap_get_chan_by_scid(conn, dcid);
3963 if (!chan) {
3964 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003965 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003966 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003967
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003968 l2cap_chan_lock(chan);
3969
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003970 sk = chan->sk;
3971
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003972 rsp.dcid = cpu_to_le16(chan->scid);
3973 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003974 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3975
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003976 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003977 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003978 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003979
Mat Martineau61d6ef32012-04-27 16:50:50 -07003980 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003981 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003982
3983 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003984
Gustavo Padovan80b98022012-05-27 22:27:51 -03003985 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003986 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003987
3988 mutex_unlock(&conn->chan_lock);
3989
Linus Torvalds1da177e2005-04-16 15:20:36 -07003990 return 0;
3991}
3992
Gustavo Padovan2d792812012-10-06 10:07:01 +01003993static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
3994 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003995{
3996 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3997 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003998 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003999
4000 scid = __le16_to_cpu(rsp->scid);
4001 dcid = __le16_to_cpu(rsp->dcid);
4002
4003 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4004
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004005 mutex_lock(&conn->chan_lock);
4006
4007 chan = __l2cap_get_chan_by_scid(conn, scid);
4008 if (!chan) {
4009 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004010 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004011 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004012
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004013 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004014
Mat Martineau61d6ef32012-04-27 16:50:50 -07004015 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004016 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004017
4018 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004019
Gustavo Padovan80b98022012-05-27 22:27:51 -03004020 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004021 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004022
4023 mutex_unlock(&conn->chan_lock);
4024
Linus Torvalds1da177e2005-04-16 15:20:36 -07004025 return 0;
4026}
4027
Gustavo Padovan2d792812012-10-06 10:07:01 +01004028static inline int l2cap_information_req(struct l2cap_conn *conn,
4029 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004030{
4031 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004032 u16 type;
4033
4034 type = __le16_to_cpu(req->type);
4035
4036 BT_DBG("type 0x%4.4x", type);
4037
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004038 if (type == L2CAP_IT_FEAT_MASK) {
4039 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004040 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004041 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004042 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4043 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004044 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004045 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004046 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004047 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004048 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004049 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004050
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004051 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004052 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4053 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004054 } else if (type == L2CAP_IT_FIXED_CHAN) {
4055 u8 buf[12];
4056 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004057
4058 if (enable_hs)
4059 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4060 else
4061 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4062
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004063 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4064 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004065 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004066 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4067 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004068 } else {
4069 struct l2cap_info_rsp rsp;
4070 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004071 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004072 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4073 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004074 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004075
4076 return 0;
4077}
4078
Gustavo Padovan2d792812012-10-06 10:07:01 +01004079static inline int l2cap_information_rsp(struct l2cap_conn *conn,
4080 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004081{
4082 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4083 u16 type, result;
4084
4085 type = __le16_to_cpu(rsp->type);
4086 result = __le16_to_cpu(rsp->result);
4087
4088 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4089
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004090 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4091 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004092 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004093 return 0;
4094
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004095 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004096
Ville Tervoadb08ed2010-08-04 09:43:33 +03004097 if (result != L2CAP_IR_SUCCESS) {
4098 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4099 conn->info_ident = 0;
4100
4101 l2cap_conn_start(conn);
4102
4103 return 0;
4104 }
4105
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004106 switch (type) {
4107 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004108 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004109
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004110 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004111 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004112 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004113
4114 conn->info_ident = l2cap_get_ident(conn);
4115
4116 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004117 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004118 } else {
4119 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4120 conn->info_ident = 0;
4121
4122 l2cap_conn_start(conn);
4123 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004124 break;
4125
4126 case L2CAP_IT_FIXED_CHAN:
4127 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004128 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004129 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004130
4131 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004132 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004133 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004134
Linus Torvalds1da177e2005-04-16 15:20:36 -07004135 return 0;
4136}
4137
Mat Martineau17009152012-10-23 15:24:07 -07004138static int l2cap_create_channel_req(struct l2cap_conn *conn,
4139 struct l2cap_cmd_hdr *cmd,
4140 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004141{
4142 struct l2cap_create_chan_req *req = data;
Mat Martineau17009152012-10-23 15:24:07 -07004143 struct l2cap_chan *chan;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004144 u16 psm, scid;
4145
4146 if (cmd_len != sizeof(*req))
4147 return -EPROTO;
4148
4149 if (!enable_hs)
4150 return -EINVAL;
4151
4152 psm = le16_to_cpu(req->psm);
4153 scid = le16_to_cpu(req->scid);
4154
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004155 BT_DBG("psm 0x%2.2x, scid 0x%4.4x, amp_id %d", psm, scid, req->amp_id);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004156
Mat Martineau17009152012-10-23 15:24:07 -07004157 if (req->amp_id) {
4158 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004159
Mat Martineau17009152012-10-23 15:24:07 -07004160 /* Validate AMP controller id */
4161 hdev = hci_dev_get(req->amp_id);
4162 if (!hdev || hdev->dev_type != HCI_AMP ||
4163 !test_bit(HCI_UP, &hdev->flags)) {
4164 struct l2cap_create_chan_rsp rsp;
4165
4166 rsp.dcid = 0;
4167 rsp.scid = cpu_to_le16(scid);
4168 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4169 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4170
4171 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4172 sizeof(rsp), &rsp);
4173
4174 if (hdev)
4175 hci_dev_put(hdev);
4176
4177 return 0;
4178 }
4179
4180 hci_dev_put(hdev);
4181 }
4182
4183 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4184 req->amp_id);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004185
4186 return 0;
4187}
4188
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004189static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004190 u16 icid, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004191{
4192 struct l2cap_move_chan_rsp rsp;
4193
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004194 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004195
4196 rsp.icid = cpu_to_le16(icid);
4197 rsp.result = cpu_to_le16(result);
4198
4199 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp);
4200}
4201
Mat Martineau5b155ef2012-10-23 15:24:14 -07004202static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004203{
4204 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004205
Mat Martineau5b155ef2012-10-23 15:24:14 -07004206 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004207
Mat Martineau5b155ef2012-10-23 15:24:14 -07004208 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004209
Mat Martineau5b155ef2012-10-23 15:24:14 -07004210 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004211 cfm.result = cpu_to_le16(result);
4212
Mat Martineau5b155ef2012-10-23 15:24:14 -07004213 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4214 sizeof(cfm), &cfm);
4215
4216 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4217}
4218
4219static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4220{
4221 struct l2cap_move_chan_cfm cfm;
4222
4223 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4224
4225 cfm.icid = cpu_to_le16(icid);
4226 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4227
4228 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4229 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004230}
4231
4232static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004233 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004234{
4235 struct l2cap_move_chan_cfm_rsp rsp;
4236
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004237 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004238
4239 rsp.icid = cpu_to_le16(icid);
4240 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4241}
4242
Mat Martineau5f3847a2012-10-23 15:24:12 -07004243static void __release_logical_link(struct l2cap_chan *chan)
4244{
4245 chan->hs_hchan = NULL;
4246 chan->hs_hcon = NULL;
4247
4248 /* Placeholder - release the logical link */
4249}
4250
Mat Martineau5b155ef2012-10-23 15:24:14 -07004251static void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4252 u8 status)
4253{
4254 /* Placeholder */
4255 return;
4256}
4257
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004258static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004259 struct l2cap_cmd_hdr *cmd,
4260 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004261{
4262 struct l2cap_move_chan_req *req = data;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004263 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004264 u16 icid = 0;
4265 u16 result = L2CAP_MR_NOT_ALLOWED;
4266
4267 if (cmd_len != sizeof(*req))
4268 return -EPROTO;
4269
4270 icid = le16_to_cpu(req->icid);
4271
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004272 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004273
4274 if (!enable_hs)
4275 return -EINVAL;
4276
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004277 chan = l2cap_get_chan_by_dcid(conn, icid);
4278 if (!chan) {
4279 l2cap_send_move_chan_rsp(conn, cmd->ident, icid,
4280 L2CAP_MR_NOT_ALLOWED);
4281 return 0;
4282 }
4283
4284 if (chan->scid < L2CAP_CID_DYN_START ||
4285 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4286 (chan->mode != L2CAP_MODE_ERTM &&
4287 chan->mode != L2CAP_MODE_STREAMING)) {
4288 result = L2CAP_MR_NOT_ALLOWED;
4289 goto send_move_response;
4290 }
4291
4292 if (chan->local_amp_id == req->dest_amp_id) {
4293 result = L2CAP_MR_SAME_ID;
4294 goto send_move_response;
4295 }
4296
4297 if (req->dest_amp_id) {
4298 struct hci_dev *hdev;
4299 hdev = hci_dev_get(req->dest_amp_id);
4300 if (!hdev || hdev->dev_type != HCI_AMP ||
4301 !test_bit(HCI_UP, &hdev->flags)) {
4302 if (hdev)
4303 hci_dev_put(hdev);
4304
4305 result = L2CAP_MR_BAD_ID;
4306 goto send_move_response;
4307 }
4308 hci_dev_put(hdev);
4309 }
4310
4311 /* Detect a move collision. Only send a collision response
4312 * if this side has "lost", otherwise proceed with the move.
4313 * The winner has the larger bd_addr.
4314 */
4315 if ((__chan_is_moving(chan) ||
4316 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
4317 bacmp(conn->src, conn->dst) > 0) {
4318 result = L2CAP_MR_COLLISION;
4319 goto send_move_response;
4320 }
4321
4322 chan->ident = cmd->ident;
4323 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4324 l2cap_move_setup(chan);
4325 chan->move_id = req->dest_amp_id;
4326 icid = chan->dcid;
4327
4328 if (!req->dest_amp_id) {
4329 /* Moving to BR/EDR */
4330 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4331 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4332 result = L2CAP_MR_PEND;
4333 } else {
4334 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4335 result = L2CAP_MR_SUCCESS;
4336 }
4337 } else {
4338 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4339 /* Placeholder - uncomment when amp functions are available */
4340 /*amp_accept_physical(chan, req->dest_amp_id);*/
4341 result = L2CAP_MR_PEND;
4342 }
4343
4344send_move_response:
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004345 l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result);
4346
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004347 l2cap_chan_unlock(chan);
4348
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004349 return 0;
4350}
4351
Mat Martineau5b155ef2012-10-23 15:24:14 -07004352static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4353{
4354 struct l2cap_chan *chan;
4355 struct hci_chan *hchan = NULL;
4356
4357 chan = l2cap_get_chan_by_scid(conn, icid);
4358 if (!chan) {
4359 l2cap_send_move_chan_cfm_icid(conn, icid);
4360 return;
4361 }
4362
4363 __clear_chan_timer(chan);
4364 if (result == L2CAP_MR_PEND)
4365 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4366
4367 switch (chan->move_state) {
4368 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4369 /* Move confirm will be sent when logical link
4370 * is complete.
4371 */
4372 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4373 break;
4374 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4375 if (result == L2CAP_MR_PEND) {
4376 break;
4377 } else if (test_bit(CONN_LOCAL_BUSY,
4378 &chan->conn_state)) {
4379 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4380 } else {
4381 /* Logical link is up or moving to BR/EDR,
4382 * proceed with move
4383 */
4384 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4385 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4386 }
4387 break;
4388 case L2CAP_MOVE_WAIT_RSP:
4389 /* Moving to AMP */
4390 if (result == L2CAP_MR_SUCCESS) {
4391 /* Remote is ready, send confirm immediately
4392 * after logical link is ready
4393 */
4394 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4395 } else {
4396 /* Both logical link and move success
4397 * are required to confirm
4398 */
4399 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4400 }
4401
4402 /* Placeholder - get hci_chan for logical link */
4403 if (!hchan) {
4404 /* Logical link not available */
4405 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4406 break;
4407 }
4408
4409 /* If the logical link is not yet connected, do not
4410 * send confirmation.
4411 */
4412 if (hchan->state != BT_CONNECTED)
4413 break;
4414
4415 /* Logical link is already ready to go */
4416
4417 chan->hs_hcon = hchan->conn;
4418 chan->hs_hcon->l2cap_data = chan->conn;
4419
4420 if (result == L2CAP_MR_SUCCESS) {
4421 /* Can confirm now */
4422 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4423 } else {
4424 /* Now only need move success
4425 * to confirm
4426 */
4427 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4428 }
4429
4430 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4431 break;
4432 default:
4433 /* Any other amp move state means the move failed. */
4434 chan->move_id = chan->local_amp_id;
4435 l2cap_move_done(chan);
4436 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4437 }
4438
4439 l2cap_chan_unlock(chan);
4440}
4441
4442static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
4443 u16 result)
4444{
4445 struct l2cap_chan *chan;
4446
4447 chan = l2cap_get_chan_by_ident(conn, ident);
4448 if (!chan) {
4449 /* Could not locate channel, icid is best guess */
4450 l2cap_send_move_chan_cfm_icid(conn, icid);
4451 return;
4452 }
4453
4454 __clear_chan_timer(chan);
4455
4456 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4457 if (result == L2CAP_MR_COLLISION) {
4458 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4459 } else {
4460 /* Cleanup - cancel move */
4461 chan->move_id = chan->local_amp_id;
4462 l2cap_move_done(chan);
4463 }
4464 }
4465
4466 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4467
4468 l2cap_chan_unlock(chan);
4469}
4470
4471static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
4472 struct l2cap_cmd_hdr *cmd,
4473 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004474{
4475 struct l2cap_move_chan_rsp *rsp = data;
4476 u16 icid, result;
4477
4478 if (cmd_len != sizeof(*rsp))
4479 return -EPROTO;
4480
4481 icid = le16_to_cpu(rsp->icid);
4482 result = le16_to_cpu(rsp->result);
4483
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004484 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004485
Mat Martineau5b155ef2012-10-23 15:24:14 -07004486 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
4487 l2cap_move_continue(conn, icid, result);
4488 else
4489 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004490
4491 return 0;
4492}
4493
Mat Martineau5f3847a2012-10-23 15:24:12 -07004494static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
4495 struct l2cap_cmd_hdr *cmd,
4496 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004497{
4498 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07004499 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004500 u16 icid, result;
4501
4502 if (cmd_len != sizeof(*cfm))
4503 return -EPROTO;
4504
4505 icid = le16_to_cpu(cfm->icid);
4506 result = le16_to_cpu(cfm->result);
4507
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004508 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004509
Mat Martineau5f3847a2012-10-23 15:24:12 -07004510 chan = l2cap_get_chan_by_dcid(conn, icid);
4511 if (!chan) {
4512 /* Spec requires a response even if the icid was not found */
4513 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4514 return 0;
4515 }
4516
4517 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
4518 if (result == L2CAP_MC_CONFIRMED) {
4519 chan->local_amp_id = chan->move_id;
4520 if (!chan->local_amp_id)
4521 __release_logical_link(chan);
4522 } else {
4523 chan->move_id = chan->local_amp_id;
4524 }
4525
4526 l2cap_move_done(chan);
4527 }
4528
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004529 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4530
Mat Martineau5f3847a2012-10-23 15:24:12 -07004531 l2cap_chan_unlock(chan);
4532
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004533 return 0;
4534}
4535
4536static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004537 struct l2cap_cmd_hdr *cmd,
4538 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004539{
4540 struct l2cap_move_chan_cfm_rsp *rsp = data;
4541 u16 icid;
4542
4543 if (cmd_len != sizeof(*rsp))
4544 return -EPROTO;
4545
4546 icid = le16_to_cpu(rsp->icid);
4547
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004548 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004549
4550 return 0;
4551}
4552
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004553static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004554 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02004555{
4556 u16 max_latency;
4557
4558 if (min > max || min < 6 || max > 3200)
4559 return -EINVAL;
4560
4561 if (to_multiplier < 10 || to_multiplier > 3200)
4562 return -EINVAL;
4563
4564 if (max >= to_multiplier * 8)
4565 return -EINVAL;
4566
4567 max_latency = (to_multiplier * 8 / max) - 1;
4568 if (latency > 499 || latency > max_latency)
4569 return -EINVAL;
4570
4571 return 0;
4572}
4573
4574static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004575 struct l2cap_cmd_hdr *cmd,
4576 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02004577{
4578 struct hci_conn *hcon = conn->hcon;
4579 struct l2cap_conn_param_update_req *req;
4580 struct l2cap_conn_param_update_rsp rsp;
4581 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004582 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02004583
4584 if (!(hcon->link_mode & HCI_LM_MASTER))
4585 return -EINVAL;
4586
4587 cmd_len = __le16_to_cpu(cmd->len);
4588 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
4589 return -EPROTO;
4590
4591 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004592 min = __le16_to_cpu(req->min);
4593 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02004594 latency = __le16_to_cpu(req->latency);
4595 to_multiplier = __le16_to_cpu(req->to_multiplier);
4596
4597 BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
Gustavo Padovan2d792812012-10-06 10:07:01 +01004598 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02004599
4600 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004601
4602 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
4603 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004604 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004605 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004606 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004607
4608 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004609 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02004610
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004611 if (!err)
4612 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
4613
Claudio Takahaside731152011-02-11 19:28:55 -02004614 return 0;
4615}
4616
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004617static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004618 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4619 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004620{
4621 int err = 0;
4622
4623 switch (cmd->code) {
4624 case L2CAP_COMMAND_REJ:
4625 l2cap_command_rej(conn, cmd, data);
4626 break;
4627
4628 case L2CAP_CONN_REQ:
4629 err = l2cap_connect_req(conn, cmd, data);
4630 break;
4631
4632 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03004633 case L2CAP_CREATE_CHAN_RSP:
Mat Martineau5909cf32012-10-23 15:24:08 -07004634 err = l2cap_connect_create_rsp(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004635 break;
4636
4637 case L2CAP_CONF_REQ:
4638 err = l2cap_config_req(conn, cmd, cmd_len, data);
4639 break;
4640
4641 case L2CAP_CONF_RSP:
4642 err = l2cap_config_rsp(conn, cmd, data);
4643 break;
4644
4645 case L2CAP_DISCONN_REQ:
4646 err = l2cap_disconnect_req(conn, cmd, data);
4647 break;
4648
4649 case L2CAP_DISCONN_RSP:
4650 err = l2cap_disconnect_rsp(conn, cmd, data);
4651 break;
4652
4653 case L2CAP_ECHO_REQ:
4654 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
4655 break;
4656
4657 case L2CAP_ECHO_RSP:
4658 break;
4659
4660 case L2CAP_INFO_REQ:
4661 err = l2cap_information_req(conn, cmd, data);
4662 break;
4663
4664 case L2CAP_INFO_RSP:
4665 err = l2cap_information_rsp(conn, cmd, data);
4666 break;
4667
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004668 case L2CAP_CREATE_CHAN_REQ:
4669 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
4670 break;
4671
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004672 case L2CAP_MOVE_CHAN_REQ:
4673 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
4674 break;
4675
4676 case L2CAP_MOVE_CHAN_RSP:
4677 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
4678 break;
4679
4680 case L2CAP_MOVE_CHAN_CFM:
4681 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
4682 break;
4683
4684 case L2CAP_MOVE_CHAN_CFM_RSP:
4685 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
4686 break;
4687
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004688 default:
4689 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
4690 err = -EINVAL;
4691 break;
4692 }
4693
4694 return err;
4695}
4696
4697static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004698 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004699{
4700 switch (cmd->code) {
4701 case L2CAP_COMMAND_REJ:
4702 return 0;
4703
4704 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02004705 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004706
4707 case L2CAP_CONN_PARAM_UPDATE_RSP:
4708 return 0;
4709
4710 default:
4711 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
4712 return -EINVAL;
4713 }
4714}
4715
4716static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004717 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004718{
4719 u8 *data = skb->data;
4720 int len = skb->len;
4721 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004722 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004723
4724 l2cap_raw_recv(conn, skb);
4725
4726 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07004727 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004728 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
4729 data += L2CAP_CMD_HDR_SIZE;
4730 len -= L2CAP_CMD_HDR_SIZE;
4731
Al Viro88219a02007-07-29 00:17:25 -07004732 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004733
Gustavo Padovan2d792812012-10-06 10:07:01 +01004734 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
4735 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004736
Al Viro88219a02007-07-29 00:17:25 -07004737 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004738 BT_DBG("corrupted command");
4739 break;
4740 }
4741
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004742 if (conn->hcon->type == LE_LINK)
4743 err = l2cap_le_sig_cmd(conn, &cmd, data);
4744 else
4745 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004746
4747 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004748 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03004749
4750 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004751
4752 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004753 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004754 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
4755 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004756 }
4757
Al Viro88219a02007-07-29 00:17:25 -07004758 data += cmd_len;
4759 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004760 }
4761
4762 kfree_skb(skb);
4763}
4764
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004765static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004766{
4767 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03004768 int hdr_size;
4769
4770 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
4771 hdr_size = L2CAP_EXT_HDR_SIZE;
4772 else
4773 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004774
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004775 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004776 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004777 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
4778 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
4779
4780 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03004781 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004782 }
4783 return 0;
4784}
4785
Mat Martineau6ea00482012-05-17 20:53:52 -07004786static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004787{
Mat Martineaue31f7632012-05-17 20:53:41 -07004788 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004789
Mat Martineaue31f7632012-05-17 20:53:41 -07004790 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004791
Mat Martineaue31f7632012-05-17 20:53:41 -07004792 memset(&control, 0, sizeof(control));
4793 control.sframe = 1;
4794 control.final = 1;
4795 control.reqseq = chan->buffer_seq;
4796 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004797
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004798 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07004799 control.super = L2CAP_SUPER_RNR;
4800 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004801 }
4802
Mat Martineaue31f7632012-05-17 20:53:41 -07004803 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
4804 chan->unacked_frames > 0)
4805 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004806
Mat Martineaue31f7632012-05-17 20:53:41 -07004807 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03004808 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004809
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004810 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07004811 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
4812 /* F-bit wasn't sent in an s-frame or i-frame yet, so
4813 * send it now.
4814 */
4815 control.super = L2CAP_SUPER_RR;
4816 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004817 }
4818}
4819
Gustavo Padovan2d792812012-10-06 10:07:01 +01004820static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
4821 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004822{
Mat Martineau84084a32011-07-22 14:54:00 -07004823 /* skb->len reflects data in skb as well as all fragments
4824 * skb->data_len reflects only data in fragments
4825 */
4826 if (!skb_has_frag_list(skb))
4827 skb_shinfo(skb)->frag_list = new_frag;
4828
4829 new_frag->next = NULL;
4830
4831 (*last_frag)->next = new_frag;
4832 *last_frag = new_frag;
4833
4834 skb->len += new_frag->len;
4835 skb->data_len += new_frag->len;
4836 skb->truesize += new_frag->truesize;
4837}
4838
Mat Martineau4b51dae92012-05-17 20:53:37 -07004839static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
4840 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07004841{
4842 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004843
Mat Martineau4b51dae92012-05-17 20:53:37 -07004844 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004845 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07004846 if (chan->sdu)
4847 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004848
Gustavo Padovan80b98022012-05-27 22:27:51 -03004849 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07004850 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004851
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004852 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07004853 if (chan->sdu)
4854 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004855
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004856 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004857 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004858
Mat Martineau84084a32011-07-22 14:54:00 -07004859 if (chan->sdu_len > chan->imtu) {
4860 err = -EMSGSIZE;
4861 break;
4862 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004863
Mat Martineau84084a32011-07-22 14:54:00 -07004864 if (skb->len >= chan->sdu_len)
4865 break;
4866
4867 chan->sdu = skb;
4868 chan->sdu_last_frag = skb;
4869
4870 skb = NULL;
4871 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004872 break;
4873
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004874 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004875 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004876 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004877
Mat Martineau84084a32011-07-22 14:54:00 -07004878 append_skb_frag(chan->sdu, skb,
4879 &chan->sdu_last_frag);
4880 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004881
Mat Martineau84084a32011-07-22 14:54:00 -07004882 if (chan->sdu->len >= chan->sdu_len)
4883 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004884
Mat Martineau84084a32011-07-22 14:54:00 -07004885 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004886 break;
4887
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004888 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004889 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004890 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004891
Mat Martineau84084a32011-07-22 14:54:00 -07004892 append_skb_frag(chan->sdu, skb,
4893 &chan->sdu_last_frag);
4894 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004895
Mat Martineau84084a32011-07-22 14:54:00 -07004896 if (chan->sdu->len != chan->sdu_len)
4897 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004898
Gustavo Padovan80b98022012-05-27 22:27:51 -03004899 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004900
Mat Martineau84084a32011-07-22 14:54:00 -07004901 if (!err) {
4902 /* Reassembly complete */
4903 chan->sdu = NULL;
4904 chan->sdu_last_frag = NULL;
4905 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004906 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004907 break;
4908 }
4909
Mat Martineau84084a32011-07-22 14:54:00 -07004910 if (err) {
4911 kfree_skb(skb);
4912 kfree_skb(chan->sdu);
4913 chan->sdu = NULL;
4914 chan->sdu_last_frag = NULL;
4915 chan->sdu_len = 0;
4916 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004917
Mat Martineau84084a32011-07-22 14:54:00 -07004918 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004919}
4920
Mat Martineau32b32732012-10-23 15:24:11 -07004921static int l2cap_resegment(struct l2cap_chan *chan)
4922{
4923 /* Placeholder */
4924 return 0;
4925}
4926
Mat Martineaue3281402011-07-07 09:39:02 -07004927void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03004928{
Mat Martineau61aa4f52012-05-17 20:53:40 -07004929 u8 event;
4930
4931 if (chan->mode != L2CAP_MODE_ERTM)
4932 return;
4933
4934 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03004935 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004936}
4937
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004938static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
4939{
Mat Martineau63838722012-05-17 20:53:45 -07004940 int err = 0;
4941 /* Pass sequential frames to l2cap_reassemble_sdu()
4942 * until a gap is encountered.
4943 */
4944
4945 BT_DBG("chan %p", chan);
4946
4947 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4948 struct sk_buff *skb;
4949 BT_DBG("Searching for skb with txseq %d (queue len %d)",
4950 chan->buffer_seq, skb_queue_len(&chan->srej_q));
4951
4952 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
4953
4954 if (!skb)
4955 break;
4956
4957 skb_unlink(skb, &chan->srej_q);
4958 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
4959 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
4960 if (err)
4961 break;
4962 }
4963
4964 if (skb_queue_empty(&chan->srej_q)) {
4965 chan->rx_state = L2CAP_RX_STATE_RECV;
4966 l2cap_send_ack(chan);
4967 }
4968
4969 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004970}
4971
4972static void l2cap_handle_srej(struct l2cap_chan *chan,
4973 struct l2cap_ctrl *control)
4974{
Mat Martineauf80842a2012-05-17 20:53:46 -07004975 struct sk_buff *skb;
4976
4977 BT_DBG("chan %p, control %p", chan, control);
4978
4979 if (control->reqseq == chan->next_tx_seq) {
4980 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4981 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4982 return;
4983 }
4984
4985 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4986
4987 if (skb == NULL) {
4988 BT_DBG("Seq %d not available for retransmission",
4989 control->reqseq);
4990 return;
4991 }
4992
4993 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
4994 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4995 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4996 return;
4997 }
4998
4999 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5000
5001 if (control->poll) {
5002 l2cap_pass_to_tx(chan, control);
5003
5004 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5005 l2cap_retransmit(chan, control);
5006 l2cap_ertm_send(chan);
5007
5008 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5009 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5010 chan->srej_save_reqseq = control->reqseq;
5011 }
5012 } else {
5013 l2cap_pass_to_tx_fbit(chan, control);
5014
5015 if (control->final) {
5016 if (chan->srej_save_reqseq != control->reqseq ||
5017 !test_and_clear_bit(CONN_SREJ_ACT,
5018 &chan->conn_state))
5019 l2cap_retransmit(chan, control);
5020 } else {
5021 l2cap_retransmit(chan, control);
5022 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5023 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5024 chan->srej_save_reqseq = control->reqseq;
5025 }
5026 }
5027 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005028}
5029
5030static void l2cap_handle_rej(struct l2cap_chan *chan,
5031 struct l2cap_ctrl *control)
5032{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005033 struct sk_buff *skb;
5034
5035 BT_DBG("chan %p, control %p", chan, control);
5036
5037 if (control->reqseq == chan->next_tx_seq) {
5038 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
5039 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5040 return;
5041 }
5042
5043 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5044
5045 if (chan->max_tx && skb &&
5046 bt_cb(skb)->control.retries >= chan->max_tx) {
5047 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
5048 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5049 return;
5050 }
5051
5052 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5053
5054 l2cap_pass_to_tx(chan, control);
5055
5056 if (control->final) {
5057 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5058 l2cap_retransmit_all(chan, control);
5059 } else {
5060 l2cap_retransmit_all(chan, control);
5061 l2cap_ertm_send(chan);
5062 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5063 set_bit(CONN_REJ_ACT, &chan->conn_state);
5064 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005065}
5066
Mat Martineau4b51dae92012-05-17 20:53:37 -07005067static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5068{
5069 BT_DBG("chan %p, txseq %d", chan, txseq);
5070
5071 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5072 chan->expected_tx_seq);
5073
5074 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5075 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005076 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005077 /* See notes below regarding "double poll" and
5078 * invalid packets.
5079 */
5080 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5081 BT_DBG("Invalid/Ignore - after SREJ");
5082 return L2CAP_TXSEQ_INVALID_IGNORE;
5083 } else {
5084 BT_DBG("Invalid - in window after SREJ sent");
5085 return L2CAP_TXSEQ_INVALID;
5086 }
5087 }
5088
5089 if (chan->srej_list.head == txseq) {
5090 BT_DBG("Expected SREJ");
5091 return L2CAP_TXSEQ_EXPECTED_SREJ;
5092 }
5093
5094 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5095 BT_DBG("Duplicate SREJ - txseq already stored");
5096 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5097 }
5098
5099 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5100 BT_DBG("Unexpected SREJ - not requested");
5101 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5102 }
5103 }
5104
5105 if (chan->expected_tx_seq == txseq) {
5106 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5107 chan->tx_win) {
5108 BT_DBG("Invalid - txseq outside tx window");
5109 return L2CAP_TXSEQ_INVALID;
5110 } else {
5111 BT_DBG("Expected");
5112 return L2CAP_TXSEQ_EXPECTED;
5113 }
5114 }
5115
5116 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005117 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005118 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5119 return L2CAP_TXSEQ_DUPLICATE;
5120 }
5121
5122 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5123 /* A source of invalid packets is a "double poll" condition,
5124 * where delays cause us to send multiple poll packets. If
5125 * the remote stack receives and processes both polls,
5126 * sequence numbers can wrap around in such a way that a
5127 * resent frame has a sequence number that looks like new data
5128 * with a sequence gap. This would trigger an erroneous SREJ
5129 * request.
5130 *
5131 * Fortunately, this is impossible with a tx window that's
5132 * less than half of the maximum sequence number, which allows
5133 * invalid frames to be safely ignored.
5134 *
5135 * With tx window sizes greater than half of the tx window
5136 * maximum, the frame is invalid and cannot be ignored. This
5137 * causes a disconnect.
5138 */
5139
5140 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5141 BT_DBG("Invalid/Ignore - txseq outside tx window");
5142 return L2CAP_TXSEQ_INVALID_IGNORE;
5143 } else {
5144 BT_DBG("Invalid - txseq outside tx window");
5145 return L2CAP_TXSEQ_INVALID;
5146 }
5147 } else {
5148 BT_DBG("Unexpected - txseq indicates missing frames");
5149 return L2CAP_TXSEQ_UNEXPECTED;
5150 }
5151}
5152
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005153static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5154 struct l2cap_ctrl *control,
5155 struct sk_buff *skb, u8 event)
5156{
5157 int err = 0;
5158 bool skb_in_use = 0;
5159
5160 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5161 event);
5162
5163 switch (event) {
5164 case L2CAP_EV_RECV_IFRAME:
5165 switch (l2cap_classify_txseq(chan, control->txseq)) {
5166 case L2CAP_TXSEQ_EXPECTED:
5167 l2cap_pass_to_tx(chan, control);
5168
5169 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5170 BT_DBG("Busy, discarding expected seq %d",
5171 control->txseq);
5172 break;
5173 }
5174
5175 chan->expected_tx_seq = __next_seq(chan,
5176 control->txseq);
5177
5178 chan->buffer_seq = chan->expected_tx_seq;
5179 skb_in_use = 1;
5180
5181 err = l2cap_reassemble_sdu(chan, skb, control);
5182 if (err)
5183 break;
5184
5185 if (control->final) {
5186 if (!test_and_clear_bit(CONN_REJ_ACT,
5187 &chan->conn_state)) {
5188 control->final = 0;
5189 l2cap_retransmit_all(chan, control);
5190 l2cap_ertm_send(chan);
5191 }
5192 }
5193
5194 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5195 l2cap_send_ack(chan);
5196 break;
5197 case L2CAP_TXSEQ_UNEXPECTED:
5198 l2cap_pass_to_tx(chan, control);
5199
5200 /* Can't issue SREJ frames in the local busy state.
5201 * Drop this frame, it will be seen as missing
5202 * when local busy is exited.
5203 */
5204 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5205 BT_DBG("Busy, discarding unexpected seq %d",
5206 control->txseq);
5207 break;
5208 }
5209
5210 /* There was a gap in the sequence, so an SREJ
5211 * must be sent for each missing frame. The
5212 * current frame is stored for later use.
5213 */
5214 skb_queue_tail(&chan->srej_q, skb);
5215 skb_in_use = 1;
5216 BT_DBG("Queued %p (queue len %d)", skb,
5217 skb_queue_len(&chan->srej_q));
5218
5219 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5220 l2cap_seq_list_clear(&chan->srej_list);
5221 l2cap_send_srej(chan, control->txseq);
5222
5223 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5224 break;
5225 case L2CAP_TXSEQ_DUPLICATE:
5226 l2cap_pass_to_tx(chan, control);
5227 break;
5228 case L2CAP_TXSEQ_INVALID_IGNORE:
5229 break;
5230 case L2CAP_TXSEQ_INVALID:
5231 default:
5232 l2cap_send_disconn_req(chan->conn, chan,
5233 ECONNRESET);
5234 break;
5235 }
5236 break;
5237 case L2CAP_EV_RECV_RR:
5238 l2cap_pass_to_tx(chan, control);
5239 if (control->final) {
5240 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5241
5242 if (!test_and_clear_bit(CONN_REJ_ACT,
5243 &chan->conn_state)) {
5244 control->final = 0;
5245 l2cap_retransmit_all(chan, control);
5246 }
5247
5248 l2cap_ertm_send(chan);
5249 } else if (control->poll) {
5250 l2cap_send_i_or_rr_or_rnr(chan);
5251 } else {
5252 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5253 &chan->conn_state) &&
5254 chan->unacked_frames)
5255 __set_retrans_timer(chan);
5256
5257 l2cap_ertm_send(chan);
5258 }
5259 break;
5260 case L2CAP_EV_RECV_RNR:
5261 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5262 l2cap_pass_to_tx(chan, control);
5263 if (control && control->poll) {
5264 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5265 l2cap_send_rr_or_rnr(chan, 0);
5266 }
5267 __clear_retrans_timer(chan);
5268 l2cap_seq_list_clear(&chan->retrans_list);
5269 break;
5270 case L2CAP_EV_RECV_REJ:
5271 l2cap_handle_rej(chan, control);
5272 break;
5273 case L2CAP_EV_RECV_SREJ:
5274 l2cap_handle_srej(chan, control);
5275 break;
5276 default:
5277 break;
5278 }
5279
5280 if (skb && !skb_in_use) {
5281 BT_DBG("Freeing %p", skb);
5282 kfree_skb(skb);
5283 }
5284
5285 return err;
5286}
5287
5288static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5289 struct l2cap_ctrl *control,
5290 struct sk_buff *skb, u8 event)
5291{
5292 int err = 0;
5293 u16 txseq = control->txseq;
5294 bool skb_in_use = 0;
5295
5296 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5297 event);
5298
5299 switch (event) {
5300 case L2CAP_EV_RECV_IFRAME:
5301 switch (l2cap_classify_txseq(chan, txseq)) {
5302 case L2CAP_TXSEQ_EXPECTED:
5303 /* Keep frame for reassembly later */
5304 l2cap_pass_to_tx(chan, control);
5305 skb_queue_tail(&chan->srej_q, skb);
5306 skb_in_use = 1;
5307 BT_DBG("Queued %p (queue len %d)", skb,
5308 skb_queue_len(&chan->srej_q));
5309
5310 chan->expected_tx_seq = __next_seq(chan, txseq);
5311 break;
5312 case L2CAP_TXSEQ_EXPECTED_SREJ:
5313 l2cap_seq_list_pop(&chan->srej_list);
5314
5315 l2cap_pass_to_tx(chan, control);
5316 skb_queue_tail(&chan->srej_q, skb);
5317 skb_in_use = 1;
5318 BT_DBG("Queued %p (queue len %d)", skb,
5319 skb_queue_len(&chan->srej_q));
5320
5321 err = l2cap_rx_queued_iframes(chan);
5322 if (err)
5323 break;
5324
5325 break;
5326 case L2CAP_TXSEQ_UNEXPECTED:
5327 /* Got a frame that can't be reassembled yet.
5328 * Save it for later, and send SREJs to cover
5329 * the missing frames.
5330 */
5331 skb_queue_tail(&chan->srej_q, skb);
5332 skb_in_use = 1;
5333 BT_DBG("Queued %p (queue len %d)", skb,
5334 skb_queue_len(&chan->srej_q));
5335
5336 l2cap_pass_to_tx(chan, control);
5337 l2cap_send_srej(chan, control->txseq);
5338 break;
5339 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
5340 /* This frame was requested with an SREJ, but
5341 * some expected retransmitted frames are
5342 * missing. Request retransmission of missing
5343 * SREJ'd frames.
5344 */
5345 skb_queue_tail(&chan->srej_q, skb);
5346 skb_in_use = 1;
5347 BT_DBG("Queued %p (queue len %d)", skb,
5348 skb_queue_len(&chan->srej_q));
5349
5350 l2cap_pass_to_tx(chan, control);
5351 l2cap_send_srej_list(chan, control->txseq);
5352 break;
5353 case L2CAP_TXSEQ_DUPLICATE_SREJ:
5354 /* We've already queued this frame. Drop this copy. */
5355 l2cap_pass_to_tx(chan, control);
5356 break;
5357 case L2CAP_TXSEQ_DUPLICATE:
5358 /* Expecting a later sequence number, so this frame
5359 * was already received. Ignore it completely.
5360 */
5361 break;
5362 case L2CAP_TXSEQ_INVALID_IGNORE:
5363 break;
5364 case L2CAP_TXSEQ_INVALID:
5365 default:
5366 l2cap_send_disconn_req(chan->conn, chan,
5367 ECONNRESET);
5368 break;
5369 }
5370 break;
5371 case L2CAP_EV_RECV_RR:
5372 l2cap_pass_to_tx(chan, control);
5373 if (control->final) {
5374 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5375
5376 if (!test_and_clear_bit(CONN_REJ_ACT,
5377 &chan->conn_state)) {
5378 control->final = 0;
5379 l2cap_retransmit_all(chan, control);
5380 }
5381
5382 l2cap_ertm_send(chan);
5383 } else if (control->poll) {
5384 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5385 &chan->conn_state) &&
5386 chan->unacked_frames) {
5387 __set_retrans_timer(chan);
5388 }
5389
5390 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5391 l2cap_send_srej_tail(chan);
5392 } else {
5393 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5394 &chan->conn_state) &&
5395 chan->unacked_frames)
5396 __set_retrans_timer(chan);
5397
5398 l2cap_send_ack(chan);
5399 }
5400 break;
5401 case L2CAP_EV_RECV_RNR:
5402 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5403 l2cap_pass_to_tx(chan, control);
5404 if (control->poll) {
5405 l2cap_send_srej_tail(chan);
5406 } else {
5407 struct l2cap_ctrl rr_control;
5408 memset(&rr_control, 0, sizeof(rr_control));
5409 rr_control.sframe = 1;
5410 rr_control.super = L2CAP_SUPER_RR;
5411 rr_control.reqseq = chan->buffer_seq;
5412 l2cap_send_sframe(chan, &rr_control);
5413 }
5414
5415 break;
5416 case L2CAP_EV_RECV_REJ:
5417 l2cap_handle_rej(chan, control);
5418 break;
5419 case L2CAP_EV_RECV_SREJ:
5420 l2cap_handle_srej(chan, control);
5421 break;
5422 }
5423
5424 if (skb && !skb_in_use) {
5425 BT_DBG("Freeing %p", skb);
5426 kfree_skb(skb);
5427 }
5428
5429 return err;
5430}
5431
Mat Martineau32b32732012-10-23 15:24:11 -07005432static int l2cap_finish_move(struct l2cap_chan *chan)
5433{
5434 BT_DBG("chan %p", chan);
5435
5436 chan->rx_state = L2CAP_RX_STATE_RECV;
5437
5438 if (chan->hs_hcon)
5439 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
5440 else
5441 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
5442
5443 return l2cap_resegment(chan);
5444}
5445
5446static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
5447 struct l2cap_ctrl *control,
5448 struct sk_buff *skb, u8 event)
5449{
5450 int err;
5451
5452 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5453 event);
5454
5455 if (!control->poll)
5456 return -EPROTO;
5457
5458 l2cap_process_reqseq(chan, control->reqseq);
5459
5460 if (!skb_queue_empty(&chan->tx_q))
5461 chan->tx_send_head = skb_peek(&chan->tx_q);
5462 else
5463 chan->tx_send_head = NULL;
5464
5465 /* Rewind next_tx_seq to the point expected
5466 * by the receiver.
5467 */
5468 chan->next_tx_seq = control->reqseq;
5469 chan->unacked_frames = 0;
5470
5471 err = l2cap_finish_move(chan);
5472 if (err)
5473 return err;
5474
5475 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5476 l2cap_send_i_or_rr_or_rnr(chan);
5477
5478 if (event == L2CAP_EV_RECV_IFRAME)
5479 return -EPROTO;
5480
5481 return l2cap_rx_state_recv(chan, control, NULL, event);
5482}
5483
5484static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
5485 struct l2cap_ctrl *control,
5486 struct sk_buff *skb, u8 event)
5487{
5488 int err;
5489
5490 if (!control->final)
5491 return -EPROTO;
5492
5493 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5494
5495 chan->rx_state = L2CAP_RX_STATE_RECV;
5496 l2cap_process_reqseq(chan, control->reqseq);
5497
5498 if (!skb_queue_empty(&chan->tx_q))
5499 chan->tx_send_head = skb_peek(&chan->tx_q);
5500 else
5501 chan->tx_send_head = NULL;
5502
5503 /* Rewind next_tx_seq to the point expected
5504 * by the receiver.
5505 */
5506 chan->next_tx_seq = control->reqseq;
5507 chan->unacked_frames = 0;
5508
5509 if (chan->hs_hcon)
5510 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
5511 else
5512 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
5513
5514 err = l2cap_resegment(chan);
5515
5516 if (!err)
5517 err = l2cap_rx_state_recv(chan, control, skb, event);
5518
5519 return err;
5520}
5521
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005522static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
5523{
5524 /* Make sure reqseq is for a packet that has been sent but not acked */
5525 u16 unacked;
5526
5527 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
5528 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
5529}
5530
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005531static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5532 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005533{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005534 int err = 0;
5535
5536 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
5537 control, skb, event, chan->rx_state);
5538
5539 if (__valid_reqseq(chan, control->reqseq)) {
5540 switch (chan->rx_state) {
5541 case L2CAP_RX_STATE_RECV:
5542 err = l2cap_rx_state_recv(chan, control, skb, event);
5543 break;
5544 case L2CAP_RX_STATE_SREJ_SENT:
5545 err = l2cap_rx_state_srej_sent(chan, control, skb,
5546 event);
5547 break;
Mat Martineau32b32732012-10-23 15:24:11 -07005548 case L2CAP_RX_STATE_WAIT_P:
5549 err = l2cap_rx_state_wait_p(chan, control, skb, event);
5550 break;
5551 case L2CAP_RX_STATE_WAIT_F:
5552 err = l2cap_rx_state_wait_f(chan, control, skb, event);
5553 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005554 default:
5555 /* shut it down */
5556 break;
5557 }
5558 } else {
5559 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
5560 control->reqseq, chan->next_tx_seq,
5561 chan->expected_ack_seq);
5562 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5563 }
5564
5565 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005566}
5567
5568static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5569 struct sk_buff *skb)
5570{
Mat Martineau4b51dae92012-05-17 20:53:37 -07005571 int err = 0;
5572
5573 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
5574 chan->rx_state);
5575
5576 if (l2cap_classify_txseq(chan, control->txseq) ==
5577 L2CAP_TXSEQ_EXPECTED) {
5578 l2cap_pass_to_tx(chan, control);
5579
5580 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
5581 __next_seq(chan, chan->buffer_seq));
5582
5583 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5584
5585 l2cap_reassemble_sdu(chan, skb, control);
5586 } else {
5587 if (chan->sdu) {
5588 kfree_skb(chan->sdu);
5589 chan->sdu = NULL;
5590 }
5591 chan->sdu_last_frag = NULL;
5592 chan->sdu_len = 0;
5593
5594 if (skb) {
5595 BT_DBG("Freeing %p", skb);
5596 kfree_skb(skb);
5597 }
5598 }
5599
5600 chan->last_acked_seq = control->txseq;
5601 chan->expected_tx_seq = __next_seq(chan, control->txseq);
5602
5603 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005604}
5605
5606static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
5607{
5608 struct l2cap_ctrl *control = &bt_cb(skb)->control;
5609 u16 len;
5610 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005611
Mat Martineaub76bbd62012-04-11 10:48:43 -07005612 __unpack_control(chan, skb);
5613
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005614 len = skb->len;
5615
5616 /*
5617 * We can just drop the corrupted I-frame here.
5618 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005619 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005620 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005621 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005622 goto drop;
5623
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005624 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005625 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005626
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005627 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005628 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005629
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005630 if (len > chan->mps) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005631 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005632 goto drop;
5633 }
5634
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005635 if (!control->sframe) {
5636 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005637
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005638 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
5639 control->sar, control->reqseq, control->final,
5640 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03005641
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005642 /* Validate F-bit - F=0 always valid, F=1 only
5643 * valid in TX WAIT_F
5644 */
5645 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005646 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005647
5648 if (chan->mode != L2CAP_MODE_STREAMING) {
5649 event = L2CAP_EV_RECV_IFRAME;
5650 err = l2cap_rx(chan, control, skb, event);
5651 } else {
5652 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005653 }
5654
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005655 if (err)
5656 l2cap_send_disconn_req(chan->conn, chan,
5657 ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005658 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005659 const u8 rx_func_to_event[4] = {
5660 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
5661 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
5662 };
5663
5664 /* Only I-frames are expected in streaming mode */
5665 if (chan->mode == L2CAP_MODE_STREAMING)
5666 goto drop;
5667
5668 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
5669 control->reqseq, control->final, control->poll,
5670 control->super);
5671
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005672 if (len != 0) {
5673 BT_ERR("%d", len);
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005674 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005675 goto drop;
5676 }
5677
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005678 /* Validate F and P bits */
5679 if (control->final && (control->poll ||
5680 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
5681 goto drop;
5682
5683 event = rx_func_to_event[control->super];
5684 if (l2cap_rx(chan, control, skb, event))
5685 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005686 }
5687
5688 return 0;
5689
5690drop:
5691 kfree_skb(skb);
5692 return 0;
5693}
5694
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005695static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
5696 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005697{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005698 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005699
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03005700 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005701 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005702 if (cid == L2CAP_CID_A2MP) {
5703 chan = a2mp_channel_create(conn, skb);
5704 if (!chan) {
5705 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005706 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005707 }
5708
5709 l2cap_chan_lock(chan);
5710 } else {
5711 BT_DBG("unknown cid 0x%4.4x", cid);
5712 /* Drop packet and return */
5713 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005714 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005715 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005716 }
5717
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03005718 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005719
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005720 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005721 goto drop;
5722
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005723 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005724 case L2CAP_MODE_BASIC:
5725 /* If socket recv buffers overflows we drop data here
5726 * which is *bad* because L2CAP has to be reliable.
5727 * But we don't have any other choice. L2CAP doesn't
5728 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005729
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005730 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005731 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005732
Gustavo Padovan80b98022012-05-27 22:27:51 -03005733 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005734 goto done;
5735 break;
5736
5737 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005738 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005739 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005740 goto done;
5741
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005742 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005743 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005744 break;
5745 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005746
5747drop:
5748 kfree_skb(skb);
5749
5750done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005751 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005752}
5753
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005754static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
5755 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005756{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005757 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005758
Ido Yarivc2287682012-04-20 15:46:07 -03005759 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005760 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005761 goto drop;
5762
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005763 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005764
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005765 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005766 goto drop;
5767
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005768 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005769 goto drop;
5770
Gustavo Padovan80b98022012-05-27 22:27:51 -03005771 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005772 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005773
5774drop:
5775 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005776}
5777
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005778static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
5779 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005780{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005781 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005782
Ido Yarivc2287682012-04-20 15:46:07 -03005783 chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005784 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005785 goto drop;
5786
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005787 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005788
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005789 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005790 goto drop;
5791
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005792 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005793 goto drop;
5794
Gustavo Padovan80b98022012-05-27 22:27:51 -03005795 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005796 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005797
5798drop:
5799 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005800}
5801
Linus Torvalds1da177e2005-04-16 15:20:36 -07005802static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
5803{
5804 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07005805 u16 cid, len;
5806 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005807
5808 skb_pull(skb, L2CAP_HDR_SIZE);
5809 cid = __le16_to_cpu(lh->cid);
5810 len = __le16_to_cpu(lh->len);
5811
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005812 if (len != skb->len) {
5813 kfree_skb(skb);
5814 return;
5815 }
5816
Linus Torvalds1da177e2005-04-16 15:20:36 -07005817 BT_DBG("len %d, cid 0x%4.4x", len, cid);
5818
5819 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005820 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005821 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005822 l2cap_sig_channel(conn, skb);
5823 break;
5824
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005825 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02005826 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03005827 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005828 l2cap_conless_channel(conn, psm, skb);
5829 break;
5830
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005831 case L2CAP_CID_LE_DATA:
5832 l2cap_att_channel(conn, cid, skb);
5833 break;
5834
Anderson Brigliab501d6a2011-06-07 18:46:31 -03005835 case L2CAP_CID_SMP:
5836 if (smp_sig_channel(conn, skb))
5837 l2cap_conn_del(conn->hcon, EACCES);
5838 break;
5839
Linus Torvalds1da177e2005-04-16 15:20:36 -07005840 default:
5841 l2cap_data_channel(conn, cid, skb);
5842 break;
5843 }
5844}
5845
5846/* ---- L2CAP interface with lower layer (HCI) ---- */
5847
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005848int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005849{
5850 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005851 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005852
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03005853 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005854
5855 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005856 read_lock(&chan_list_lock);
5857 list_for_each_entry(c, &chan_list, global_l) {
5858 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005859
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005860 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005861 continue;
5862
5863 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005864 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005865 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005866 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005867 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005868 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
5869 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005870 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005871 lm2 |= HCI_LM_MASTER;
5872 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005873 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005874 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005875
5876 return exact ? lm1 : lm2;
5877}
5878
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03005879void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005880{
Marcel Holtmann01394182006-07-03 10:02:46 +02005881 struct l2cap_conn *conn;
5882
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03005883 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005884
Linus Torvalds1da177e2005-04-16 15:20:36 -07005885 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005886 conn = l2cap_conn_add(hcon, status);
5887 if (conn)
5888 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02005889 } else
Joe Perchese1750722011-06-29 18:18:29 -07005890 l2cap_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005891
Linus Torvalds1da177e2005-04-16 15:20:36 -07005892}
5893
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005894int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01005895{
5896 struct l2cap_conn *conn = hcon->l2cap_data;
5897
5898 BT_DBG("hcon %p", hcon);
5899
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005900 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02005901 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01005902 return conn->disc_reason;
5903}
5904
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03005905void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005906{
5907 BT_DBG("hcon %p reason %d", hcon, reason);
5908
Joe Perchese1750722011-06-29 18:18:29 -07005909 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005910}
5911
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005912static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005913{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03005914 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01005915 return;
5916
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005917 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005918 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005919 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005920 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03005921 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005922 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005923 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03005924 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005925 }
5926}
5927
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005928int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005929{
Marcel Holtmann40be4922008-07-14 20:13:50 +02005930 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005931 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005932
Marcel Holtmann01394182006-07-03 10:02:46 +02005933 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005934 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02005935
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03005936 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005937
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005938 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05305939 if (!status && encrypt)
5940 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02005941 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005942 }
5943
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005944 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005945
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005946 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005947 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005948
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03005949 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
5950 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005951
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03005952 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
5953 l2cap_chan_unlock(chan);
5954 continue;
5955 }
5956
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005957 if (chan->scid == L2CAP_CID_LE_DATA) {
5958 if (!status && encrypt) {
5959 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02005960 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005961 }
5962
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005963 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005964 continue;
5965 }
5966
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03005967 if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005968 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01005969 continue;
5970 }
5971
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005972 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01005973 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03005974 struct sock *sk = chan->sk;
5975
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005976 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03005977 sk->sk_state_change(sk);
5978
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005979 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005980 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02005981 continue;
5982 }
5983
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005984 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005985 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03005986 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005987 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005988 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005989 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005990 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005991 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005992 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005993 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005994
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005995 lock_sock(sk);
5996
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005997 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005998 if (test_bit(BT_SK_DEFER_SETUP,
5999 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006000 res = L2CAP_CR_PEND;
6001 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006002 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006003 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006004 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006005 res = L2CAP_CR_SUCCESS;
6006 stat = L2CAP_CS_NO_INFO;
6007 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006008 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006009 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006010 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006011 res = L2CAP_CR_SEC_BLOCK;
6012 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006013 }
6014
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006015 release_sock(sk);
6016
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006017 rsp.scid = cpu_to_le16(chan->dcid);
6018 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006019 rsp.result = cpu_to_le16(res);
6020 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006021 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006022 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006023
6024 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6025 res == L2CAP_CR_SUCCESS) {
6026 char buf[128];
6027 set_bit(CONF_REQ_SENT, &chan->conf_state);
6028 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6029 L2CAP_CONF_REQ,
6030 l2cap_build_conf_req(chan, buf),
6031 buf);
6032 chan->num_conf_req++;
6033 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006034 }
6035
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006036 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006037 }
6038
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006039 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006040
Linus Torvalds1da177e2005-04-16 15:20:36 -07006041 return 0;
6042}
6043
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006044int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006045{
6046 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006047 struct l2cap_hdr *hdr;
6048 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006049
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006050 /* For AMP controller do not create l2cap conn */
6051 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6052 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006053
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006054 if (!conn)
6055 conn = l2cap_conn_add(hcon, 0);
6056
6057 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006058 goto drop;
6059
6060 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6061
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006062 switch (flags) {
6063 case ACL_START:
6064 case ACL_START_NO_FLUSH:
6065 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006066 if (conn->rx_len) {
6067 BT_ERR("Unexpected start frame (len %d)", skb->len);
6068 kfree_skb(conn->rx_skb);
6069 conn->rx_skb = NULL;
6070 conn->rx_len = 0;
6071 l2cap_conn_unreliable(conn, ECOMM);
6072 }
6073
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006074 /* Start fragment always begin with Basic L2CAP header */
6075 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006076 BT_ERR("Frame is too short (len %d)", skb->len);
6077 l2cap_conn_unreliable(conn, ECOMM);
6078 goto drop;
6079 }
6080
6081 hdr = (struct l2cap_hdr *) skb->data;
6082 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6083
6084 if (len == skb->len) {
6085 /* Complete frame received */
6086 l2cap_recv_frame(conn, skb);
6087 return 0;
6088 }
6089
6090 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6091
6092 if (skb->len > len) {
6093 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006094 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006095 l2cap_conn_unreliable(conn, ECOMM);
6096 goto drop;
6097 }
6098
6099 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006100 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006101 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006102 goto drop;
6103
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006104 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006105 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006106 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006107 break;
6108
6109 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006110 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6111
6112 if (!conn->rx_len) {
6113 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6114 l2cap_conn_unreliable(conn, ECOMM);
6115 goto drop;
6116 }
6117
6118 if (skb->len > conn->rx_len) {
6119 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006120 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006121 kfree_skb(conn->rx_skb);
6122 conn->rx_skb = NULL;
6123 conn->rx_len = 0;
6124 l2cap_conn_unreliable(conn, ECOMM);
6125 goto drop;
6126 }
6127
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006128 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006129 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006130 conn->rx_len -= skb->len;
6131
6132 if (!conn->rx_len) {
6133 /* Complete frame received */
6134 l2cap_recv_frame(conn, conn->rx_skb);
6135 conn->rx_skb = NULL;
6136 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006137 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006138 }
6139
6140drop:
6141 kfree_skb(skb);
6142 return 0;
6143}
6144
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006145static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006146{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006147 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006148
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006149 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006150
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006151 list_for_each_entry(c, &chan_list, global_l) {
6152 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006153
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006154 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
6155 &bt_sk(sk)->src, &bt_sk(sk)->dst,
6156 c->state, __le16_to_cpu(c->psm),
6157 c->scid, c->dcid, c->imtu, c->omtu,
6158 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006159 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006160
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006161 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006162
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006163 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006164}
6165
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006166static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6167{
6168 return single_open(file, l2cap_debugfs_show, inode->i_private);
6169}
6170
6171static const struct file_operations l2cap_debugfs_fops = {
6172 .open = l2cap_debugfs_open,
6173 .read = seq_read,
6174 .llseek = seq_lseek,
6175 .release = single_release,
6176};
6177
6178static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006179
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006180int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006181{
6182 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006183
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006184 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006185 if (err < 0)
6186 return err;
6187
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006188 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006189 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6190 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006191 if (!l2cap_debugfs)
6192 BT_ERR("Failed to create L2CAP debug file");
6193 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006194
Linus Torvalds1da177e2005-04-16 15:20:36 -07006195 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006196}
6197
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006198void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006199{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006200 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006201 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006202}
6203
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006204module_param(disable_ertm, bool, 0644);
6205MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");