blob: d8cffdbf0d37c2692b9348f54069370ca357450d [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>
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +020041#include <net/bluetooth/amp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
Mat Martineaud1de6d42012-05-17 20:53:55 -070043bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020044
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070045static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Mat Martineau50a147c2011-11-02 16:18:34 -070046static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070047
Johannes Bergb5ad8b72011-06-01 08:54:45 +020048static LIST_HEAD(chan_list);
49static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Linus Torvalds1da177e2005-04-16 15:20:36 -070051static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010052 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030053static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010054 void *data);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -030055static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +020056static void l2cap_send_disconn_req(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
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200580 if (chan->hs_hchan) {
581 struct hci_chan *hs_hchan = chan->hs_hchan;
582
583 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
584 amp_disconnect_logical_link(hs_hchan);
585 }
586
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100587 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200588
Mat Martineau28270112012-05-17 21:14:09 -0700589 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300590 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300591
Gustavo Padovanee556f62012-05-18 20:22:38 -0300592 switch(chan->mode) {
593 case L2CAP_MODE_BASIC:
594 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300595
Gustavo Padovanee556f62012-05-18 20:22:38 -0300596 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300597 __clear_retrans_timer(chan);
598 __clear_monitor_timer(chan);
599 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300600
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300601 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300602
Mat Martineau3c588192012-04-11 10:48:42 -0700603 l2cap_seq_list_free(&chan->srej_list);
604 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300605
606 /* fall through */
607
608 case L2CAP_MODE_STREAMING:
609 skb_queue_purge(&chan->tx_q);
610 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300611 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300612
613 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200614}
615
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300616void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300617{
618 struct l2cap_conn *conn = chan->conn;
619 struct sock *sk = chan->sk;
620
Gustavo Padovan2d792812012-10-06 10:07:01 +0100621 BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state),
622 sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300623
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300624 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300625 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100626 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300627 break;
628
629 case BT_CONNECTED:
630 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300631 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100632 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300633 __set_chan_timer(chan, sk->sk_sndtimeo);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200634 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300635 } else
636 l2cap_chan_del(chan, reason);
637 break;
638
639 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300640 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100641 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300642 struct l2cap_conn_rsp rsp;
643 __u16 result;
644
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300645 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300646 result = L2CAP_CR_SEC_BLOCK;
647 else
648 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300649 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300650
651 rsp.scid = cpu_to_le16(chan->dcid);
652 rsp.dcid = cpu_to_le16(chan->scid);
653 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300654 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300655 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100656 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300657 }
658
659 l2cap_chan_del(chan, reason);
660 break;
661
662 case BT_CONNECT:
663 case BT_DISCONN:
664 l2cap_chan_del(chan, reason);
665 break;
666
667 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100668 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300669 break;
670 }
671}
672
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300673static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530674{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300675 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300676 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530677 case BT_SECURITY_HIGH:
678 return HCI_AT_DEDICATED_BONDING_MITM;
679 case BT_SECURITY_MEDIUM:
680 return HCI_AT_DEDICATED_BONDING;
681 default:
682 return HCI_AT_NO_BONDING;
683 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300684 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300685 if (chan->sec_level == BT_SECURITY_LOW)
686 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530687
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300688 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530689 return HCI_AT_NO_BONDING_MITM;
690 else
691 return HCI_AT_NO_BONDING;
692 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300693 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530694 case BT_SECURITY_HIGH:
695 return HCI_AT_GENERAL_BONDING_MITM;
696 case BT_SECURITY_MEDIUM:
697 return HCI_AT_GENERAL_BONDING;
698 default:
699 return HCI_AT_NO_BONDING;
700 }
701 }
702}
703
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200704/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200705int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200706{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300707 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100708 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200709
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300710 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100711
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300712 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200713}
714
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200715static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200716{
717 u8 id;
718
719 /* Get next available identificator.
720 * 1 - 128 are used by kernel.
721 * 129 - 199 are reserved.
722 * 200 - 254 are used by utilities like l2ping, etc.
723 */
724
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200725 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200726
727 if (++conn->tx_ident > 128)
728 conn->tx_ident = 1;
729
730 id = conn->tx_ident;
731
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200732 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200733
734 return id;
735}
736
Gustavo Padovan2d792812012-10-06 10:07:01 +0100737static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
738 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200739{
740 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200741 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200742
743 BT_DBG("code 0x%2.2x", code);
744
745 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300746 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200747
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200748 if (lmp_no_flush_capable(conn->hcon->hdev))
749 flags = ACL_START_NO_FLUSH;
750 else
751 flags = ACL_START;
752
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700753 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200754 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700755
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200756 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200757}
758
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700759static bool __chan_is_moving(struct l2cap_chan *chan)
760{
761 return chan->move_state != L2CAP_MOVE_STABLE &&
762 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
763}
764
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200765static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
766{
767 struct hci_conn *hcon = chan->conn->hcon;
768 u16 flags;
769
770 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100771 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200772
Mat Martineaud5f8a752012-10-23 15:24:18 -0700773 if (chan->hs_hcon && !__chan_is_moving(chan)) {
774 if (chan->hs_hchan)
775 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
776 else
777 kfree_skb(skb);
778
779 return;
780 }
781
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200782 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100783 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200784 flags = ACL_START_NO_FLUSH;
785 else
786 flags = ACL_START;
787
788 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
789 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790}
791
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700792static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
793{
794 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
795 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
796
797 if (enh & L2CAP_CTRL_FRAME_TYPE) {
798 /* S-Frame */
799 control->sframe = 1;
800 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
801 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
802
803 control->sar = 0;
804 control->txseq = 0;
805 } else {
806 /* I-Frame */
807 control->sframe = 0;
808 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
809 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
810
811 control->poll = 0;
812 control->super = 0;
813 }
814}
815
816static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
817{
818 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
819 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
820
821 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
822 /* S-Frame */
823 control->sframe = 1;
824 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
825 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
826
827 control->sar = 0;
828 control->txseq = 0;
829 } else {
830 /* I-Frame */
831 control->sframe = 0;
832 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
833 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
834
835 control->poll = 0;
836 control->super = 0;
837 }
838}
839
840static inline void __unpack_control(struct l2cap_chan *chan,
841 struct sk_buff *skb)
842{
843 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
844 __unpack_extended_control(get_unaligned_le32(skb->data),
845 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700846 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700847 } else {
848 __unpack_enhanced_control(get_unaligned_le16(skb->data),
849 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700850 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700851 }
852}
853
854static u32 __pack_extended_control(struct l2cap_ctrl *control)
855{
856 u32 packed;
857
858 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
859 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
860
861 if (control->sframe) {
862 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
863 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
864 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
865 } else {
866 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
867 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
868 }
869
870 return packed;
871}
872
873static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
874{
875 u16 packed;
876
877 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
878 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
879
880 if (control->sframe) {
881 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
882 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
883 packed |= L2CAP_CTRL_FRAME_TYPE;
884 } else {
885 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
886 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
887 }
888
889 return packed;
890}
891
892static inline void __pack_control(struct l2cap_chan *chan,
893 struct l2cap_ctrl *control,
894 struct sk_buff *skb)
895{
896 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
897 put_unaligned_le32(__pack_extended_control(control),
898 skb->data + L2CAP_HDR_SIZE);
899 } else {
900 put_unaligned_le16(__pack_enhanced_control(control),
901 skb->data + L2CAP_HDR_SIZE);
902 }
903}
904
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300905static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
906{
907 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
908 return L2CAP_EXT_HDR_SIZE;
909 else
910 return L2CAP_ENH_HDR_SIZE;
911}
912
Mat Martineaua67d7f62012-05-17 20:53:35 -0700913static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
914 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300915{
916 struct sk_buff *skb;
917 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300918 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300919
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300920 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300921 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300922
Mat Martineaua67d7f62012-05-17 20:53:35 -0700923 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300924
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300925 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700926 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300927
928 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300929 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300930 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300931
Mat Martineaua67d7f62012-05-17 20:53:35 -0700932 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
933 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
934 else
935 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300936
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300937 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700938 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300939 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300940 }
941
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200942 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700943 return skb;
944}
945
946static void l2cap_send_sframe(struct l2cap_chan *chan,
947 struct l2cap_ctrl *control)
948{
949 struct sk_buff *skb;
950 u32 control_field;
951
952 BT_DBG("chan %p, control %p", chan, control);
953
954 if (!control->sframe)
955 return;
956
Mat Martineaub99e13a2012-10-23 15:24:19 -0700957 if (__chan_is_moving(chan))
958 return;
959
Mat Martineaua67d7f62012-05-17 20:53:35 -0700960 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
961 !control->poll)
962 control->final = 1;
963
964 if (control->super == L2CAP_SUPER_RR)
965 clear_bit(CONN_RNR_SENT, &chan->conn_state);
966 else if (control->super == L2CAP_SUPER_RNR)
967 set_bit(CONN_RNR_SENT, &chan->conn_state);
968
969 if (control->super != L2CAP_SUPER_SREJ) {
970 chan->last_acked_seq = control->reqseq;
971 __clear_ack_timer(chan);
972 }
973
974 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
975 control->final, control->poll, control->super);
976
977 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
978 control_field = __pack_extended_control(control);
979 else
980 control_field = __pack_enhanced_control(control);
981
982 skb = l2cap_create_sframe_pdu(chan, control_field);
983 if (!IS_ERR(skb))
984 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300985}
986
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700987static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300988{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700989 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300990
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700991 BT_DBG("chan %p, poll %d", chan, poll);
992
993 memset(&control, 0, sizeof(control));
994 control.sframe = 1;
995 control.poll = poll;
996
997 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
998 control.super = L2CAP_SUPER_RNR;
999 else
1000 control.super = L2CAP_SUPER_RR;
1001
1002 control.reqseq = chan->buffer_seq;
1003 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001004}
1005
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001006static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001007{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001008 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001009}
1010
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001011static bool __amp_capable(struct l2cap_chan *chan)
1012{
1013 struct l2cap_conn *conn = chan->conn;
1014
1015 if (enable_hs &&
Andrei Emeltchenko5d054162012-11-29 17:46:05 +02001016 hci_amp_capable() &&
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001017 chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED &&
1018 conn->fixed_chan_mask & L2CAP_FC_A2MP)
1019 return true;
1020 else
1021 return false;
1022}
1023
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001024static bool l2cap_check_efs(struct l2cap_chan *chan)
1025{
1026 /* Check EFS parameters */
1027 return true;
1028}
1029
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001030void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001031{
1032 struct l2cap_conn *conn = chan->conn;
1033 struct l2cap_conn_req req;
1034
1035 req.scid = cpu_to_le16(chan->scid);
1036 req.psm = chan->psm;
1037
1038 chan->ident = l2cap_get_ident(conn);
1039
1040 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1041
1042 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1043}
1044
Mat Martineau8eb200b2012-10-23 15:24:17 -07001045static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1046{
1047 struct l2cap_create_chan_req req;
1048 req.scid = cpu_to_le16(chan->scid);
1049 req.psm = chan->psm;
1050 req.amp_id = amp_id;
1051
1052 chan->ident = l2cap_get_ident(chan->conn);
1053
1054 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1055 sizeof(req), &req);
1056}
1057
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001058static void l2cap_move_setup(struct l2cap_chan *chan)
1059{
1060 struct sk_buff *skb;
1061
1062 BT_DBG("chan %p", chan);
1063
1064 if (chan->mode != L2CAP_MODE_ERTM)
1065 return;
1066
1067 __clear_retrans_timer(chan);
1068 __clear_monitor_timer(chan);
1069 __clear_ack_timer(chan);
1070
1071 chan->retry_count = 0;
1072 skb_queue_walk(&chan->tx_q, skb) {
1073 if (bt_cb(skb)->control.retries)
1074 bt_cb(skb)->control.retries = 1;
1075 else
1076 break;
1077 }
1078
1079 chan->expected_tx_seq = chan->buffer_seq;
1080
1081 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1082 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1083 l2cap_seq_list_clear(&chan->retrans_list);
1084 l2cap_seq_list_clear(&chan->srej_list);
1085 skb_queue_purge(&chan->srej_q);
1086
1087 chan->tx_state = L2CAP_TX_STATE_XMIT;
1088 chan->rx_state = L2CAP_RX_STATE_MOVE;
1089
1090 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1091}
1092
Mat Martineau5f3847a2012-10-23 15:24:12 -07001093static void l2cap_move_done(struct l2cap_chan *chan)
1094{
1095 u8 move_role = chan->move_role;
1096 BT_DBG("chan %p", chan);
1097
1098 chan->move_state = L2CAP_MOVE_STABLE;
1099 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1100
1101 if (chan->mode != L2CAP_MODE_ERTM)
1102 return;
1103
1104 switch (move_role) {
1105 case L2CAP_MOVE_ROLE_INITIATOR:
1106 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1107 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1108 break;
1109 case L2CAP_MOVE_ROLE_RESPONDER:
1110 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1111 break;
1112 }
1113}
1114
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001115static void l2cap_chan_ready(struct l2cap_chan *chan)
1116{
Mat Martineau28270112012-05-17 21:14:09 -07001117 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001118 chan->conf_state = 0;
1119 __clear_chan_timer(chan);
1120
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001121 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001122
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001123 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001124}
1125
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001126static void l2cap_start_connection(struct l2cap_chan *chan)
1127{
1128 if (__amp_capable(chan)) {
1129 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1130 a2mp_discover_amp(chan);
1131 } else {
1132 l2cap_send_conn_req(chan);
1133 }
1134}
1135
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001136static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001137{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001138 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001139
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001140 if (conn->hcon->type == LE_LINK) {
1141 l2cap_chan_ready(chan);
1142 return;
1143 }
1144
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001145 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001146 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1147 return;
1148
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001149 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001150 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001151 l2cap_start_connection(chan);
1152 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001153 } else {
1154 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001155 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001156
1157 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1158 conn->info_ident = l2cap_get_ident(conn);
1159
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001160 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001161
Gustavo Padovan2d792812012-10-06 10:07:01 +01001162 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1163 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001164 }
1165}
1166
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001167static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1168{
1169 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001170 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001171 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1172
1173 switch (mode) {
1174 case L2CAP_MODE_ERTM:
1175 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1176 case L2CAP_MODE_STREAMING:
1177 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1178 default:
1179 return 0x00;
1180 }
1181}
1182
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001183static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001184{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001185 struct sock *sk = chan->sk;
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001186 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001187 struct l2cap_disconn_req req;
1188
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001189 if (!conn)
1190 return;
1191
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001192 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001193 __clear_retrans_timer(chan);
1194 __clear_monitor_timer(chan);
1195 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001196 }
1197
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001198 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001199 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001200 return;
1201 }
1202
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001203 req.dcid = cpu_to_le16(chan->dcid);
1204 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001205 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1206 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001207
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001208 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001209 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001210 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001211 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001212}
1213
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001215static void l2cap_conn_start(struct l2cap_conn *conn)
1216{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001217 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001218
1219 BT_DBG("conn %p", conn);
1220
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001221 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001222
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001223 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001224 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001225
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001226 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001227
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001228 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001229 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001230 continue;
1231 }
1232
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001233 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001234 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001235 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001236 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001237 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001238 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001239
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001240 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001241 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001242 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001243 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001244 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001245 continue;
1246 }
1247
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001248 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001249
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001250 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001251 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001252 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001253 rsp.scid = cpu_to_le16(chan->dcid);
1254 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001255
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001256 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001257 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001258 if (test_bit(BT_SK_DEFER_SETUP,
1259 &bt_sk(sk)->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001260 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1261 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001262 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001263
1264 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001265 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001266 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1267 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001268 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001269 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001270 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001271 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1272 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001273 }
1274
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001275 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001276 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001277
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001278 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001279 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001280 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001281 continue;
1282 }
1283
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001284 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001285 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001286 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001287 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001288 }
1289
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001290 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001291 }
1292
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001293 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001294}
1295
Ido Yarivc2287682012-04-20 15:46:07 -03001296/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001297 * Returns closest match, locked.
1298 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001299static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001300 bdaddr_t *src,
1301 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001302{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001303 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001304
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001305 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001306
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001307 list_for_each_entry(c, &chan_list, global_l) {
1308 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001309
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001310 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001311 continue;
1312
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001313 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001314 int src_match, dst_match;
1315 int src_any, dst_any;
1316
Ville Tervob62f3282011-02-10 22:38:50 -03001317 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001318 src_match = !bacmp(&bt_sk(sk)->src, src);
1319 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1320 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001321 read_unlock(&chan_list_lock);
1322 return c;
1323 }
Ville Tervob62f3282011-02-10 22:38:50 -03001324
1325 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001326 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1327 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1328 if ((src_match && dst_any) || (src_any && dst_match) ||
1329 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001330 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001331 }
1332 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001333
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001334 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001335
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001336 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001337}
1338
1339static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1340{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001341 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001342 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001343
1344 BT_DBG("");
1345
1346 /* Check if we have socket listening on cid */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001347 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
Ido Yarivc2287682012-04-20 15:46:07 -03001348 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001349 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001350 return;
1351
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001352 parent = pchan->sk;
1353
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001354 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001355
Gustavo Padovan80b98022012-05-27 22:27:51 -03001356 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001357 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001358 goto clean;
1359
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001360 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001361
Ville Tervob62f3282011-02-10 22:38:50 -03001362 hci_conn_hold(conn->hcon);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001363 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
Ville Tervob62f3282011-02-10 22:38:50 -03001364
Ville Tervob62f3282011-02-10 22:38:50 -03001365 bacpy(&bt_sk(sk)->src, conn->src);
1366 bacpy(&bt_sk(sk)->dst, conn->dst);
1367
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001368 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001369
Gustavo Padovan6754e0d2012-05-25 09:30:56 -03001370 l2cap_chan_ready(chan);
Ville Tervob62f3282011-02-10 22:38:50 -03001371
Ville Tervob62f3282011-02-10 22:38:50 -03001372clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001373 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001374}
1375
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001376static void l2cap_conn_ready(struct l2cap_conn *conn)
1377{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001378 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001379 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001380
1381 BT_DBG("conn %p", conn);
1382
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001383 if (!hcon->out && hcon->type == LE_LINK)
Ville Tervob62f3282011-02-10 22:38:50 -03001384 l2cap_le_conn_ready(conn);
1385
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001386 if (hcon->out && hcon->type == LE_LINK)
1387 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001388
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001389 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001390
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001391 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001392
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001393 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001394
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001395 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1396 l2cap_chan_unlock(chan);
1397 continue;
1398 }
1399
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001400 if (hcon->type == LE_LINK) {
1401 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001402 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001403
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001404 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001405 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001406 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001407 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001408 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001409 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001410 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001411
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001412 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001413 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001414
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001415 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001416 }
1417
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001418 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001419}
1420
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001421/* Notify sockets that we cannot guaranty reliability anymore */
1422static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1423{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001424 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001425
1426 BT_DBG("conn %p", conn);
1427
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001428 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001429
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001430 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001431 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001432 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001433 }
1434
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001435 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001436}
1437
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001438static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001439{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001440 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001441 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001442
Marcel Holtmann984947d2009-02-06 23:35:19 +01001443 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001444 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001445
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001446 l2cap_conn_start(conn);
1447}
1448
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001449static void l2cap_conn_del(struct hci_conn *hcon, int err)
1450{
1451 struct l2cap_conn *conn = hcon->l2cap_data;
1452 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001453
1454 if (!conn)
1455 return;
1456
1457 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1458
1459 kfree_skb(conn->rx_skb);
1460
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001461 mutex_lock(&conn->chan_lock);
1462
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001463 /* Kill channels */
1464 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001465 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001466 l2cap_chan_lock(chan);
1467
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001468 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001469
1470 l2cap_chan_unlock(chan);
1471
Gustavo Padovan80b98022012-05-27 22:27:51 -03001472 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001473 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001474 }
1475
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001476 mutex_unlock(&conn->chan_lock);
1477
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001478 hci_chan_del(conn->hchan);
1479
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001480 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001481 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001482
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001483 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001484 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001485 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001486 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001487
1488 hcon->l2cap_data = NULL;
1489 kfree(conn);
1490}
1491
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001492static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001493{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001494 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001495 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001496
Johan Hedbergd06cc412012-06-06 18:44:11 +08001497 BT_DBG("conn %p", conn);
1498
1499 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1500 smp_chan_destroy(conn);
1501 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1502 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001503}
1504
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1506{
Marcel Holtmann01394182006-07-03 10:02:46 +02001507 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001508 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509
Marcel Holtmann01394182006-07-03 10:02:46 +02001510 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511 return conn;
1512
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001513 hchan = hci_chan_create(hcon);
1514 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001517 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001518 if (!conn) {
1519 hci_chan_del(hchan);
1520 return NULL;
1521 }
1522
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 hcon->l2cap_data = conn;
1524 conn->hcon = hcon;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001525 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001527 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001528
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001529 switch (hcon->type) {
1530 case AMP_LINK:
1531 conn->mtu = hcon->hdev->block_mtu;
1532 break;
1533
1534 case LE_LINK:
1535 if (hcon->hdev->le_mtu) {
1536 conn->mtu = hcon->hdev->le_mtu;
1537 break;
1538 }
1539 /* fall through */
1540
1541 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001542 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001543 break;
1544 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001545
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 conn->src = &hcon->hdev->bdaddr;
1547 conn->dst = &hcon->dst;
1548
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001549 conn->feat_mask = 0;
1550
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001552 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001553
1554 INIT_LIST_HEAD(&conn->chan_l);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001555
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001556 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001557 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001558 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001559 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001560
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001561 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001562
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563 return conn;
1564}
1565
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567
Ido Yarivc2287682012-04-20 15:46:07 -03001568/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569 * Returns closest match.
1570 */
Ido Yarivc2287682012-04-20 15:46:07 -03001571static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1572 bdaddr_t *src,
1573 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001575 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001577 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001578
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001579 list_for_each_entry(c, &chan_list, global_l) {
1580 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001581
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001582 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583 continue;
1584
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001585 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001586 int src_match, dst_match;
1587 int src_any, dst_any;
1588
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001590 src_match = !bacmp(&bt_sk(sk)->src, src);
1591 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1592 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001593 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001594 return c;
1595 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596
1597 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001598 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1599 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1600 if ((src_match && dst_any) || (src_any && dst_match) ||
1601 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001602 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603 }
1604 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001606 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001607
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001608 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609}
1610
Andre Guedes8e9f9892012-04-24 21:02:55 -03001611int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1612 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001614 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616 struct l2cap_conn *conn;
1617 struct hci_conn *hcon;
1618 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001619 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001620 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001622 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301623 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001625 hdev = hci_get_route(dst, src);
1626 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 return -EHOSTUNREACH;
1628
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001629 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001631 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001632
1633 /* PSM must be odd and lsb of upper byte must be 0 */
1634 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001635 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001636 err = -EINVAL;
1637 goto done;
1638 }
1639
1640 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1641 err = -EINVAL;
1642 goto done;
1643 }
1644
1645 switch (chan->mode) {
1646 case L2CAP_MODE_BASIC:
1647 break;
1648 case L2CAP_MODE_ERTM:
1649 case L2CAP_MODE_STREAMING:
1650 if (!disable_ertm)
1651 break;
1652 /* fall through */
1653 default:
1654 err = -ENOTSUPP;
1655 goto done;
1656 }
1657
Gustavo Padovan0797e012012-05-27 22:27:54 -03001658 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001659 case BT_CONNECT:
1660 case BT_CONNECT2:
1661 case BT_CONFIG:
1662 /* Already connecting */
1663 err = 0;
1664 goto done;
1665
1666 case BT_CONNECTED:
1667 /* Already connected */
1668 err = -EISCONN;
1669 goto done;
1670
1671 case BT_OPEN:
1672 case BT_BOUND:
1673 /* Can connect */
1674 break;
1675
1676 default:
1677 err = -EBADFD;
1678 goto done;
1679 }
1680
1681 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001682 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001683 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001684 release_sock(sk);
1685
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001686 chan->psm = psm;
1687 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001689 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001690
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001691 if (chan->dcid == L2CAP_CID_LE_DATA)
Andre Guedes8e9f9892012-04-24 21:02:55 -03001692 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001693 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001694 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001695 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001696 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001697
Ville Tervo30e76272011-02-22 16:10:53 -03001698 if (IS_ERR(hcon)) {
1699 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001701 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702
1703 conn = l2cap_conn_add(hcon, 0);
1704 if (!conn) {
1705 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001706 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 goto done;
1708 }
1709
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001710 if (hcon->type == LE_LINK) {
1711 err = 0;
1712
1713 if (!list_empty(&conn->chan_l)) {
1714 err = -EBUSY;
1715 hci_conn_put(hcon);
1716 }
1717
1718 if (err)
1719 goto done;
1720 }
1721
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 /* Update source addr of the socket */
1723 bacpy(src, conn->src);
1724
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001725 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001726 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001727 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001728
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001729 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001730 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731
1732 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001733 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001734 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001735 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001736 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001737 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001738 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 }
1740
Ville Tervo30e76272011-02-22 16:10:53 -03001741 err = 0;
1742
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001744 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001745 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746 hci_dev_put(hdev);
1747 return err;
1748}
1749
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001750int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001751{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001752 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001753 DECLARE_WAITQUEUE(wait, current);
1754 int err = 0;
1755 int timeo = HZ/5;
1756
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001757 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001758 set_current_state(TASK_INTERRUPTIBLE);
1759 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001760 if (!timeo)
1761 timeo = HZ/5;
1762
1763 if (signal_pending(current)) {
1764 err = sock_intr_errno(timeo);
1765 break;
1766 }
1767
1768 release_sock(sk);
1769 timeo = schedule_timeout(timeo);
1770 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001771 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001772
1773 err = sock_error(sk);
1774 if (err)
1775 break;
1776 }
1777 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001778 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001779 return err;
1780}
1781
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001782static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001783{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001784 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001785 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001786
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001787 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001788
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001789 l2cap_chan_lock(chan);
1790
Mat Martineau80909e02012-05-17 20:53:50 -07001791 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001792 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001793 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001794 return;
1795 }
1796
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001797 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001798
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001799 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001800 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001801}
1802
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001803static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001804{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001805 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001806 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001807
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001808 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001809
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001810 l2cap_chan_lock(chan);
1811
Mat Martineau80909e02012-05-17 20:53:50 -07001812 if (!chan->conn) {
1813 l2cap_chan_unlock(chan);
1814 l2cap_chan_put(chan);
1815 return;
1816 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001817
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001818 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001819 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001820 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001821}
1822
Gustavo Padovand6603662012-05-21 13:58:22 -03001823static void l2cap_streaming_send(struct l2cap_chan *chan,
1824 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001825{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001826 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001827 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001828
Mat Martineau37339372012-05-17 20:53:33 -07001829 BT_DBG("chan %p, skbs %p", chan, skbs);
1830
Mat Martineaub99e13a2012-10-23 15:24:19 -07001831 if (__chan_is_moving(chan))
1832 return;
1833
Mat Martineau37339372012-05-17 20:53:33 -07001834 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1835
1836 while (!skb_queue_empty(&chan->tx_q)) {
1837
1838 skb = skb_dequeue(&chan->tx_q);
1839
1840 bt_cb(skb)->control.retries = 1;
1841 control = &bt_cb(skb)->control;
1842
1843 control->reqseq = 0;
1844 control->txseq = chan->next_tx_seq;
1845
1846 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001847
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001848 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001849 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1850 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001851 }
1852
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001853 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001854
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001855 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001856
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001857 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001858 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001859 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001860}
1861
Szymon Janc67c9e842011-07-28 16:24:33 +02001862static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001863{
1864 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001865 struct l2cap_ctrl *control;
1866 int sent = 0;
1867
1868 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001869
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001870 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001871 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001872
Mat Martineau94122bb2012-05-02 09:42:02 -07001873 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1874 return 0;
1875
Mat Martineaub99e13a2012-10-23 15:24:19 -07001876 if (__chan_is_moving(chan))
1877 return 0;
1878
Mat Martineau18a48e72012-05-17 20:53:34 -07001879 while (chan->tx_send_head &&
1880 chan->unacked_frames < chan->remote_tx_win &&
1881 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001882
Mat Martineau18a48e72012-05-17 20:53:34 -07001883 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001884
Mat Martineau18a48e72012-05-17 20:53:34 -07001885 bt_cb(skb)->control.retries = 1;
1886 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001887
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001888 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001889 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001890
Mat Martineau18a48e72012-05-17 20:53:34 -07001891 control->reqseq = chan->buffer_seq;
1892 chan->last_acked_seq = chan->buffer_seq;
1893 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001894
Mat Martineau18a48e72012-05-17 20:53:34 -07001895 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001896
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001897 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001898 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1899 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001900 }
1901
Mat Martineau18a48e72012-05-17 20:53:34 -07001902 /* Clone after data has been modified. Data is assumed to be
1903 read-only (for locking purposes) on cloned sk_buffs.
1904 */
1905 tx_skb = skb_clone(skb, GFP_KERNEL);
1906
1907 if (!tx_skb)
1908 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001909
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001910 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001911
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001912 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001913 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001914 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001915 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001916
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001917 if (skb_queue_is_last(&chan->tx_q, skb))
1918 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001919 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001920 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001921
1922 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001923 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001924 }
1925
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001926 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
1927 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07001928
1929 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001930}
1931
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001932static void l2cap_ertm_resend(struct l2cap_chan *chan)
1933{
1934 struct l2cap_ctrl control;
1935 struct sk_buff *skb;
1936 struct sk_buff *tx_skb;
1937 u16 seq;
1938
1939 BT_DBG("chan %p", chan);
1940
1941 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1942 return;
1943
Mat Martineaub99e13a2012-10-23 15:24:19 -07001944 if (__chan_is_moving(chan))
1945 return;
1946
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001947 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1948 seq = l2cap_seq_list_pop(&chan->retrans_list);
1949
1950 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1951 if (!skb) {
1952 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01001953 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001954 continue;
1955 }
1956
1957 bt_cb(skb)->control.retries++;
1958 control = bt_cb(skb)->control;
1959
1960 if (chan->max_tx != 0 &&
1961 bt_cb(skb)->control.retries > chan->max_tx) {
1962 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001963 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001964 l2cap_seq_list_clear(&chan->retrans_list);
1965 break;
1966 }
1967
1968 control.reqseq = chan->buffer_seq;
1969 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
1970 control.final = 1;
1971 else
1972 control.final = 0;
1973
1974 if (skb_cloned(skb)) {
1975 /* Cloned sk_buffs are read-only, so we need a
1976 * writeable copy
1977 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001978 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001979 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001980 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001981 }
1982
1983 if (!tx_skb) {
1984 l2cap_seq_list_clear(&chan->retrans_list);
1985 break;
1986 }
1987
1988 /* Update skb contents */
1989 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1990 put_unaligned_le32(__pack_extended_control(&control),
1991 tx_skb->data + L2CAP_HDR_SIZE);
1992 } else {
1993 put_unaligned_le16(__pack_enhanced_control(&control),
1994 tx_skb->data + L2CAP_HDR_SIZE);
1995 }
1996
1997 if (chan->fcs == L2CAP_FCS_CRC16) {
1998 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
1999 put_unaligned_le16(fcs, skb_put(tx_skb,
2000 L2CAP_FCS_SIZE));
2001 }
2002
2003 l2cap_do_send(chan, tx_skb);
2004
2005 BT_DBG("Resent txseq %d", control.txseq);
2006
2007 chan->last_acked_seq = chan->buffer_seq;
2008 }
2009}
2010
Mat Martineauf80842a2012-05-17 20:53:46 -07002011static void l2cap_retransmit(struct l2cap_chan *chan,
2012 struct l2cap_ctrl *control)
2013{
2014 BT_DBG("chan %p, control %p", chan, control);
2015
2016 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2017 l2cap_ertm_resend(chan);
2018}
2019
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002020static void l2cap_retransmit_all(struct l2cap_chan *chan,
2021 struct l2cap_ctrl *control)
2022{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002023 struct sk_buff *skb;
2024
2025 BT_DBG("chan %p, control %p", chan, control);
2026
2027 if (control->poll)
2028 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2029
2030 l2cap_seq_list_clear(&chan->retrans_list);
2031
2032 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2033 return;
2034
2035 if (chan->unacked_frames) {
2036 skb_queue_walk(&chan->tx_q, skb) {
2037 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002038 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002039 break;
2040 }
2041
2042 skb_queue_walk_from(&chan->tx_q, skb) {
2043 if (skb == chan->tx_send_head)
2044 break;
2045
2046 l2cap_seq_list_append(&chan->retrans_list,
2047 bt_cb(skb)->control.txseq);
2048 }
2049
2050 l2cap_ertm_resend(chan);
2051 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002052}
2053
Szymon Jancb17e73b2012-01-11 10:59:47 +01002054static void l2cap_send_ack(struct l2cap_chan *chan)
2055{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002056 struct l2cap_ctrl control;
2057 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2058 chan->last_acked_seq);
2059 int threshold;
2060
2061 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2062 chan, chan->last_acked_seq, chan->buffer_seq);
2063
2064 memset(&control, 0, sizeof(control));
2065 control.sframe = 1;
2066
2067 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2068 chan->rx_state == L2CAP_RX_STATE_RECV) {
2069 __clear_ack_timer(chan);
2070 control.super = L2CAP_SUPER_RNR;
2071 control.reqseq = chan->buffer_seq;
2072 l2cap_send_sframe(chan, &control);
2073 } else {
2074 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2075 l2cap_ertm_send(chan);
2076 /* If any i-frames were sent, they included an ack */
2077 if (chan->buffer_seq == chan->last_acked_seq)
2078 frames_to_ack = 0;
2079 }
2080
Mat Martineauc20f8e32012-07-10 05:47:07 -07002081 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002082 * Calculate without mul or div
2083 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002084 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002085 threshold += threshold << 1;
2086 threshold >>= 2;
2087
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002088 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002089 threshold);
2090
2091 if (frames_to_ack >= threshold) {
2092 __clear_ack_timer(chan);
2093 control.super = L2CAP_SUPER_RR;
2094 control.reqseq = chan->buffer_seq;
2095 l2cap_send_sframe(chan, &control);
2096 frames_to_ack = 0;
2097 }
2098
2099 if (frames_to_ack)
2100 __set_ack_timer(chan);
2101 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002102}
2103
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002104static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2105 struct msghdr *msg, int len,
2106 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002107{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002108 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002109 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002110 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002111
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002112 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002113 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002114
2115 sent += count;
2116 len -= count;
2117
2118 /* Continuation fragments (no L2CAP header) */
2119 frag = &skb_shinfo(skb)->frag_list;
2120 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002121 struct sk_buff *tmp;
2122
Linus Torvalds1da177e2005-04-16 15:20:36 -07002123 count = min_t(unsigned int, conn->mtu, len);
2124
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002125 tmp = chan->ops->alloc_skb(chan, count,
2126 msg->msg_flags & MSG_DONTWAIT);
2127 if (IS_ERR(tmp))
2128 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002129
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002130 *frag = tmp;
2131
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002132 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2133 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002134
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002135 (*frag)->priority = skb->priority;
2136
Linus Torvalds1da177e2005-04-16 15:20:36 -07002137 sent += count;
2138 len -= count;
2139
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002140 skb->len += (*frag)->len;
2141 skb->data_len += (*frag)->len;
2142
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143 frag = &(*frag)->next;
2144 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145
2146 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002147}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002148
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002149static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002150 struct msghdr *msg, size_t len,
2151 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002152{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002153 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002154 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002155 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002156 struct l2cap_hdr *lh;
2157
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002158 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002159
2160 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002161
2162 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002163 msg->msg_flags & MSG_DONTWAIT);
2164 if (IS_ERR(skb))
2165 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002166
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002167 skb->priority = priority;
2168
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002169 /* Create L2CAP header */
2170 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002171 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002172 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
2173 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002174
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002175 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002176 if (unlikely(err < 0)) {
2177 kfree_skb(skb);
2178 return ERR_PTR(err);
2179 }
2180 return skb;
2181}
2182
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002183static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002184 struct msghdr *msg, size_t len,
2185 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002186{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002187 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002188 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002189 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002190 struct l2cap_hdr *lh;
2191
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002192 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002193
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002194 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002195
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002196 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002197 msg->msg_flags & MSG_DONTWAIT);
2198 if (IS_ERR(skb))
2199 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002200
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002201 skb->priority = priority;
2202
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002203 /* Create L2CAP header */
2204 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002205 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002206 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002207
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002208 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002209 if (unlikely(err < 0)) {
2210 kfree_skb(skb);
2211 return ERR_PTR(err);
2212 }
2213 return skb;
2214}
2215
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002216static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002217 struct msghdr *msg, size_t len,
2218 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002219{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002220 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002221 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002222 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002223 struct l2cap_hdr *lh;
2224
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002225 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002226
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002227 if (!conn)
2228 return ERR_PTR(-ENOTCONN);
2229
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002230 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002231
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002232 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002233 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002234
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002235 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002236 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002237
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002238 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002239
2240 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002241 msg->msg_flags & MSG_DONTWAIT);
2242 if (IS_ERR(skb))
2243 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002244
2245 /* Create L2CAP header */
2246 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002247 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002248 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002249
Mat Martineau18a48e72012-05-17 20:53:34 -07002250 /* Control header is populated later */
2251 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2252 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2253 else
2254 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002255
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002256 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002257 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002258
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002259 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002260 if (unlikely(err < 0)) {
2261 kfree_skb(skb);
2262 return ERR_PTR(err);
2263 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002264
Mat Martineau18a48e72012-05-17 20:53:34 -07002265 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002266 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002267 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002268}
2269
Mat Martineau94122bb2012-05-02 09:42:02 -07002270static int l2cap_segment_sdu(struct l2cap_chan *chan,
2271 struct sk_buff_head *seg_queue,
2272 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002273{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002274 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002275 u16 sdu_len;
2276 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002277 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002278
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002279 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002280
Mat Martineau94122bb2012-05-02 09:42:02 -07002281 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2282 * so fragmented skbs are not used. The HCI layer's handling
2283 * of fragmented skbs is not compatible with ERTM's queueing.
2284 */
2285
2286 /* PDU size is derived from the HCI MTU */
2287 pdu_len = chan->conn->mtu;
2288
Mat Martineaua5495742012-10-23 15:24:21 -07002289 /* Constrain PDU size for BR/EDR connections */
2290 if (!chan->hs_hcon)
2291 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002292
2293 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002294 if (chan->fcs)
2295 pdu_len -= L2CAP_FCS_SIZE;
2296
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002297 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002298
2299 /* Remote device may have requested smaller PDUs */
2300 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2301
2302 if (len <= pdu_len) {
2303 sar = L2CAP_SAR_UNSEGMENTED;
2304 sdu_len = 0;
2305 pdu_len = len;
2306 } else {
2307 sar = L2CAP_SAR_START;
2308 sdu_len = len;
2309 pdu_len -= L2CAP_SDULEN_SIZE;
2310 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002311
2312 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002313 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002314
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002315 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002316 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002317 return PTR_ERR(skb);
2318 }
2319
Mat Martineau94122bb2012-05-02 09:42:02 -07002320 bt_cb(skb)->control.sar = sar;
2321 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002322
Mat Martineau94122bb2012-05-02 09:42:02 -07002323 len -= pdu_len;
2324 if (sdu_len) {
2325 sdu_len = 0;
2326 pdu_len += L2CAP_SDULEN_SIZE;
2327 }
2328
2329 if (len <= pdu_len) {
2330 sar = L2CAP_SAR_END;
2331 pdu_len = len;
2332 } else {
2333 sar = L2CAP_SAR_CONTINUE;
2334 }
2335 }
2336
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002337 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002338}
2339
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002340int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002341 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002342{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002343 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002344 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002345 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002346
2347 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002348 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002349 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002350 if (IS_ERR(skb))
2351 return PTR_ERR(skb);
2352
2353 l2cap_do_send(chan, skb);
2354 return len;
2355 }
2356
2357 switch (chan->mode) {
2358 case L2CAP_MODE_BASIC:
2359 /* Check outgoing MTU */
2360 if (len > chan->omtu)
2361 return -EMSGSIZE;
2362
2363 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002364 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002365 if (IS_ERR(skb))
2366 return PTR_ERR(skb);
2367
2368 l2cap_do_send(chan, skb);
2369 err = len;
2370 break;
2371
2372 case L2CAP_MODE_ERTM:
2373 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002374 /* Check outgoing MTU */
2375 if (len > chan->omtu) {
2376 err = -EMSGSIZE;
2377 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002378 }
2379
Mat Martineau94122bb2012-05-02 09:42:02 -07002380 __skb_queue_head_init(&seg_queue);
2381
2382 /* Do segmentation before calling in to the state machine,
2383 * since it's possible to block while waiting for memory
2384 * allocation.
2385 */
2386 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2387
2388 /* The channel could have been closed while segmenting,
2389 * check that it is still connected.
2390 */
2391 if (chan->state != BT_CONNECTED) {
2392 __skb_queue_purge(&seg_queue);
2393 err = -ENOTCONN;
2394 }
2395
2396 if (err)
2397 break;
2398
Mat Martineau37339372012-05-17 20:53:33 -07002399 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002400 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002401 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002402 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002403
Gustavo Padovand6603662012-05-21 13:58:22 -03002404 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002405
Mat Martineau94122bb2012-05-02 09:42:02 -07002406 /* If the skbs were not queued for sending, they'll still be in
2407 * seg_queue and need to be purged.
2408 */
2409 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002410 break;
2411
2412 default:
2413 BT_DBG("bad state %1.1x", chan->mode);
2414 err = -EBADFD;
2415 }
2416
2417 return err;
2418}
2419
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002420static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2421{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002422 struct l2cap_ctrl control;
2423 u16 seq;
2424
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002425 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002426
2427 memset(&control, 0, sizeof(control));
2428 control.sframe = 1;
2429 control.super = L2CAP_SUPER_SREJ;
2430
2431 for (seq = chan->expected_tx_seq; seq != txseq;
2432 seq = __next_seq(chan, seq)) {
2433 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2434 control.reqseq = seq;
2435 l2cap_send_sframe(chan, &control);
2436 l2cap_seq_list_append(&chan->srej_list, seq);
2437 }
2438 }
2439
2440 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002441}
2442
2443static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2444{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002445 struct l2cap_ctrl control;
2446
2447 BT_DBG("chan %p", chan);
2448
2449 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2450 return;
2451
2452 memset(&control, 0, sizeof(control));
2453 control.sframe = 1;
2454 control.super = L2CAP_SUPER_SREJ;
2455 control.reqseq = chan->srej_list.tail;
2456 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002457}
2458
2459static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2460{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002461 struct l2cap_ctrl control;
2462 u16 initial_head;
2463 u16 seq;
2464
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002465 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002466
2467 memset(&control, 0, sizeof(control));
2468 control.sframe = 1;
2469 control.super = L2CAP_SUPER_SREJ;
2470
2471 /* Capture initial list head to allow only one pass through the list. */
2472 initial_head = chan->srej_list.head;
2473
2474 do {
2475 seq = l2cap_seq_list_pop(&chan->srej_list);
2476 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2477 break;
2478
2479 control.reqseq = seq;
2480 l2cap_send_sframe(chan, &control);
2481 l2cap_seq_list_append(&chan->srej_list, seq);
2482 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002483}
2484
Mat Martineau608bcc62012-05-17 20:53:32 -07002485static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2486{
2487 struct sk_buff *acked_skb;
2488 u16 ackseq;
2489
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002490 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002491
2492 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2493 return;
2494
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002495 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002496 chan->expected_ack_seq, chan->unacked_frames);
2497
2498 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2499 ackseq = __next_seq(chan, ackseq)) {
2500
2501 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2502 if (acked_skb) {
2503 skb_unlink(acked_skb, &chan->tx_q);
2504 kfree_skb(acked_skb);
2505 chan->unacked_frames--;
2506 }
2507 }
2508
2509 chan->expected_ack_seq = reqseq;
2510
2511 if (chan->unacked_frames == 0)
2512 __clear_retrans_timer(chan);
2513
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002514 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002515}
2516
2517static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2518{
2519 BT_DBG("chan %p", chan);
2520
2521 chan->expected_tx_seq = chan->buffer_seq;
2522 l2cap_seq_list_clear(&chan->srej_list);
2523 skb_queue_purge(&chan->srej_q);
2524 chan->rx_state = L2CAP_RX_STATE_RECV;
2525}
2526
Gustavo Padovand6603662012-05-21 13:58:22 -03002527static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2528 struct l2cap_ctrl *control,
2529 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002530{
Mat Martineau608bcc62012-05-17 20:53:32 -07002531 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2532 event);
2533
2534 switch (event) {
2535 case L2CAP_EV_DATA_REQUEST:
2536 if (chan->tx_send_head == NULL)
2537 chan->tx_send_head = skb_peek(skbs);
2538
2539 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2540 l2cap_ertm_send(chan);
2541 break;
2542 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2543 BT_DBG("Enter LOCAL_BUSY");
2544 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2545
2546 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2547 /* The SREJ_SENT state must be aborted if we are to
2548 * enter the LOCAL_BUSY state.
2549 */
2550 l2cap_abort_rx_srej_sent(chan);
2551 }
2552
2553 l2cap_send_ack(chan);
2554
2555 break;
2556 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2557 BT_DBG("Exit LOCAL_BUSY");
2558 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2559
2560 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2561 struct l2cap_ctrl local_control;
2562
2563 memset(&local_control, 0, sizeof(local_control));
2564 local_control.sframe = 1;
2565 local_control.super = L2CAP_SUPER_RR;
2566 local_control.poll = 1;
2567 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002568 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002569
2570 chan->retry_count = 1;
2571 __set_monitor_timer(chan);
2572 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2573 }
2574 break;
2575 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2576 l2cap_process_reqseq(chan, control->reqseq);
2577 break;
2578 case L2CAP_EV_EXPLICIT_POLL:
2579 l2cap_send_rr_or_rnr(chan, 1);
2580 chan->retry_count = 1;
2581 __set_monitor_timer(chan);
2582 __clear_ack_timer(chan);
2583 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2584 break;
2585 case L2CAP_EV_RETRANS_TO:
2586 l2cap_send_rr_or_rnr(chan, 1);
2587 chan->retry_count = 1;
2588 __set_monitor_timer(chan);
2589 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2590 break;
2591 case L2CAP_EV_RECV_FBIT:
2592 /* Nothing to process */
2593 break;
2594 default:
2595 break;
2596 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002597}
2598
Gustavo Padovand6603662012-05-21 13:58:22 -03002599static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2600 struct l2cap_ctrl *control,
2601 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002602{
Mat Martineau608bcc62012-05-17 20:53:32 -07002603 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2604 event);
2605
2606 switch (event) {
2607 case L2CAP_EV_DATA_REQUEST:
2608 if (chan->tx_send_head == NULL)
2609 chan->tx_send_head = skb_peek(skbs);
2610 /* Queue data, but don't send. */
2611 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2612 break;
2613 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2614 BT_DBG("Enter LOCAL_BUSY");
2615 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2616
2617 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2618 /* The SREJ_SENT state must be aborted if we are to
2619 * enter the LOCAL_BUSY state.
2620 */
2621 l2cap_abort_rx_srej_sent(chan);
2622 }
2623
2624 l2cap_send_ack(chan);
2625
2626 break;
2627 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2628 BT_DBG("Exit LOCAL_BUSY");
2629 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2630
2631 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2632 struct l2cap_ctrl local_control;
2633 memset(&local_control, 0, sizeof(local_control));
2634 local_control.sframe = 1;
2635 local_control.super = L2CAP_SUPER_RR;
2636 local_control.poll = 1;
2637 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002638 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002639
2640 chan->retry_count = 1;
2641 __set_monitor_timer(chan);
2642 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2643 }
2644 break;
2645 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2646 l2cap_process_reqseq(chan, control->reqseq);
2647
2648 /* Fall through */
2649
2650 case L2CAP_EV_RECV_FBIT:
2651 if (control && control->final) {
2652 __clear_monitor_timer(chan);
2653 if (chan->unacked_frames > 0)
2654 __set_retrans_timer(chan);
2655 chan->retry_count = 0;
2656 chan->tx_state = L2CAP_TX_STATE_XMIT;
2657 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2658 }
2659 break;
2660 case L2CAP_EV_EXPLICIT_POLL:
2661 /* Ignore */
2662 break;
2663 case L2CAP_EV_MONITOR_TO:
2664 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2665 l2cap_send_rr_or_rnr(chan, 1);
2666 __set_monitor_timer(chan);
2667 chan->retry_count++;
2668 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002669 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002670 }
2671 break;
2672 default:
2673 break;
2674 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002675}
2676
Gustavo Padovand6603662012-05-21 13:58:22 -03002677static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2678 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002679{
Mat Martineau608bcc62012-05-17 20:53:32 -07002680 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2681 chan, control, skbs, event, chan->tx_state);
2682
2683 switch (chan->tx_state) {
2684 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002685 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002686 break;
2687 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002688 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002689 break;
2690 default:
2691 /* Ignore event */
2692 break;
2693 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002694}
2695
Mat Martineau4b51dae92012-05-17 20:53:37 -07002696static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2697 struct l2cap_ctrl *control)
2698{
2699 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002700 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002701}
2702
Mat Martineauf80842a2012-05-17 20:53:46 -07002703static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2704 struct l2cap_ctrl *control)
2705{
2706 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002707 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002708}
2709
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710/* Copy frame to all raw sockets on that connection */
2711static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2712{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002713 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002714 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002715
2716 BT_DBG("conn %p", conn);
2717
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002718 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002719
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002720 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002721 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002722 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002723 continue;
2724
2725 /* Don't send frame to the socket it came from */
2726 if (skb->sk == sk)
2727 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002728 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002729 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002730 continue;
2731
Gustavo Padovan80b98022012-05-27 22:27:51 -03002732 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002733 kfree_skb(nskb);
2734 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002735
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002736 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002737}
2738
2739/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002740static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2741 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002742{
2743 struct sk_buff *skb, **frag;
2744 struct l2cap_cmd_hdr *cmd;
2745 struct l2cap_hdr *lh;
2746 int len, count;
2747
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002748 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2749 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750
2751 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2752 count = min_t(unsigned int, conn->mtu, len);
2753
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002754 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002755 if (!skb)
2756 return NULL;
2757
2758 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002759 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002760
2761 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002762 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002763 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002764 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002765
2766 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2767 cmd->code = code;
2768 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002769 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002770
2771 if (dlen) {
2772 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2773 memcpy(skb_put(skb, count), data, count);
2774 data += count;
2775 }
2776
2777 len -= skb->len;
2778
2779 /* Continuation fragments (no L2CAP header) */
2780 frag = &skb_shinfo(skb)->frag_list;
2781 while (len) {
2782 count = min_t(unsigned int, conn->mtu, len);
2783
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002784 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002785 if (!*frag)
2786 goto fail;
2787
2788 memcpy(skb_put(*frag, count), data, count);
2789
2790 len -= count;
2791 data += count;
2792
2793 frag = &(*frag)->next;
2794 }
2795
2796 return skb;
2797
2798fail:
2799 kfree_skb(skb);
2800 return NULL;
2801}
2802
Gustavo Padovan2d792812012-10-06 10:07:01 +01002803static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2804 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002805{
2806 struct l2cap_conf_opt *opt = *ptr;
2807 int len;
2808
2809 len = L2CAP_CONF_OPT_SIZE + opt->len;
2810 *ptr += len;
2811
2812 *type = opt->type;
2813 *olen = opt->len;
2814
2815 switch (opt->len) {
2816 case 1:
2817 *val = *((u8 *) opt->val);
2818 break;
2819
2820 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002821 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002822 break;
2823
2824 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002825 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826 break;
2827
2828 default:
2829 *val = (unsigned long) opt->val;
2830 break;
2831 }
2832
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002833 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834 return len;
2835}
2836
Linus Torvalds1da177e2005-04-16 15:20:36 -07002837static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2838{
2839 struct l2cap_conf_opt *opt = *ptr;
2840
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002841 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002842
2843 opt->type = type;
2844 opt->len = len;
2845
2846 switch (len) {
2847 case 1:
2848 *((u8 *) opt->val) = val;
2849 break;
2850
2851 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002852 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002853 break;
2854
2855 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002856 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002857 break;
2858
2859 default:
2860 memcpy(opt->val, (void *) val, len);
2861 break;
2862 }
2863
2864 *ptr += L2CAP_CONF_OPT_SIZE + len;
2865}
2866
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002867static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2868{
2869 struct l2cap_conf_efs efs;
2870
Szymon Janc1ec918c2011-11-16 09:32:21 +01002871 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002872 case L2CAP_MODE_ERTM:
2873 efs.id = chan->local_id;
2874 efs.stype = chan->local_stype;
2875 efs.msdu = cpu_to_le16(chan->local_msdu);
2876 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002877 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002878 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002879 break;
2880
2881 case L2CAP_MODE_STREAMING:
2882 efs.id = 1;
2883 efs.stype = L2CAP_SERV_BESTEFFORT;
2884 efs.msdu = cpu_to_le16(chan->local_msdu);
2885 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2886 efs.acc_lat = 0;
2887 efs.flush_to = 0;
2888 break;
2889
2890 default:
2891 return;
2892 }
2893
2894 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002895 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002896}
2897
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002898static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002899{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002900 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07002901 ack_timer.work);
2902 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002903
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02002904 BT_DBG("chan %p", chan);
2905
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002906 l2cap_chan_lock(chan);
2907
Mat Martineau03625202012-05-17 20:53:51 -07002908 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2909 chan->last_acked_seq);
2910
2911 if (frames_to_ack)
2912 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002913
2914 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01002915 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002916}
2917
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03002918int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002919{
Mat Martineau3c588192012-04-11 10:48:42 -07002920 int err;
2921
Mat Martineau105bdf92012-04-27 16:50:48 -07002922 chan->next_tx_seq = 0;
2923 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002924 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002925 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002926 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002927 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07002928 chan->last_acked_seq = 0;
2929 chan->sdu = NULL;
2930 chan->sdu_last_frag = NULL;
2931 chan->sdu_len = 0;
2932
Mat Martineaud34c34f2012-05-14 14:49:27 -07002933 skb_queue_head_init(&chan->tx_q);
2934
Mat Martineau08333282012-10-23 15:24:06 -07002935 chan->local_amp_id = 0;
2936 chan->move_id = 0;
2937 chan->move_state = L2CAP_MOVE_STABLE;
2938 chan->move_role = L2CAP_MOVE_ROLE_NONE;
2939
Mat Martineau105bdf92012-04-27 16:50:48 -07002940 if (chan->mode != L2CAP_MODE_ERTM)
2941 return 0;
2942
2943 chan->rx_state = L2CAP_RX_STATE_RECV;
2944 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002945
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002946 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
2947 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
2948 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002949
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03002950 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002951
Mat Martineau3c588192012-04-11 10:48:42 -07002952 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
2953 if (err < 0)
2954 return err;
2955
Mat Martineau9dc9aff2012-05-17 16:20:14 -07002956 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
2957 if (err < 0)
2958 l2cap_seq_list_free(&chan->srej_list);
2959
2960 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002961}
2962
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002963static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2964{
2965 switch (mode) {
2966 case L2CAP_MODE_STREAMING:
2967 case L2CAP_MODE_ERTM:
2968 if (l2cap_mode_supported(mode, remote_feat_mask))
2969 return mode;
2970 /* fall through */
2971 default:
2972 return L2CAP_MODE_BASIC;
2973 }
2974}
2975
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002976static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
2977{
2978 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
2979}
2980
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002981static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
2982{
2983 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
2984}
2985
Mat Martineau36c86c82012-10-23 15:24:20 -07002986static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
2987 struct l2cap_conf_rfc *rfc)
2988{
2989 if (chan->local_amp_id && chan->hs_hcon) {
2990 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
2991
2992 /* Class 1 devices have must have ERTM timeouts
2993 * exceeding the Link Supervision Timeout. The
2994 * default Link Supervision Timeout for AMP
2995 * controllers is 10 seconds.
2996 *
2997 * Class 1 devices use 0xffffffff for their
2998 * best-effort flush timeout, so the clamping logic
2999 * will result in a timeout that meets the above
3000 * requirement. ERTM timeouts are 16-bit values, so
3001 * the maximum timeout is 65.535 seconds.
3002 */
3003
3004 /* Convert timeout to milliseconds and round */
3005 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3006
3007 /* This is the recommended formula for class 2 devices
3008 * that start ERTM timers when packets are sent to the
3009 * controller.
3010 */
3011 ertm_to = 3 * ertm_to + 500;
3012
3013 if (ertm_to > 0xffff)
3014 ertm_to = 0xffff;
3015
3016 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3017 rfc->monitor_timeout = rfc->retrans_timeout;
3018 } else {
3019 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3020 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3021 }
3022}
3023
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003024static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3025{
3026 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003027 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003028 /* use extended control field */
3029 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003030 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3031 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003032 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003033 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003034 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3035 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003036 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003037}
3038
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003039static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003040{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003041 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003042 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003043 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003044 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003045
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003046 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003047
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003048 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003049 goto done;
3050
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003051 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003052 case L2CAP_MODE_STREAMING:
3053 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003054 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003055 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003056
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003057 if (__l2cap_efs_supported(chan))
3058 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3059
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003060 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003061 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003062 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003063 break;
3064 }
3065
3066done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003067 if (chan->imtu != L2CAP_DEFAULT_MTU)
3068 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003069
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003070 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003071 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003072 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003073 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003074 break;
3075
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003076 rfc.mode = L2CAP_MODE_BASIC;
3077 rfc.txwin_size = 0;
3078 rfc.max_transmit = 0;
3079 rfc.retrans_timeout = 0;
3080 rfc.monitor_timeout = 0;
3081 rfc.max_pdu_size = 0;
3082
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003083 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003084 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003085 break;
3086
3087 case L2CAP_MODE_ERTM:
3088 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003089 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003090
3091 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003092
3093 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003094 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3095 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003096 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003097
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003098 l2cap_txwin_setup(chan);
3099
3100 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003101 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003102
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003103 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003104 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003105
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003106 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3107 l2cap_add_opt_efs(&ptr, chan);
3108
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003109 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003110 break;
3111
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003112 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01003113 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003114 chan->fcs = L2CAP_FCS_NONE;
3115 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003116 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003117
3118 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3119 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003120 chan->tx_win);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003121 break;
3122
3123 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003124 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003125 rfc.mode = L2CAP_MODE_STREAMING;
3126 rfc.txwin_size = 0;
3127 rfc.max_transmit = 0;
3128 rfc.retrans_timeout = 0;
3129 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003130
3131 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003132 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3133 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003134 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003135
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003136 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003137 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003138
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003139 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3140 l2cap_add_opt_efs(&ptr, chan);
3141
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003142 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003143 break;
3144
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003145 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01003146 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003147 chan->fcs = L2CAP_FCS_NONE;
3148 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003149 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003150 break;
3151 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003152
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003153 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003154 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003155
3156 return ptr - data;
3157}
3158
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003159static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003160{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003161 struct l2cap_conf_rsp *rsp = data;
3162 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003163 void *req = chan->conf_req;
3164 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003165 int type, hint, olen;
3166 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003167 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003168 struct l2cap_conf_efs efs;
3169 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003170 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003171 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003172 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003173
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003174 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003175
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003176 while (len >= L2CAP_CONF_OPT_SIZE) {
3177 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003178
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003179 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003180 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003181
3182 switch (type) {
3183 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003184 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003185 break;
3186
3187 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003188 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003189 break;
3190
3191 case L2CAP_CONF_QOS:
3192 break;
3193
Marcel Holtmann6464f352007-10-20 13:39:51 +02003194 case L2CAP_CONF_RFC:
3195 if (olen == sizeof(rfc))
3196 memcpy(&rfc, (void *) val, olen);
3197 break;
3198
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003199 case L2CAP_CONF_FCS:
3200 if (val == L2CAP_FCS_NONE)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003201 set_bit(CONF_NO_FCS_RECV, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003202 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003203
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003204 case L2CAP_CONF_EFS:
3205 remote_efs = 1;
3206 if (olen == sizeof(efs))
3207 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003208 break;
3209
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003210 case L2CAP_CONF_EWS:
3211 if (!enable_hs)
3212 return -ECONNREFUSED;
3213
3214 set_bit(FLAG_EXT_CTRL, &chan->flags);
3215 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003216 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003217 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003218 break;
3219
3220 default:
3221 if (hint)
3222 break;
3223
3224 result = L2CAP_CONF_UNKNOWN;
3225 *((u8 *) ptr++) = type;
3226 break;
3227 }
3228 }
3229
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003230 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003231 goto done;
3232
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003233 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003234 case L2CAP_MODE_STREAMING:
3235 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003236 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003237 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003238 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003239 break;
3240 }
3241
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003242 if (remote_efs) {
3243 if (__l2cap_efs_supported(chan))
3244 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3245 else
3246 return -ECONNREFUSED;
3247 }
3248
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003249 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003250 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003251
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003252 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003253 }
3254
3255done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003256 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003257 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003258 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003259
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003260 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003261 return -ECONNREFUSED;
3262
Gustavo Padovan2d792812012-10-06 10:07:01 +01003263 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3264 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003265 }
3266
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003267 if (result == L2CAP_CONF_SUCCESS) {
3268 /* Configure output options and let the other side know
3269 * which ones we don't like. */
3270
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003271 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3272 result = L2CAP_CONF_UNACCEPT;
3273 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003274 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003275 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003276 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003277 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003278
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003279 if (remote_efs) {
3280 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003281 efs.stype != L2CAP_SERV_NOTRAFIC &&
3282 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003283
3284 result = L2CAP_CONF_UNACCEPT;
3285
3286 if (chan->num_conf_req >= 1)
3287 return -ECONNREFUSED;
3288
3289 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003290 sizeof(efs),
3291 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003292 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003293 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003294 result = L2CAP_CONF_PENDING;
3295 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003296 }
3297 }
3298
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003299 switch (rfc.mode) {
3300 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003301 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003302 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003303 break;
3304
3305 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003306 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3307 chan->remote_tx_win = rfc.txwin_size;
3308 else
3309 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3310
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003311 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003312
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003313 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003314 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3315 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003316 rfc.max_pdu_size = cpu_to_le16(size);
3317 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003318
Mat Martineau36c86c82012-10-23 15:24:20 -07003319 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003320
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003321 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003322
3323 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003324 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003325
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003326 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3327 chan->remote_id = efs.id;
3328 chan->remote_stype = efs.stype;
3329 chan->remote_msdu = le16_to_cpu(efs.msdu);
3330 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003331 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003332 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003333 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003334 chan->remote_sdu_itime =
3335 le32_to_cpu(efs.sdu_itime);
3336 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003337 sizeof(efs),
3338 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003339 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003340 break;
3341
3342 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003343 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003344 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3345 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003346 rfc.max_pdu_size = cpu_to_le16(size);
3347 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003348
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003349 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003350
Gustavo Padovan2d792812012-10-06 10:07:01 +01003351 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3352 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003353
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003354 break;
3355
3356 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003357 result = L2CAP_CONF_UNACCEPT;
3358
3359 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003360 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003361 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003362
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003363 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003364 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003365 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003366 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003367 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003368 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003369
3370 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003371}
3372
Gustavo Padovan2d792812012-10-06 10:07:01 +01003373static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3374 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003375{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003376 struct l2cap_conf_req *req = data;
3377 void *ptr = req->data;
3378 int type, olen;
3379 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003380 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003381 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003382
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003383 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003384
3385 while (len >= L2CAP_CONF_OPT_SIZE) {
3386 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3387
3388 switch (type) {
3389 case L2CAP_CONF_MTU:
3390 if (val < L2CAP_DEFAULT_MIN_MTU) {
3391 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003392 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003393 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003394 chan->imtu = val;
3395 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003396 break;
3397
3398 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003399 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003400 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003401 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003402 break;
3403
3404 case L2CAP_CONF_RFC:
3405 if (olen == sizeof(rfc))
3406 memcpy(&rfc, (void *)val, olen);
3407
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003408 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003409 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003410 return -ECONNREFUSED;
3411
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003412 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003413
3414 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003415 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003416 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003417
3418 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003419 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003420 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003421 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003422 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003423
3424 case L2CAP_CONF_EFS:
3425 if (olen == sizeof(efs))
3426 memcpy(&efs, (void *)val, olen);
3427
3428 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003429 efs.stype != L2CAP_SERV_NOTRAFIC &&
3430 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003431 return -ECONNREFUSED;
3432
Gustavo Padovan2d792812012-10-06 10:07:01 +01003433 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3434 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003435 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003436 }
3437 }
3438
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003439 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003440 return -ECONNREFUSED;
3441
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003442 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003443
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003444 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003445 switch (rfc.mode) {
3446 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003447 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3448 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3449 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003450 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3451 chan->ack_win = min_t(u16, chan->ack_win,
3452 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003453
3454 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3455 chan->local_msdu = le16_to_cpu(efs.msdu);
3456 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003457 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003458 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3459 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003460 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003461 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003462 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003463
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003464 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003465 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003466 }
3467 }
3468
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003469 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003470 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003471
3472 return ptr - data;
3473}
3474
Gustavo Padovan2d792812012-10-06 10:07:01 +01003475static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3476 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003477{
3478 struct l2cap_conf_rsp *rsp = data;
3479 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003480
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003481 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003482
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003483 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003484 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003485 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003486
3487 return ptr - data;
3488}
3489
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003490void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003491{
3492 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003493 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003494 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003495 u8 rsp_code;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003496
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003497 rsp.scid = cpu_to_le16(chan->dcid);
3498 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003499 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3500 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003501
3502 if (chan->hs_hcon)
3503 rsp_code = L2CAP_CREATE_CHAN_RSP;
3504 else
3505 rsp_code = L2CAP_CONN_RSP;
3506
3507 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3508
3509 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003510
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003511 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003512 return;
3513
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003514 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003515 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003516 chan->num_conf_req++;
3517}
3518
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003519static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003520{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003521 int type, olen;
3522 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003523 /* Use sane default values in case a misbehaving remote device
3524 * did not send an RFC or extended window size option.
3525 */
3526 u16 txwin_ext = chan->ack_win;
3527 struct l2cap_conf_rfc rfc = {
3528 .mode = chan->mode,
3529 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3530 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3531 .max_pdu_size = cpu_to_le16(chan->imtu),
3532 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3533 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003534
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003535 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003536
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003537 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003538 return;
3539
3540 while (len >= L2CAP_CONF_OPT_SIZE) {
3541 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3542
Mat Martineauc20f8e32012-07-10 05:47:07 -07003543 switch (type) {
3544 case L2CAP_CONF_RFC:
3545 if (olen == sizeof(rfc))
3546 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003547 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003548 case L2CAP_CONF_EWS:
3549 txwin_ext = val;
3550 break;
3551 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003552 }
3553
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003554 switch (rfc.mode) {
3555 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003556 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3557 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003558 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3559 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3560 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3561 else
3562 chan->ack_win = min_t(u16, chan->ack_win,
3563 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003564 break;
3565 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003566 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003567 }
3568}
3569
Gustavo Padovan2d792812012-10-06 10:07:01 +01003570static inline int l2cap_command_rej(struct l2cap_conn *conn,
3571 struct l2cap_cmd_hdr *cmd, u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003572{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003573 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003574
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003575 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003576 return 0;
3577
3578 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003579 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003580 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003581
3582 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003583 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003584
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003585 l2cap_conn_start(conn);
3586 }
3587
3588 return 0;
3589}
3590
Mat Martineau17009152012-10-23 15:24:07 -07003591static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3592 struct l2cap_cmd_hdr *cmd,
3593 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003594{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003595 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3596 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003597 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003598 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003599 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003600
3601 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003602 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003603
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003604 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003605
3606 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003607 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003608 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003609 result = L2CAP_CR_BAD_PSM;
3610 goto sendresp;
3611 }
3612
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003613 parent = pchan->sk;
3614
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003615 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003616 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003617
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003618 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003619 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003620 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003621 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003622 result = L2CAP_CR_SEC_BLOCK;
3623 goto response;
3624 }
3625
Linus Torvalds1da177e2005-04-16 15:20:36 -07003626 result = L2CAP_CR_NO_MEM;
3627
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003628 /* Check if we already have channel with that dcid */
3629 if (__l2cap_get_chan_by_dcid(conn, scid))
3630 goto response;
3631
Gustavo Padovan80b98022012-05-27 22:27:51 -03003632 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003633 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003634 goto response;
3635
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003636 sk = chan->sk;
3637
Linus Torvalds1da177e2005-04-16 15:20:36 -07003638 hci_conn_hold(conn->hcon);
3639
Linus Torvalds1da177e2005-04-16 15:20:36 -07003640 bacpy(&bt_sk(sk)->src, conn->src);
3641 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003642 chan->psm = psm;
3643 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003644 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003645
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003646 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003647
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003648 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003649
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003650 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003651
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003652 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003653
Marcel Holtmann984947d2009-02-06 23:35:19 +01003654 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003655 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003656 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003657 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003658 result = L2CAP_CR_PEND;
3659 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003660 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003661 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003662 /* Force pending result for AMP controllers.
3663 * The connection will succeed after the
3664 * physical link is up.
3665 */
3666 if (amp_id) {
3667 __l2cap_state_change(chan, BT_CONNECT2);
3668 result = L2CAP_CR_PEND;
3669 } else {
3670 __l2cap_state_change(chan, BT_CONFIG);
3671 result = L2CAP_CR_SUCCESS;
3672 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003673 status = L2CAP_CS_NO_INFO;
3674 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003675 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003676 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003677 result = L2CAP_CR_PEND;
3678 status = L2CAP_CS_AUTHEN_PEND;
3679 }
3680 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003681 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003682 result = L2CAP_CR_PEND;
3683 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003684 }
3685
Linus Torvalds1da177e2005-04-16 15:20:36 -07003686response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003687 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003688 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003689
3690sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003691 rsp.scid = cpu_to_le16(scid);
3692 rsp.dcid = cpu_to_le16(dcid);
3693 rsp.result = cpu_to_le16(result);
3694 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003695 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003696
3697 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3698 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003699 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003700
3701 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3702 conn->info_ident = l2cap_get_ident(conn);
3703
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003704 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003705
Gustavo Padovan2d792812012-10-06 10:07:01 +01003706 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3707 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003708 }
3709
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003710 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003711 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003712 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003713 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003714 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003715 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003716 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003717 }
Mat Martineau17009152012-10-23 15:24:07 -07003718
3719 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003720}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003721
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003722static int l2cap_connect_req(struct l2cap_conn *conn,
3723 struct l2cap_cmd_hdr *cmd, u8 *data)
3724{
Gustavo Padovan300229f2012-10-12 19:40:40 +08003725 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003726 return 0;
3727}
3728
Mat Martineau5909cf32012-10-23 15:24:08 -07003729static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003730 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003731{
3732 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3733 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003734 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003735 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003736 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003737
3738 scid = __le16_to_cpu(rsp->scid);
3739 dcid = __le16_to_cpu(rsp->dcid);
3740 result = __le16_to_cpu(rsp->result);
3741 status = __le16_to_cpu(rsp->status);
3742
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003743 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 +01003744 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003745
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003746 mutex_lock(&conn->chan_lock);
3747
Linus Torvalds1da177e2005-04-16 15:20:36 -07003748 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003749 chan = __l2cap_get_chan_by_scid(conn, scid);
3750 if (!chan) {
3751 err = -EFAULT;
3752 goto unlock;
3753 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003754 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003755 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3756 if (!chan) {
3757 err = -EFAULT;
3758 goto unlock;
3759 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003760 }
3761
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003762 err = 0;
3763
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003764 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003765
Linus Torvalds1da177e2005-04-16 15:20:36 -07003766 switch (result) {
3767 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003768 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003769 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003770 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003771 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003772
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003773 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003774 break;
3775
Linus Torvalds1da177e2005-04-16 15:20:36 -07003776 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003777 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003778 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003779 break;
3780
3781 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003782 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003783 break;
3784
3785 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003786 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003787 break;
3788 }
3789
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003790 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003791
3792unlock:
3793 mutex_unlock(&conn->chan_lock);
3794
3795 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003796}
3797
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003798static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003799{
3800 /* FCS is enabled only in ERTM or streaming mode, if one or both
3801 * sides request it.
3802 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003803 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003804 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003805 else if (!test_bit(CONF_NO_FCS_RECV, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003806 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003807}
3808
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003809static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3810 u8 ident, u16 flags)
3811{
3812 struct l2cap_conn *conn = chan->conn;
3813
3814 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3815 flags);
3816
3817 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3818 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3819
3820 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3821 l2cap_build_conf_rsp(chan, data,
3822 L2CAP_CONF_SUCCESS, flags), data);
3823}
3824
Gustavo Padovan2d792812012-10-06 10:07:01 +01003825static inline int l2cap_config_req(struct l2cap_conn *conn,
3826 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3827 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003828{
3829 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3830 u16 dcid, flags;
3831 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003832 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003833 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003834
3835 dcid = __le16_to_cpu(req->dcid);
3836 flags = __le16_to_cpu(req->flags);
3837
3838 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3839
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003840 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003841 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003842 return -ENOENT;
3843
David S. Miller033b1142011-07-21 13:38:42 -07003844 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003845 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003846
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003847 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003848 rej.scid = cpu_to_le16(chan->scid);
3849 rej.dcid = cpu_to_le16(chan->dcid);
3850
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003851 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003852 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003853 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003854 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003855
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003856 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003857 len = cmd_len - sizeof(*req);
Dan Rosenberg7ac28812011-06-24 08:38:05 -04003858 if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003859 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003860 l2cap_build_conf_rsp(chan, rsp,
3861 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003862 goto unlock;
3863 }
3864
3865 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003866 memcpy(chan->conf_req + chan->conf_len, req->data, len);
3867 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003868
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003869 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003870 /* Incomplete config. Send empty response. */
3871 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003872 l2cap_build_conf_rsp(chan, rsp,
3873 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003874 goto unlock;
3875 }
3876
3877 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003878 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003879 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02003880 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003881 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003882 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003883
Mat Martineau1500109b2012-10-23 15:24:15 -07003884 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003885 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003886 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003887
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003888 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003889 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003890
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003891 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02003892 goto unlock;
3893
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003894 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003895 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003896
Mat Martineau105bdf92012-04-27 16:50:48 -07003897 if (chan->mode == L2CAP_MODE_ERTM ||
3898 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003899 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003900
Mat Martineau3c588192012-04-11 10:48:42 -07003901 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02003902 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07003903 else
3904 l2cap_chan_ready(chan);
3905
Marcel Holtmann876d9482007-10-20 13:35:42 +02003906 goto unlock;
3907 }
3908
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003909 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003910 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003911 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003912 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003913 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003914 }
3915
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003916 /* Got Conf Rsp PENDING from remote side and asume we sent
3917 Conf Rsp PENDING in the code above */
3918 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003919 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003920
3921 /* check compatibility */
3922
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03003923 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02003924 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03003925 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
3926 else
3927 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003928 }
3929
Linus Torvalds1da177e2005-04-16 15:20:36 -07003930unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003931 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003932 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003933}
3934
Gustavo Padovan2d792812012-10-06 10:07:01 +01003935static inline int l2cap_config_rsp(struct l2cap_conn *conn,
3936 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003937{
3938 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3939 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003940 struct l2cap_chan *chan;
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003941 int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07003942 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003943
3944 scid = __le16_to_cpu(rsp->scid);
3945 flags = __le16_to_cpu(rsp->flags);
3946 result = __le16_to_cpu(rsp->result);
3947
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003948 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
3949 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003950
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003951 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003952 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003953 return 0;
3954
3955 switch (result) {
3956 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003957 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003958 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003959 break;
3960
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003961 case L2CAP_CONF_PENDING:
3962 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
3963
3964 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3965 char buf[64];
3966
3967 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003968 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003969 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02003970 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003971 goto done;
3972 }
3973
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02003974 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03003975 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
3976 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02003977 } else {
3978 if (l2cap_check_efs(chan)) {
3979 amp_create_logical_link(chan);
3980 chan->ident = cmd->ident;
3981 }
3982 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003983 }
3984 goto done;
3985
Linus Torvalds1da177e2005-04-16 15:20:36 -07003986 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003987 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003988 char req[64];
3989
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003990 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02003991 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003992 goto done;
3993 }
3994
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003995 /* throw out any old stored conf requests */
3996 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003997 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003998 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003999 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004000 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004001 goto done;
4002 }
4003
4004 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004005 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004006 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004007 if (result != L2CAP_CONF_SUCCESS)
4008 goto done;
4009 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004010 }
4011
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004012 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004013 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004014
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004015 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004016 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004017 goto done;
4018 }
4019
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004020 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004021 goto done;
4022
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004023 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004024
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004025 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004026 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004027
Mat Martineau105bdf92012-04-27 16:50:48 -07004028 if (chan->mode == L2CAP_MODE_ERTM ||
4029 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004030 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004031
Mat Martineau3c588192012-04-11 10:48:42 -07004032 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004033 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004034 else
4035 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004036 }
4037
4038done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004039 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004040 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004041}
4042
Gustavo Padovan2d792812012-10-06 10:07:01 +01004043static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
4044 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004045{
4046 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4047 struct l2cap_disconn_rsp rsp;
4048 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004049 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004050 struct sock *sk;
4051
4052 scid = __le16_to_cpu(req->scid);
4053 dcid = __le16_to_cpu(req->dcid);
4054
4055 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4056
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004057 mutex_lock(&conn->chan_lock);
4058
4059 chan = __l2cap_get_chan_by_scid(conn, dcid);
4060 if (!chan) {
4061 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004062 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004063 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004064
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004065 l2cap_chan_lock(chan);
4066
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004067 sk = chan->sk;
4068
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004069 rsp.dcid = cpu_to_le16(chan->scid);
4070 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004071 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4072
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004073 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004074 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004075 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004076
Mat Martineau61d6ef32012-04-27 16:50:50 -07004077 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004078 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004079
4080 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004081
Gustavo Padovan80b98022012-05-27 22:27:51 -03004082 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004083 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004084
4085 mutex_unlock(&conn->chan_lock);
4086
Linus Torvalds1da177e2005-04-16 15:20:36 -07004087 return 0;
4088}
4089
Gustavo Padovan2d792812012-10-06 10:07:01 +01004090static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
4091 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004092{
4093 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4094 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004095 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004096
4097 scid = __le16_to_cpu(rsp->scid);
4098 dcid = __le16_to_cpu(rsp->dcid);
4099
4100 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4101
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004102 mutex_lock(&conn->chan_lock);
4103
4104 chan = __l2cap_get_chan_by_scid(conn, scid);
4105 if (!chan) {
4106 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004107 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004108 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004109
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004110 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004111
Mat Martineau61d6ef32012-04-27 16:50:50 -07004112 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004113 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004114
4115 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004116
Gustavo Padovan80b98022012-05-27 22:27:51 -03004117 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004118 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004119
4120 mutex_unlock(&conn->chan_lock);
4121
Linus Torvalds1da177e2005-04-16 15:20:36 -07004122 return 0;
4123}
4124
Gustavo Padovan2d792812012-10-06 10:07:01 +01004125static inline int l2cap_information_req(struct l2cap_conn *conn,
4126 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004127{
4128 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004129 u16 type;
4130
4131 type = __le16_to_cpu(req->type);
4132
4133 BT_DBG("type 0x%4.4x", type);
4134
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004135 if (type == L2CAP_IT_FEAT_MASK) {
4136 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004137 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004138 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004139 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4140 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004141 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004142 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004143 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004144 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004145 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004146 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004147
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004148 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004149 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4150 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004151 } else if (type == L2CAP_IT_FIXED_CHAN) {
4152 u8 buf[12];
4153 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004154
4155 if (enable_hs)
4156 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4157 else
4158 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4159
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004160 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4161 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004162 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004163 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4164 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004165 } else {
4166 struct l2cap_info_rsp rsp;
4167 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004168 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004169 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4170 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004171 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004172
4173 return 0;
4174}
4175
Gustavo Padovan2d792812012-10-06 10:07:01 +01004176static inline int l2cap_information_rsp(struct l2cap_conn *conn,
4177 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004178{
4179 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4180 u16 type, result;
4181
4182 type = __le16_to_cpu(rsp->type);
4183 result = __le16_to_cpu(rsp->result);
4184
4185 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4186
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004187 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4188 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004189 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004190 return 0;
4191
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004192 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004193
Ville Tervoadb08ed2010-08-04 09:43:33 +03004194 if (result != L2CAP_IR_SUCCESS) {
4195 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4196 conn->info_ident = 0;
4197
4198 l2cap_conn_start(conn);
4199
4200 return 0;
4201 }
4202
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004203 switch (type) {
4204 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004205 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004206
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004207 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004208 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004209 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004210
4211 conn->info_ident = l2cap_get_ident(conn);
4212
4213 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004214 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004215 } else {
4216 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4217 conn->info_ident = 0;
4218
4219 l2cap_conn_start(conn);
4220 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004221 break;
4222
4223 case L2CAP_IT_FIXED_CHAN:
4224 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004225 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004226 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004227
4228 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004229 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004230 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004231
Linus Torvalds1da177e2005-04-16 15:20:36 -07004232 return 0;
4233}
4234
Mat Martineau17009152012-10-23 15:24:07 -07004235static int l2cap_create_channel_req(struct l2cap_conn *conn,
4236 struct l2cap_cmd_hdr *cmd,
4237 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004238{
4239 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004240 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004241 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004242 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004243 u16 psm, scid;
4244
4245 if (cmd_len != sizeof(*req))
4246 return -EPROTO;
4247
4248 if (!enable_hs)
4249 return -EINVAL;
4250
4251 psm = le16_to_cpu(req->psm);
4252 scid = le16_to_cpu(req->scid);
4253
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004254 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 -07004255
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004256 /* For controller id 0 make BR/EDR connection */
4257 if (req->amp_id == HCI_BREDR_ID) {
4258 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4259 req->amp_id);
4260 return 0;
4261 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004262
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004263 /* Validate AMP controller id */
4264 hdev = hci_dev_get(req->amp_id);
4265 if (!hdev)
4266 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004267
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004268 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004269 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004270 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004271 }
4272
4273 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4274 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004275 if (chan) {
4276 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4277 struct hci_conn *hs_hcon;
4278
4279 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, conn->dst);
4280 if (!hs_hcon) {
4281 hci_dev_put(hdev);
4282 return -EFAULT;
4283 }
4284
4285 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4286
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004287 mgr->bredr_chan = chan;
4288 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004289 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004290 conn->mtu = hdev->block_mtu;
4291 }
4292
4293 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004294
4295 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004296
4297error:
4298 rsp.dcid = 0;
4299 rsp.scid = cpu_to_le16(scid);
4300 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4301 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4302
4303 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4304 sizeof(rsp), &rsp);
4305
4306 return -EFAULT;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004307}
4308
Mat Martineau8eb200b2012-10-23 15:24:17 -07004309static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4310{
4311 struct l2cap_move_chan_req req;
4312 u8 ident;
4313
4314 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4315
4316 ident = l2cap_get_ident(chan->conn);
4317 chan->ident = ident;
4318
4319 req.icid = cpu_to_le16(chan->scid);
4320 req.dest_amp_id = dest_amp_id;
4321
4322 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4323 &req);
4324
4325 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4326}
4327
Mat Martineau1500109b2012-10-23 15:24:15 -07004328static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004329{
4330 struct l2cap_move_chan_rsp rsp;
4331
Mat Martineau1500109b2012-10-23 15:24:15 -07004332 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004333
Mat Martineau1500109b2012-10-23 15:24:15 -07004334 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004335 rsp.result = cpu_to_le16(result);
4336
Mat Martineau1500109b2012-10-23 15:24:15 -07004337 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4338 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004339}
4340
Mat Martineau5b155ef2012-10-23 15:24:14 -07004341static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004342{
4343 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004344
Mat Martineau5b155ef2012-10-23 15:24:14 -07004345 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004346
Mat Martineau5b155ef2012-10-23 15:24:14 -07004347 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004348
Mat Martineau5b155ef2012-10-23 15:24:14 -07004349 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004350 cfm.result = cpu_to_le16(result);
4351
Mat Martineau5b155ef2012-10-23 15:24:14 -07004352 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4353 sizeof(cfm), &cfm);
4354
4355 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4356}
4357
4358static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4359{
4360 struct l2cap_move_chan_cfm cfm;
4361
4362 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4363
4364 cfm.icid = cpu_to_le16(icid);
4365 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4366
4367 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4368 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004369}
4370
4371static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004372 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004373{
4374 struct l2cap_move_chan_cfm_rsp rsp;
4375
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004376 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004377
4378 rsp.icid = cpu_to_le16(icid);
4379 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4380}
4381
Mat Martineau5f3847a2012-10-23 15:24:12 -07004382static void __release_logical_link(struct l2cap_chan *chan)
4383{
4384 chan->hs_hchan = NULL;
4385 chan->hs_hcon = NULL;
4386
4387 /* Placeholder - release the logical link */
4388}
4389
Mat Martineau1500109b2012-10-23 15:24:15 -07004390static void l2cap_logical_fail(struct l2cap_chan *chan)
4391{
4392 /* Logical link setup failed */
4393 if (chan->state != BT_CONNECTED) {
4394 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004395 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004396 return;
4397 }
4398
4399 switch (chan->move_role) {
4400 case L2CAP_MOVE_ROLE_RESPONDER:
4401 l2cap_move_done(chan);
4402 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4403 break;
4404 case L2CAP_MOVE_ROLE_INITIATOR:
4405 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4406 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4407 /* Remote has only sent pending or
4408 * success responses, clean up
4409 */
4410 l2cap_move_done(chan);
4411 }
4412
4413 /* Other amp move states imply that the move
4414 * has already aborted
4415 */
4416 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4417 break;
4418 }
4419}
4420
4421static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4422 struct hci_chan *hchan)
4423{
4424 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004425
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004426 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004427 chan->hs_hcon->l2cap_data = chan->conn;
4428
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004429 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004430
4431 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004432 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004433
4434 set_default_fcs(chan);
4435
4436 err = l2cap_ertm_init(chan);
4437 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004438 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004439 else
4440 l2cap_chan_ready(chan);
4441 }
4442}
4443
4444static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4445 struct hci_chan *hchan)
4446{
4447 chan->hs_hcon = hchan->conn;
4448 chan->hs_hcon->l2cap_data = chan->conn;
4449
4450 BT_DBG("move_state %d", chan->move_state);
4451
4452 switch (chan->move_state) {
4453 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4454 /* Move confirm will be sent after a success
4455 * response is received
4456 */
4457 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4458 break;
4459 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4460 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4461 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4462 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4463 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4464 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4465 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4466 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4467 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4468 }
4469 break;
4470 default:
4471 /* Move was not in expected state, free the channel */
4472 __release_logical_link(chan);
4473
4474 chan->move_state = L2CAP_MOVE_STABLE;
4475 }
4476}
4477
4478/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004479void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4480 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004481{
Mat Martineau1500109b2012-10-23 15:24:15 -07004482 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4483
4484 if (status) {
4485 l2cap_logical_fail(chan);
4486 __release_logical_link(chan);
4487 return;
4488 }
4489
4490 if (chan->state != BT_CONNECTED) {
4491 /* Ignore logical link if channel is on BR/EDR */
4492 if (chan->local_amp_id)
4493 l2cap_logical_finish_create(chan, hchan);
4494 } else {
4495 l2cap_logical_finish_move(chan, hchan);
4496 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004497}
4498
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004499void l2cap_move_start(struct l2cap_chan *chan)
4500{
4501 BT_DBG("chan %p", chan);
4502
4503 if (chan->local_amp_id == HCI_BREDR_ID) {
4504 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4505 return;
4506 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4507 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4508 /* Placeholder - start physical link setup */
4509 } else {
4510 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4511 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4512 chan->move_id = 0;
4513 l2cap_move_setup(chan);
4514 l2cap_send_move_chan_req(chan, 0);
4515 }
4516}
4517
Mat Martineau8eb200b2012-10-23 15:24:17 -07004518static void l2cap_do_create(struct l2cap_chan *chan, int result,
4519 u8 local_amp_id, u8 remote_amp_id)
4520{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004521 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4522 local_amp_id, remote_amp_id);
4523
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004524 chan->fcs = L2CAP_FCS_NONE;
4525
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004526 /* Outgoing channel on AMP */
4527 if (chan->state == BT_CONNECT) {
4528 if (result == L2CAP_CR_SUCCESS) {
4529 chan->local_amp_id = local_amp_id;
4530 l2cap_send_create_chan_req(chan, remote_amp_id);
4531 } else {
4532 /* Revert to BR/EDR connect */
4533 l2cap_send_conn_req(chan);
4534 }
4535
4536 return;
4537 }
4538
4539 /* Incoming channel on AMP */
4540 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004541 struct l2cap_conn_rsp rsp;
4542 char buf[128];
4543 rsp.scid = cpu_to_le16(chan->dcid);
4544 rsp.dcid = cpu_to_le16(chan->scid);
4545
Mat Martineau8eb200b2012-10-23 15:24:17 -07004546 if (result == L2CAP_CR_SUCCESS) {
4547 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004548 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4549 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004550 } else {
4551 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004552 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4553 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004554 }
4555
4556 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4557 sizeof(rsp), &rsp);
4558
4559 if (result == L2CAP_CR_SUCCESS) {
4560 __l2cap_state_change(chan, BT_CONFIG);
4561 set_bit(CONF_REQ_SENT, &chan->conf_state);
4562 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4563 L2CAP_CONF_REQ,
4564 l2cap_build_conf_req(chan, buf), buf);
4565 chan->num_conf_req++;
4566 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004567 }
4568}
4569
4570static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4571 u8 remote_amp_id)
4572{
4573 l2cap_move_setup(chan);
4574 chan->move_id = local_amp_id;
4575 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4576
4577 l2cap_send_move_chan_req(chan, remote_amp_id);
4578}
4579
4580static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4581{
4582 struct hci_chan *hchan = NULL;
4583
4584 /* Placeholder - get hci_chan for logical link */
4585
4586 if (hchan) {
4587 if (hchan->state == BT_CONNECTED) {
4588 /* Logical link is ready to go */
4589 chan->hs_hcon = hchan->conn;
4590 chan->hs_hcon->l2cap_data = chan->conn;
4591 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4592 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4593
4594 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4595 } else {
4596 /* Wait for logical link to be ready */
4597 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4598 }
4599 } else {
4600 /* Logical link not available */
4601 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4602 }
4603}
4604
4605static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4606{
4607 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4608 u8 rsp_result;
4609 if (result == -EINVAL)
4610 rsp_result = L2CAP_MR_BAD_ID;
4611 else
4612 rsp_result = L2CAP_MR_NOT_ALLOWED;
4613
4614 l2cap_send_move_chan_rsp(chan, rsp_result);
4615 }
4616
4617 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4618 chan->move_state = L2CAP_MOVE_STABLE;
4619
4620 /* Restart data transmission */
4621 l2cap_ertm_send(chan);
4622}
4623
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004624/* Invoke with locked chan */
4625void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004626{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004627 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004628 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004629
Mat Martineau8eb200b2012-10-23 15:24:17 -07004630 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4631 chan, result, local_amp_id, remote_amp_id);
4632
Mat Martineau8eb200b2012-10-23 15:24:17 -07004633 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4634 l2cap_chan_unlock(chan);
4635 return;
4636 }
4637
4638 if (chan->state != BT_CONNECTED) {
4639 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4640 } else if (result != L2CAP_MR_SUCCESS) {
4641 l2cap_do_move_cancel(chan, result);
4642 } else {
4643 switch (chan->move_role) {
4644 case L2CAP_MOVE_ROLE_INITIATOR:
4645 l2cap_do_move_initiate(chan, local_amp_id,
4646 remote_amp_id);
4647 break;
4648 case L2CAP_MOVE_ROLE_RESPONDER:
4649 l2cap_do_move_respond(chan, result);
4650 break;
4651 default:
4652 l2cap_do_move_cancel(chan, result);
4653 break;
4654 }
4655 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004656}
4657
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004658static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004659 struct l2cap_cmd_hdr *cmd,
4660 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004661{
4662 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004663 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004664 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004665 u16 icid = 0;
4666 u16 result = L2CAP_MR_NOT_ALLOWED;
4667
4668 if (cmd_len != sizeof(*req))
4669 return -EPROTO;
4670
4671 icid = le16_to_cpu(req->icid);
4672
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004673 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004674
4675 if (!enable_hs)
4676 return -EINVAL;
4677
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004678 chan = l2cap_get_chan_by_dcid(conn, icid);
4679 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004680 rsp.icid = cpu_to_le16(icid);
4681 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4682 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4683 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004684 return 0;
4685 }
4686
Mat Martineau1500109b2012-10-23 15:24:15 -07004687 chan->ident = cmd->ident;
4688
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004689 if (chan->scid < L2CAP_CID_DYN_START ||
4690 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4691 (chan->mode != L2CAP_MODE_ERTM &&
4692 chan->mode != L2CAP_MODE_STREAMING)) {
4693 result = L2CAP_MR_NOT_ALLOWED;
4694 goto send_move_response;
4695 }
4696
4697 if (chan->local_amp_id == req->dest_amp_id) {
4698 result = L2CAP_MR_SAME_ID;
4699 goto send_move_response;
4700 }
4701
4702 if (req->dest_amp_id) {
4703 struct hci_dev *hdev;
4704 hdev = hci_dev_get(req->dest_amp_id);
4705 if (!hdev || hdev->dev_type != HCI_AMP ||
4706 !test_bit(HCI_UP, &hdev->flags)) {
4707 if (hdev)
4708 hci_dev_put(hdev);
4709
4710 result = L2CAP_MR_BAD_ID;
4711 goto send_move_response;
4712 }
4713 hci_dev_put(hdev);
4714 }
4715
4716 /* Detect a move collision. Only send a collision response
4717 * if this side has "lost", otherwise proceed with the move.
4718 * The winner has the larger bd_addr.
4719 */
4720 if ((__chan_is_moving(chan) ||
4721 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
4722 bacmp(conn->src, conn->dst) > 0) {
4723 result = L2CAP_MR_COLLISION;
4724 goto send_move_response;
4725 }
4726
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004727 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4728 l2cap_move_setup(chan);
4729 chan->move_id = req->dest_amp_id;
4730 icid = chan->dcid;
4731
4732 if (!req->dest_amp_id) {
4733 /* Moving to BR/EDR */
4734 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4735 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4736 result = L2CAP_MR_PEND;
4737 } else {
4738 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4739 result = L2CAP_MR_SUCCESS;
4740 }
4741 } else {
4742 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4743 /* Placeholder - uncomment when amp functions are available */
4744 /*amp_accept_physical(chan, req->dest_amp_id);*/
4745 result = L2CAP_MR_PEND;
4746 }
4747
4748send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004749 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004750
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004751 l2cap_chan_unlock(chan);
4752
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004753 return 0;
4754}
4755
Mat Martineau5b155ef2012-10-23 15:24:14 -07004756static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4757{
4758 struct l2cap_chan *chan;
4759 struct hci_chan *hchan = NULL;
4760
4761 chan = l2cap_get_chan_by_scid(conn, icid);
4762 if (!chan) {
4763 l2cap_send_move_chan_cfm_icid(conn, icid);
4764 return;
4765 }
4766
4767 __clear_chan_timer(chan);
4768 if (result == L2CAP_MR_PEND)
4769 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4770
4771 switch (chan->move_state) {
4772 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4773 /* Move confirm will be sent when logical link
4774 * is complete.
4775 */
4776 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4777 break;
4778 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4779 if (result == L2CAP_MR_PEND) {
4780 break;
4781 } else if (test_bit(CONN_LOCAL_BUSY,
4782 &chan->conn_state)) {
4783 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4784 } else {
4785 /* Logical link is up or moving to BR/EDR,
4786 * proceed with move
4787 */
4788 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4789 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4790 }
4791 break;
4792 case L2CAP_MOVE_WAIT_RSP:
4793 /* Moving to AMP */
4794 if (result == L2CAP_MR_SUCCESS) {
4795 /* Remote is ready, send confirm immediately
4796 * after logical link is ready
4797 */
4798 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4799 } else {
4800 /* Both logical link and move success
4801 * are required to confirm
4802 */
4803 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4804 }
4805
4806 /* Placeholder - get hci_chan for logical link */
4807 if (!hchan) {
4808 /* Logical link not available */
4809 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4810 break;
4811 }
4812
4813 /* If the logical link is not yet connected, do not
4814 * send confirmation.
4815 */
4816 if (hchan->state != BT_CONNECTED)
4817 break;
4818
4819 /* Logical link is already ready to go */
4820
4821 chan->hs_hcon = hchan->conn;
4822 chan->hs_hcon->l2cap_data = chan->conn;
4823
4824 if (result == L2CAP_MR_SUCCESS) {
4825 /* Can confirm now */
4826 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4827 } else {
4828 /* Now only need move success
4829 * to confirm
4830 */
4831 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4832 }
4833
4834 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4835 break;
4836 default:
4837 /* Any other amp move state means the move failed. */
4838 chan->move_id = chan->local_amp_id;
4839 l2cap_move_done(chan);
4840 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4841 }
4842
4843 l2cap_chan_unlock(chan);
4844}
4845
4846static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
4847 u16 result)
4848{
4849 struct l2cap_chan *chan;
4850
4851 chan = l2cap_get_chan_by_ident(conn, ident);
4852 if (!chan) {
4853 /* Could not locate channel, icid is best guess */
4854 l2cap_send_move_chan_cfm_icid(conn, icid);
4855 return;
4856 }
4857
4858 __clear_chan_timer(chan);
4859
4860 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4861 if (result == L2CAP_MR_COLLISION) {
4862 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4863 } else {
4864 /* Cleanup - cancel move */
4865 chan->move_id = chan->local_amp_id;
4866 l2cap_move_done(chan);
4867 }
4868 }
4869
4870 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4871
4872 l2cap_chan_unlock(chan);
4873}
4874
4875static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
4876 struct l2cap_cmd_hdr *cmd,
4877 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004878{
4879 struct l2cap_move_chan_rsp *rsp = data;
4880 u16 icid, result;
4881
4882 if (cmd_len != sizeof(*rsp))
4883 return -EPROTO;
4884
4885 icid = le16_to_cpu(rsp->icid);
4886 result = le16_to_cpu(rsp->result);
4887
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004888 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004889
Mat Martineau5b155ef2012-10-23 15:24:14 -07004890 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
4891 l2cap_move_continue(conn, icid, result);
4892 else
4893 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004894
4895 return 0;
4896}
4897
Mat Martineau5f3847a2012-10-23 15:24:12 -07004898static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
4899 struct l2cap_cmd_hdr *cmd,
4900 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004901{
4902 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07004903 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004904 u16 icid, result;
4905
4906 if (cmd_len != sizeof(*cfm))
4907 return -EPROTO;
4908
4909 icid = le16_to_cpu(cfm->icid);
4910 result = le16_to_cpu(cfm->result);
4911
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004912 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004913
Mat Martineau5f3847a2012-10-23 15:24:12 -07004914 chan = l2cap_get_chan_by_dcid(conn, icid);
4915 if (!chan) {
4916 /* Spec requires a response even if the icid was not found */
4917 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4918 return 0;
4919 }
4920
4921 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
4922 if (result == L2CAP_MC_CONFIRMED) {
4923 chan->local_amp_id = chan->move_id;
4924 if (!chan->local_amp_id)
4925 __release_logical_link(chan);
4926 } else {
4927 chan->move_id = chan->local_amp_id;
4928 }
4929
4930 l2cap_move_done(chan);
4931 }
4932
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004933 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4934
Mat Martineau5f3847a2012-10-23 15:24:12 -07004935 l2cap_chan_unlock(chan);
4936
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004937 return 0;
4938}
4939
4940static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004941 struct l2cap_cmd_hdr *cmd,
4942 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004943{
4944 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07004945 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004946 u16 icid;
4947
4948 if (cmd_len != sizeof(*rsp))
4949 return -EPROTO;
4950
4951 icid = le16_to_cpu(rsp->icid);
4952
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004953 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004954
Mat Martineau3fd71a02012-10-23 15:24:16 -07004955 chan = l2cap_get_chan_by_scid(conn, icid);
4956 if (!chan)
4957 return 0;
4958
4959 __clear_chan_timer(chan);
4960
4961 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
4962 chan->local_amp_id = chan->move_id;
4963
4964 if (!chan->local_amp_id && chan->hs_hchan)
4965 __release_logical_link(chan);
4966
4967 l2cap_move_done(chan);
4968 }
4969
4970 l2cap_chan_unlock(chan);
4971
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004972 return 0;
4973}
4974
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004975static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004976 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02004977{
4978 u16 max_latency;
4979
4980 if (min > max || min < 6 || max > 3200)
4981 return -EINVAL;
4982
4983 if (to_multiplier < 10 || to_multiplier > 3200)
4984 return -EINVAL;
4985
4986 if (max >= to_multiplier * 8)
4987 return -EINVAL;
4988
4989 max_latency = (to_multiplier * 8 / max) - 1;
4990 if (latency > 499 || latency > max_latency)
4991 return -EINVAL;
4992
4993 return 0;
4994}
4995
4996static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004997 struct l2cap_cmd_hdr *cmd,
4998 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02004999{
5000 struct hci_conn *hcon = conn->hcon;
5001 struct l2cap_conn_param_update_req *req;
5002 struct l2cap_conn_param_update_rsp rsp;
5003 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005004 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005005
5006 if (!(hcon->link_mode & HCI_LM_MASTER))
5007 return -EINVAL;
5008
5009 cmd_len = __le16_to_cpu(cmd->len);
5010 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5011 return -EPROTO;
5012
5013 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005014 min = __le16_to_cpu(req->min);
5015 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005016 latency = __le16_to_cpu(req->latency);
5017 to_multiplier = __le16_to_cpu(req->to_multiplier);
5018
5019 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 +01005020 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005021
5022 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005023
5024 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5025 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005026 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005027 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005028 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005029
5030 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005031 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005032
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005033 if (!err)
5034 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5035
Claudio Takahaside731152011-02-11 19:28:55 -02005036 return 0;
5037}
5038
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005039static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005040 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5041 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005042{
5043 int err = 0;
5044
5045 switch (cmd->code) {
5046 case L2CAP_COMMAND_REJ:
5047 l2cap_command_rej(conn, cmd, data);
5048 break;
5049
5050 case L2CAP_CONN_REQ:
5051 err = l2cap_connect_req(conn, cmd, data);
5052 break;
5053
5054 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005055 case L2CAP_CREATE_CHAN_RSP:
Mat Martineau5909cf32012-10-23 15:24:08 -07005056 err = l2cap_connect_create_rsp(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005057 break;
5058
5059 case L2CAP_CONF_REQ:
5060 err = l2cap_config_req(conn, cmd, cmd_len, data);
5061 break;
5062
5063 case L2CAP_CONF_RSP:
5064 err = l2cap_config_rsp(conn, cmd, data);
5065 break;
5066
5067 case L2CAP_DISCONN_REQ:
5068 err = l2cap_disconnect_req(conn, cmd, data);
5069 break;
5070
5071 case L2CAP_DISCONN_RSP:
5072 err = l2cap_disconnect_rsp(conn, cmd, data);
5073 break;
5074
5075 case L2CAP_ECHO_REQ:
5076 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5077 break;
5078
5079 case L2CAP_ECHO_RSP:
5080 break;
5081
5082 case L2CAP_INFO_REQ:
5083 err = l2cap_information_req(conn, cmd, data);
5084 break;
5085
5086 case L2CAP_INFO_RSP:
5087 err = l2cap_information_rsp(conn, cmd, data);
5088 break;
5089
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005090 case L2CAP_CREATE_CHAN_REQ:
5091 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5092 break;
5093
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005094 case L2CAP_MOVE_CHAN_REQ:
5095 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5096 break;
5097
5098 case L2CAP_MOVE_CHAN_RSP:
5099 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
5100 break;
5101
5102 case L2CAP_MOVE_CHAN_CFM:
5103 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5104 break;
5105
5106 case L2CAP_MOVE_CHAN_CFM_RSP:
5107 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
5108 break;
5109
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005110 default:
5111 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5112 err = -EINVAL;
5113 break;
5114 }
5115
5116 return err;
5117}
5118
5119static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005120 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005121{
5122 switch (cmd->code) {
5123 case L2CAP_COMMAND_REJ:
5124 return 0;
5125
5126 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005127 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005128
5129 case L2CAP_CONN_PARAM_UPDATE_RSP:
5130 return 0;
5131
5132 default:
5133 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5134 return -EINVAL;
5135 }
5136}
5137
5138static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005139 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005140{
5141 u8 *data = skb->data;
5142 int len = skb->len;
5143 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005144 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005145
5146 l2cap_raw_recv(conn, skb);
5147
5148 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005149 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005150 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5151 data += L2CAP_CMD_HDR_SIZE;
5152 len -= L2CAP_CMD_HDR_SIZE;
5153
Al Viro88219a02007-07-29 00:17:25 -07005154 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005155
Gustavo Padovan2d792812012-10-06 10:07:01 +01005156 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5157 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005158
Al Viro88219a02007-07-29 00:17:25 -07005159 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005160 BT_DBG("corrupted command");
5161 break;
5162 }
5163
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005164 if (conn->hcon->type == LE_LINK)
5165 err = l2cap_le_sig_cmd(conn, &cmd, data);
5166 else
5167 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005168
5169 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005170 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005171
5172 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005173
5174 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005175 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005176 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5177 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005178 }
5179
Al Viro88219a02007-07-29 00:17:25 -07005180 data += cmd_len;
5181 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005182 }
5183
5184 kfree_skb(skb);
5185}
5186
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005187static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005188{
5189 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005190 int hdr_size;
5191
5192 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5193 hdr_size = L2CAP_EXT_HDR_SIZE;
5194 else
5195 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005196
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005197 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005198 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005199 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5200 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5201
5202 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005203 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005204 }
5205 return 0;
5206}
5207
Mat Martineau6ea00482012-05-17 20:53:52 -07005208static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005209{
Mat Martineaue31f7632012-05-17 20:53:41 -07005210 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005211
Mat Martineaue31f7632012-05-17 20:53:41 -07005212 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005213
Mat Martineaue31f7632012-05-17 20:53:41 -07005214 memset(&control, 0, sizeof(control));
5215 control.sframe = 1;
5216 control.final = 1;
5217 control.reqseq = chan->buffer_seq;
5218 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005219
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005220 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005221 control.super = L2CAP_SUPER_RNR;
5222 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005223 }
5224
Mat Martineaue31f7632012-05-17 20:53:41 -07005225 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5226 chan->unacked_frames > 0)
5227 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005228
Mat Martineaue31f7632012-05-17 20:53:41 -07005229 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005230 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005231
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005232 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005233 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5234 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5235 * send it now.
5236 */
5237 control.super = L2CAP_SUPER_RR;
5238 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005239 }
5240}
5241
Gustavo Padovan2d792812012-10-06 10:07:01 +01005242static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5243 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005244{
Mat Martineau84084a32011-07-22 14:54:00 -07005245 /* skb->len reflects data in skb as well as all fragments
5246 * skb->data_len reflects only data in fragments
5247 */
5248 if (!skb_has_frag_list(skb))
5249 skb_shinfo(skb)->frag_list = new_frag;
5250
5251 new_frag->next = NULL;
5252
5253 (*last_frag)->next = new_frag;
5254 *last_frag = new_frag;
5255
5256 skb->len += new_frag->len;
5257 skb->data_len += new_frag->len;
5258 skb->truesize += new_frag->truesize;
5259}
5260
Mat Martineau4b51dae92012-05-17 20:53:37 -07005261static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5262 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005263{
5264 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005265
Mat Martineau4b51dae92012-05-17 20:53:37 -07005266 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005267 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005268 if (chan->sdu)
5269 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005270
Gustavo Padovan80b98022012-05-27 22:27:51 -03005271 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005272 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005273
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005274 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005275 if (chan->sdu)
5276 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005277
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005278 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005279 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005280
Mat Martineau84084a32011-07-22 14:54:00 -07005281 if (chan->sdu_len > chan->imtu) {
5282 err = -EMSGSIZE;
5283 break;
5284 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005285
Mat Martineau84084a32011-07-22 14:54:00 -07005286 if (skb->len >= chan->sdu_len)
5287 break;
5288
5289 chan->sdu = skb;
5290 chan->sdu_last_frag = skb;
5291
5292 skb = NULL;
5293 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005294 break;
5295
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005296 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005297 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005298 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005299
Mat Martineau84084a32011-07-22 14:54:00 -07005300 append_skb_frag(chan->sdu, skb,
5301 &chan->sdu_last_frag);
5302 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005303
Mat Martineau84084a32011-07-22 14:54:00 -07005304 if (chan->sdu->len >= chan->sdu_len)
5305 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005306
Mat Martineau84084a32011-07-22 14:54:00 -07005307 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005308 break;
5309
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005310 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005311 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005312 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005313
Mat Martineau84084a32011-07-22 14:54:00 -07005314 append_skb_frag(chan->sdu, skb,
5315 &chan->sdu_last_frag);
5316 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005317
Mat Martineau84084a32011-07-22 14:54:00 -07005318 if (chan->sdu->len != chan->sdu_len)
5319 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005320
Gustavo Padovan80b98022012-05-27 22:27:51 -03005321 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005322
Mat Martineau84084a32011-07-22 14:54:00 -07005323 if (!err) {
5324 /* Reassembly complete */
5325 chan->sdu = NULL;
5326 chan->sdu_last_frag = NULL;
5327 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005328 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005329 break;
5330 }
5331
Mat Martineau84084a32011-07-22 14:54:00 -07005332 if (err) {
5333 kfree_skb(skb);
5334 kfree_skb(chan->sdu);
5335 chan->sdu = NULL;
5336 chan->sdu_last_frag = NULL;
5337 chan->sdu_len = 0;
5338 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005339
Mat Martineau84084a32011-07-22 14:54:00 -07005340 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005341}
5342
Mat Martineau32b32732012-10-23 15:24:11 -07005343static int l2cap_resegment(struct l2cap_chan *chan)
5344{
5345 /* Placeholder */
5346 return 0;
5347}
5348
Mat Martineaue3281402011-07-07 09:39:02 -07005349void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005350{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005351 u8 event;
5352
5353 if (chan->mode != L2CAP_MODE_ERTM)
5354 return;
5355
5356 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005357 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005358}
5359
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005360static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5361{
Mat Martineau63838722012-05-17 20:53:45 -07005362 int err = 0;
5363 /* Pass sequential frames to l2cap_reassemble_sdu()
5364 * until a gap is encountered.
5365 */
5366
5367 BT_DBG("chan %p", chan);
5368
5369 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5370 struct sk_buff *skb;
5371 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5372 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5373
5374 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5375
5376 if (!skb)
5377 break;
5378
5379 skb_unlink(skb, &chan->srej_q);
5380 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5381 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5382 if (err)
5383 break;
5384 }
5385
5386 if (skb_queue_empty(&chan->srej_q)) {
5387 chan->rx_state = L2CAP_RX_STATE_RECV;
5388 l2cap_send_ack(chan);
5389 }
5390
5391 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005392}
5393
5394static void l2cap_handle_srej(struct l2cap_chan *chan,
5395 struct l2cap_ctrl *control)
5396{
Mat Martineauf80842a2012-05-17 20:53:46 -07005397 struct sk_buff *skb;
5398
5399 BT_DBG("chan %p, control %p", chan, control);
5400
5401 if (control->reqseq == chan->next_tx_seq) {
5402 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005403 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005404 return;
5405 }
5406
5407 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5408
5409 if (skb == NULL) {
5410 BT_DBG("Seq %d not available for retransmission",
5411 control->reqseq);
5412 return;
5413 }
5414
5415 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5416 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005417 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005418 return;
5419 }
5420
5421 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5422
5423 if (control->poll) {
5424 l2cap_pass_to_tx(chan, control);
5425
5426 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5427 l2cap_retransmit(chan, control);
5428 l2cap_ertm_send(chan);
5429
5430 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5431 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5432 chan->srej_save_reqseq = control->reqseq;
5433 }
5434 } else {
5435 l2cap_pass_to_tx_fbit(chan, control);
5436
5437 if (control->final) {
5438 if (chan->srej_save_reqseq != control->reqseq ||
5439 !test_and_clear_bit(CONN_SREJ_ACT,
5440 &chan->conn_state))
5441 l2cap_retransmit(chan, control);
5442 } else {
5443 l2cap_retransmit(chan, control);
5444 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5445 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5446 chan->srej_save_reqseq = control->reqseq;
5447 }
5448 }
5449 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005450}
5451
5452static void l2cap_handle_rej(struct l2cap_chan *chan,
5453 struct l2cap_ctrl *control)
5454{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005455 struct sk_buff *skb;
5456
5457 BT_DBG("chan %p, control %p", chan, control);
5458
5459 if (control->reqseq == chan->next_tx_seq) {
5460 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005461 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005462 return;
5463 }
5464
5465 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5466
5467 if (chan->max_tx && skb &&
5468 bt_cb(skb)->control.retries >= chan->max_tx) {
5469 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005470 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005471 return;
5472 }
5473
5474 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5475
5476 l2cap_pass_to_tx(chan, control);
5477
5478 if (control->final) {
5479 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5480 l2cap_retransmit_all(chan, control);
5481 } else {
5482 l2cap_retransmit_all(chan, control);
5483 l2cap_ertm_send(chan);
5484 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5485 set_bit(CONN_REJ_ACT, &chan->conn_state);
5486 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005487}
5488
Mat Martineau4b51dae92012-05-17 20:53:37 -07005489static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5490{
5491 BT_DBG("chan %p, txseq %d", chan, txseq);
5492
5493 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5494 chan->expected_tx_seq);
5495
5496 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5497 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005498 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005499 /* See notes below regarding "double poll" and
5500 * invalid packets.
5501 */
5502 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5503 BT_DBG("Invalid/Ignore - after SREJ");
5504 return L2CAP_TXSEQ_INVALID_IGNORE;
5505 } else {
5506 BT_DBG("Invalid - in window after SREJ sent");
5507 return L2CAP_TXSEQ_INVALID;
5508 }
5509 }
5510
5511 if (chan->srej_list.head == txseq) {
5512 BT_DBG("Expected SREJ");
5513 return L2CAP_TXSEQ_EXPECTED_SREJ;
5514 }
5515
5516 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5517 BT_DBG("Duplicate SREJ - txseq already stored");
5518 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5519 }
5520
5521 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5522 BT_DBG("Unexpected SREJ - not requested");
5523 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5524 }
5525 }
5526
5527 if (chan->expected_tx_seq == txseq) {
5528 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5529 chan->tx_win) {
5530 BT_DBG("Invalid - txseq outside tx window");
5531 return L2CAP_TXSEQ_INVALID;
5532 } else {
5533 BT_DBG("Expected");
5534 return L2CAP_TXSEQ_EXPECTED;
5535 }
5536 }
5537
5538 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005539 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005540 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5541 return L2CAP_TXSEQ_DUPLICATE;
5542 }
5543
5544 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5545 /* A source of invalid packets is a "double poll" condition,
5546 * where delays cause us to send multiple poll packets. If
5547 * the remote stack receives and processes both polls,
5548 * sequence numbers can wrap around in such a way that a
5549 * resent frame has a sequence number that looks like new data
5550 * with a sequence gap. This would trigger an erroneous SREJ
5551 * request.
5552 *
5553 * Fortunately, this is impossible with a tx window that's
5554 * less than half of the maximum sequence number, which allows
5555 * invalid frames to be safely ignored.
5556 *
5557 * With tx window sizes greater than half of the tx window
5558 * maximum, the frame is invalid and cannot be ignored. This
5559 * causes a disconnect.
5560 */
5561
5562 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5563 BT_DBG("Invalid/Ignore - txseq outside tx window");
5564 return L2CAP_TXSEQ_INVALID_IGNORE;
5565 } else {
5566 BT_DBG("Invalid - txseq outside tx window");
5567 return L2CAP_TXSEQ_INVALID;
5568 }
5569 } else {
5570 BT_DBG("Unexpected - txseq indicates missing frames");
5571 return L2CAP_TXSEQ_UNEXPECTED;
5572 }
5573}
5574
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005575static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5576 struct l2cap_ctrl *control,
5577 struct sk_buff *skb, u8 event)
5578{
5579 int err = 0;
5580 bool skb_in_use = 0;
5581
5582 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5583 event);
5584
5585 switch (event) {
5586 case L2CAP_EV_RECV_IFRAME:
5587 switch (l2cap_classify_txseq(chan, control->txseq)) {
5588 case L2CAP_TXSEQ_EXPECTED:
5589 l2cap_pass_to_tx(chan, control);
5590
5591 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5592 BT_DBG("Busy, discarding expected seq %d",
5593 control->txseq);
5594 break;
5595 }
5596
5597 chan->expected_tx_seq = __next_seq(chan,
5598 control->txseq);
5599
5600 chan->buffer_seq = chan->expected_tx_seq;
5601 skb_in_use = 1;
5602
5603 err = l2cap_reassemble_sdu(chan, skb, control);
5604 if (err)
5605 break;
5606
5607 if (control->final) {
5608 if (!test_and_clear_bit(CONN_REJ_ACT,
5609 &chan->conn_state)) {
5610 control->final = 0;
5611 l2cap_retransmit_all(chan, control);
5612 l2cap_ertm_send(chan);
5613 }
5614 }
5615
5616 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5617 l2cap_send_ack(chan);
5618 break;
5619 case L2CAP_TXSEQ_UNEXPECTED:
5620 l2cap_pass_to_tx(chan, control);
5621
5622 /* Can't issue SREJ frames in the local busy state.
5623 * Drop this frame, it will be seen as missing
5624 * when local busy is exited.
5625 */
5626 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5627 BT_DBG("Busy, discarding unexpected seq %d",
5628 control->txseq);
5629 break;
5630 }
5631
5632 /* There was a gap in the sequence, so an SREJ
5633 * must be sent for each missing frame. The
5634 * current frame is stored for later use.
5635 */
5636 skb_queue_tail(&chan->srej_q, skb);
5637 skb_in_use = 1;
5638 BT_DBG("Queued %p (queue len %d)", skb,
5639 skb_queue_len(&chan->srej_q));
5640
5641 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5642 l2cap_seq_list_clear(&chan->srej_list);
5643 l2cap_send_srej(chan, control->txseq);
5644
5645 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5646 break;
5647 case L2CAP_TXSEQ_DUPLICATE:
5648 l2cap_pass_to_tx(chan, control);
5649 break;
5650 case L2CAP_TXSEQ_INVALID_IGNORE:
5651 break;
5652 case L2CAP_TXSEQ_INVALID:
5653 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005654 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005655 break;
5656 }
5657 break;
5658 case L2CAP_EV_RECV_RR:
5659 l2cap_pass_to_tx(chan, control);
5660 if (control->final) {
5661 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5662
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005663 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5664 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005665 control->final = 0;
5666 l2cap_retransmit_all(chan, control);
5667 }
5668
5669 l2cap_ertm_send(chan);
5670 } else if (control->poll) {
5671 l2cap_send_i_or_rr_or_rnr(chan);
5672 } else {
5673 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5674 &chan->conn_state) &&
5675 chan->unacked_frames)
5676 __set_retrans_timer(chan);
5677
5678 l2cap_ertm_send(chan);
5679 }
5680 break;
5681 case L2CAP_EV_RECV_RNR:
5682 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5683 l2cap_pass_to_tx(chan, control);
5684 if (control && control->poll) {
5685 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5686 l2cap_send_rr_or_rnr(chan, 0);
5687 }
5688 __clear_retrans_timer(chan);
5689 l2cap_seq_list_clear(&chan->retrans_list);
5690 break;
5691 case L2CAP_EV_RECV_REJ:
5692 l2cap_handle_rej(chan, control);
5693 break;
5694 case L2CAP_EV_RECV_SREJ:
5695 l2cap_handle_srej(chan, control);
5696 break;
5697 default:
5698 break;
5699 }
5700
5701 if (skb && !skb_in_use) {
5702 BT_DBG("Freeing %p", skb);
5703 kfree_skb(skb);
5704 }
5705
5706 return err;
5707}
5708
5709static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5710 struct l2cap_ctrl *control,
5711 struct sk_buff *skb, u8 event)
5712{
5713 int err = 0;
5714 u16 txseq = control->txseq;
5715 bool skb_in_use = 0;
5716
5717 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5718 event);
5719
5720 switch (event) {
5721 case L2CAP_EV_RECV_IFRAME:
5722 switch (l2cap_classify_txseq(chan, txseq)) {
5723 case L2CAP_TXSEQ_EXPECTED:
5724 /* Keep frame for reassembly later */
5725 l2cap_pass_to_tx(chan, control);
5726 skb_queue_tail(&chan->srej_q, skb);
5727 skb_in_use = 1;
5728 BT_DBG("Queued %p (queue len %d)", skb,
5729 skb_queue_len(&chan->srej_q));
5730
5731 chan->expected_tx_seq = __next_seq(chan, txseq);
5732 break;
5733 case L2CAP_TXSEQ_EXPECTED_SREJ:
5734 l2cap_seq_list_pop(&chan->srej_list);
5735
5736 l2cap_pass_to_tx(chan, control);
5737 skb_queue_tail(&chan->srej_q, skb);
5738 skb_in_use = 1;
5739 BT_DBG("Queued %p (queue len %d)", skb,
5740 skb_queue_len(&chan->srej_q));
5741
5742 err = l2cap_rx_queued_iframes(chan);
5743 if (err)
5744 break;
5745
5746 break;
5747 case L2CAP_TXSEQ_UNEXPECTED:
5748 /* Got a frame that can't be reassembled yet.
5749 * Save it for later, and send SREJs to cover
5750 * the missing frames.
5751 */
5752 skb_queue_tail(&chan->srej_q, skb);
5753 skb_in_use = 1;
5754 BT_DBG("Queued %p (queue len %d)", skb,
5755 skb_queue_len(&chan->srej_q));
5756
5757 l2cap_pass_to_tx(chan, control);
5758 l2cap_send_srej(chan, control->txseq);
5759 break;
5760 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
5761 /* This frame was requested with an SREJ, but
5762 * some expected retransmitted frames are
5763 * missing. Request retransmission of missing
5764 * SREJ'd frames.
5765 */
5766 skb_queue_tail(&chan->srej_q, skb);
5767 skb_in_use = 1;
5768 BT_DBG("Queued %p (queue len %d)", skb,
5769 skb_queue_len(&chan->srej_q));
5770
5771 l2cap_pass_to_tx(chan, control);
5772 l2cap_send_srej_list(chan, control->txseq);
5773 break;
5774 case L2CAP_TXSEQ_DUPLICATE_SREJ:
5775 /* We've already queued this frame. Drop this copy. */
5776 l2cap_pass_to_tx(chan, control);
5777 break;
5778 case L2CAP_TXSEQ_DUPLICATE:
5779 /* Expecting a later sequence number, so this frame
5780 * was already received. Ignore it completely.
5781 */
5782 break;
5783 case L2CAP_TXSEQ_INVALID_IGNORE:
5784 break;
5785 case L2CAP_TXSEQ_INVALID:
5786 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005787 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005788 break;
5789 }
5790 break;
5791 case L2CAP_EV_RECV_RR:
5792 l2cap_pass_to_tx(chan, control);
5793 if (control->final) {
5794 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5795
5796 if (!test_and_clear_bit(CONN_REJ_ACT,
5797 &chan->conn_state)) {
5798 control->final = 0;
5799 l2cap_retransmit_all(chan, control);
5800 }
5801
5802 l2cap_ertm_send(chan);
5803 } else if (control->poll) {
5804 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5805 &chan->conn_state) &&
5806 chan->unacked_frames) {
5807 __set_retrans_timer(chan);
5808 }
5809
5810 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5811 l2cap_send_srej_tail(chan);
5812 } else {
5813 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5814 &chan->conn_state) &&
5815 chan->unacked_frames)
5816 __set_retrans_timer(chan);
5817
5818 l2cap_send_ack(chan);
5819 }
5820 break;
5821 case L2CAP_EV_RECV_RNR:
5822 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5823 l2cap_pass_to_tx(chan, control);
5824 if (control->poll) {
5825 l2cap_send_srej_tail(chan);
5826 } else {
5827 struct l2cap_ctrl rr_control;
5828 memset(&rr_control, 0, sizeof(rr_control));
5829 rr_control.sframe = 1;
5830 rr_control.super = L2CAP_SUPER_RR;
5831 rr_control.reqseq = chan->buffer_seq;
5832 l2cap_send_sframe(chan, &rr_control);
5833 }
5834
5835 break;
5836 case L2CAP_EV_RECV_REJ:
5837 l2cap_handle_rej(chan, control);
5838 break;
5839 case L2CAP_EV_RECV_SREJ:
5840 l2cap_handle_srej(chan, control);
5841 break;
5842 }
5843
5844 if (skb && !skb_in_use) {
5845 BT_DBG("Freeing %p", skb);
5846 kfree_skb(skb);
5847 }
5848
5849 return err;
5850}
5851
Mat Martineau32b32732012-10-23 15:24:11 -07005852static int l2cap_finish_move(struct l2cap_chan *chan)
5853{
5854 BT_DBG("chan %p", chan);
5855
5856 chan->rx_state = L2CAP_RX_STATE_RECV;
5857
5858 if (chan->hs_hcon)
5859 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
5860 else
5861 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
5862
5863 return l2cap_resegment(chan);
5864}
5865
5866static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
5867 struct l2cap_ctrl *control,
5868 struct sk_buff *skb, u8 event)
5869{
5870 int err;
5871
5872 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5873 event);
5874
5875 if (!control->poll)
5876 return -EPROTO;
5877
5878 l2cap_process_reqseq(chan, control->reqseq);
5879
5880 if (!skb_queue_empty(&chan->tx_q))
5881 chan->tx_send_head = skb_peek(&chan->tx_q);
5882 else
5883 chan->tx_send_head = NULL;
5884
5885 /* Rewind next_tx_seq to the point expected
5886 * by the receiver.
5887 */
5888 chan->next_tx_seq = control->reqseq;
5889 chan->unacked_frames = 0;
5890
5891 err = l2cap_finish_move(chan);
5892 if (err)
5893 return err;
5894
5895 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5896 l2cap_send_i_or_rr_or_rnr(chan);
5897
5898 if (event == L2CAP_EV_RECV_IFRAME)
5899 return -EPROTO;
5900
5901 return l2cap_rx_state_recv(chan, control, NULL, event);
5902}
5903
5904static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
5905 struct l2cap_ctrl *control,
5906 struct sk_buff *skb, u8 event)
5907{
5908 int err;
5909
5910 if (!control->final)
5911 return -EPROTO;
5912
5913 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5914
5915 chan->rx_state = L2CAP_RX_STATE_RECV;
5916 l2cap_process_reqseq(chan, control->reqseq);
5917
5918 if (!skb_queue_empty(&chan->tx_q))
5919 chan->tx_send_head = skb_peek(&chan->tx_q);
5920 else
5921 chan->tx_send_head = NULL;
5922
5923 /* Rewind next_tx_seq to the point expected
5924 * by the receiver.
5925 */
5926 chan->next_tx_seq = control->reqseq;
5927 chan->unacked_frames = 0;
5928
5929 if (chan->hs_hcon)
5930 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
5931 else
5932 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
5933
5934 err = l2cap_resegment(chan);
5935
5936 if (!err)
5937 err = l2cap_rx_state_recv(chan, control, skb, event);
5938
5939 return err;
5940}
5941
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005942static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
5943{
5944 /* Make sure reqseq is for a packet that has been sent but not acked */
5945 u16 unacked;
5946
5947 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
5948 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
5949}
5950
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005951static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5952 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005953{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005954 int err = 0;
5955
5956 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
5957 control, skb, event, chan->rx_state);
5958
5959 if (__valid_reqseq(chan, control->reqseq)) {
5960 switch (chan->rx_state) {
5961 case L2CAP_RX_STATE_RECV:
5962 err = l2cap_rx_state_recv(chan, control, skb, event);
5963 break;
5964 case L2CAP_RX_STATE_SREJ_SENT:
5965 err = l2cap_rx_state_srej_sent(chan, control, skb,
5966 event);
5967 break;
Mat Martineau32b32732012-10-23 15:24:11 -07005968 case L2CAP_RX_STATE_WAIT_P:
5969 err = l2cap_rx_state_wait_p(chan, control, skb, event);
5970 break;
5971 case L2CAP_RX_STATE_WAIT_F:
5972 err = l2cap_rx_state_wait_f(chan, control, skb, event);
5973 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005974 default:
5975 /* shut it down */
5976 break;
5977 }
5978 } else {
5979 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
5980 control->reqseq, chan->next_tx_seq,
5981 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005982 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005983 }
5984
5985 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005986}
5987
5988static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5989 struct sk_buff *skb)
5990{
Mat Martineau4b51dae92012-05-17 20:53:37 -07005991 int err = 0;
5992
5993 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
5994 chan->rx_state);
5995
5996 if (l2cap_classify_txseq(chan, control->txseq) ==
5997 L2CAP_TXSEQ_EXPECTED) {
5998 l2cap_pass_to_tx(chan, control);
5999
6000 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6001 __next_seq(chan, chan->buffer_seq));
6002
6003 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6004
6005 l2cap_reassemble_sdu(chan, skb, control);
6006 } else {
6007 if (chan->sdu) {
6008 kfree_skb(chan->sdu);
6009 chan->sdu = NULL;
6010 }
6011 chan->sdu_last_frag = NULL;
6012 chan->sdu_len = 0;
6013
6014 if (skb) {
6015 BT_DBG("Freeing %p", skb);
6016 kfree_skb(skb);
6017 }
6018 }
6019
6020 chan->last_acked_seq = control->txseq;
6021 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6022
6023 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006024}
6025
6026static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6027{
6028 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6029 u16 len;
6030 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006031
Mat Martineaub76bbd62012-04-11 10:48:43 -07006032 __unpack_control(chan, skb);
6033
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006034 len = skb->len;
6035
6036 /*
6037 * We can just drop the corrupted I-frame here.
6038 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006039 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006040 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006041 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006042 goto drop;
6043
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006044 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006045 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006046
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006047 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006048 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006049
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006050 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006051 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006052 goto drop;
6053 }
6054
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006055 if (!control->sframe) {
6056 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006057
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006058 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6059 control->sar, control->reqseq, control->final,
6060 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006061
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006062 /* Validate F-bit - F=0 always valid, F=1 only
6063 * valid in TX WAIT_F
6064 */
6065 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006066 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006067
6068 if (chan->mode != L2CAP_MODE_STREAMING) {
6069 event = L2CAP_EV_RECV_IFRAME;
6070 err = l2cap_rx(chan, control, skb, event);
6071 } else {
6072 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006073 }
6074
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006075 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006076 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006077 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006078 const u8 rx_func_to_event[4] = {
6079 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6080 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6081 };
6082
6083 /* Only I-frames are expected in streaming mode */
6084 if (chan->mode == L2CAP_MODE_STREAMING)
6085 goto drop;
6086
6087 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6088 control->reqseq, control->final, control->poll,
6089 control->super);
6090
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006091 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006092 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006093 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006094 goto drop;
6095 }
6096
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006097 /* Validate F and P bits */
6098 if (control->final && (control->poll ||
6099 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6100 goto drop;
6101
6102 event = rx_func_to_event[control->super];
6103 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006104 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006105 }
6106
6107 return 0;
6108
6109drop:
6110 kfree_skb(skb);
6111 return 0;
6112}
6113
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006114static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6115 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006116{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006117 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006118
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006119 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006120 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006121 if (cid == L2CAP_CID_A2MP) {
6122 chan = a2mp_channel_create(conn, skb);
6123 if (!chan) {
6124 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006125 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006126 }
6127
6128 l2cap_chan_lock(chan);
6129 } else {
6130 BT_DBG("unknown cid 0x%4.4x", cid);
6131 /* Drop packet and return */
6132 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006133 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006134 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006135 }
6136
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006137 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006138
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006139 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006140 goto drop;
6141
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006142 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006143 case L2CAP_MODE_BASIC:
6144 /* If socket recv buffers overflows we drop data here
6145 * which is *bad* because L2CAP has to be reliable.
6146 * But we don't have any other choice. L2CAP doesn't
6147 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006148
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006149 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006150 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006151
Gustavo Padovan80b98022012-05-27 22:27:51 -03006152 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006153 goto done;
6154 break;
6155
6156 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006157 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006158 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006159 goto done;
6160
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006161 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006162 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006163 break;
6164 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006165
6166drop:
6167 kfree_skb(skb);
6168
6169done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006170 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006171}
6172
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006173static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6174 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006175{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006176 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006177
Ido Yarivc2287682012-04-20 15:46:07 -03006178 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006179 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006180 goto drop;
6181
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006182 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006183
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006184 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006185 goto drop;
6186
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006187 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006188 goto drop;
6189
Gustavo Padovan80b98022012-05-27 22:27:51 -03006190 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006191 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006192
6193drop:
6194 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006195}
6196
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006197static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
6198 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006199{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006200 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006201
Ido Yarivc2287682012-04-20 15:46:07 -03006202 chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006203 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006204 goto drop;
6205
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006206 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006207
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006208 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006209 goto drop;
6210
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006211 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006212 goto drop;
6213
Gustavo Padovan80b98022012-05-27 22:27:51 -03006214 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006215 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006216
6217drop:
6218 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006219}
6220
Linus Torvalds1da177e2005-04-16 15:20:36 -07006221static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6222{
6223 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006224 u16 cid, len;
6225 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006226
6227 skb_pull(skb, L2CAP_HDR_SIZE);
6228 cid = __le16_to_cpu(lh->cid);
6229 len = __le16_to_cpu(lh->len);
6230
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006231 if (len != skb->len) {
6232 kfree_skb(skb);
6233 return;
6234 }
6235
Linus Torvalds1da177e2005-04-16 15:20:36 -07006236 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6237
6238 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02006239 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006240 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006241 l2cap_sig_channel(conn, skb);
6242 break;
6243
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006244 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006245 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006246 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006247 l2cap_conless_channel(conn, psm, skb);
6248 break;
6249
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006250 case L2CAP_CID_LE_DATA:
6251 l2cap_att_channel(conn, cid, skb);
6252 break;
6253
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006254 case L2CAP_CID_SMP:
6255 if (smp_sig_channel(conn, skb))
6256 l2cap_conn_del(conn->hcon, EACCES);
6257 break;
6258
Linus Torvalds1da177e2005-04-16 15:20:36 -07006259 default:
6260 l2cap_data_channel(conn, cid, skb);
6261 break;
6262 }
6263}
6264
6265/* ---- L2CAP interface with lower layer (HCI) ---- */
6266
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006267int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006268{
6269 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006270 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006271
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006272 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006273
6274 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006275 read_lock(&chan_list_lock);
6276 list_for_each_entry(c, &chan_list, global_l) {
6277 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006278
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006279 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006280 continue;
6281
6282 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006283 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006284 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006285 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006286 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006287 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
6288 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006289 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006290 lm2 |= HCI_LM_MASTER;
6291 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006292 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006293 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006294
6295 return exact ? lm1 : lm2;
6296}
6297
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006298void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006299{
Marcel Holtmann01394182006-07-03 10:02:46 +02006300 struct l2cap_conn *conn;
6301
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006302 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006303
Linus Torvalds1da177e2005-04-16 15:20:36 -07006304 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006305 conn = l2cap_conn_add(hcon, status);
6306 if (conn)
6307 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006308 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006309 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006310 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006311}
6312
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006313int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006314{
6315 struct l2cap_conn *conn = hcon->l2cap_data;
6316
6317 BT_DBG("hcon %p", hcon);
6318
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006319 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006320 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006321 return conn->disc_reason;
6322}
6323
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006324void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006325{
6326 BT_DBG("hcon %p reason %d", hcon, reason);
6327
Joe Perchese1750722011-06-29 18:18:29 -07006328 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006329}
6330
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006331static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006332{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006333 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006334 return;
6335
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006336 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006337 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006338 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006339 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006340 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006341 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006342 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006343 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006344 }
6345}
6346
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006347int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006348{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006349 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006350 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006351
Marcel Holtmann01394182006-07-03 10:02:46 +02006352 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006353 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006354
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006355 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006356
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006357 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306358 if (!status && encrypt)
6359 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006360 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006361 }
6362
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006363 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006364
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006365 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006366 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006367
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006368 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6369 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006370
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006371 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6372 l2cap_chan_unlock(chan);
6373 continue;
6374 }
6375
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006376 if (chan->scid == L2CAP_CID_LE_DATA) {
6377 if (!status && encrypt) {
6378 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006379 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006380 }
6381
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006382 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006383 continue;
6384 }
6385
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006386 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006387 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006388 continue;
6389 }
6390
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006391 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006392 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03006393 struct sock *sk = chan->sk;
6394
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006395 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03006396 sk->sk_state_change(sk);
6397
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006398 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006399 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006400 continue;
6401 }
6402
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006403 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006404 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006405 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006406 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006407 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006408 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006409 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006410 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006411 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006412 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006413
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006414 lock_sock(sk);
6415
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006416 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006417 if (test_bit(BT_SK_DEFER_SETUP,
6418 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006419 res = L2CAP_CR_PEND;
6420 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006421 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006422 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006423 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006424 res = L2CAP_CR_SUCCESS;
6425 stat = L2CAP_CS_NO_INFO;
6426 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006427 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006428 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006429 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006430 res = L2CAP_CR_SEC_BLOCK;
6431 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006432 }
6433
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006434 release_sock(sk);
6435
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006436 rsp.scid = cpu_to_le16(chan->dcid);
6437 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006438 rsp.result = cpu_to_le16(res);
6439 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006440 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006441 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006442
6443 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6444 res == L2CAP_CR_SUCCESS) {
6445 char buf[128];
6446 set_bit(CONF_REQ_SENT, &chan->conf_state);
6447 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6448 L2CAP_CONF_REQ,
6449 l2cap_build_conf_req(chan, buf),
6450 buf);
6451 chan->num_conf_req++;
6452 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006453 }
6454
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006455 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006456 }
6457
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006458 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006459
Linus Torvalds1da177e2005-04-16 15:20:36 -07006460 return 0;
6461}
6462
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006463int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006464{
6465 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006466 struct l2cap_hdr *hdr;
6467 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006468
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006469 /* For AMP controller do not create l2cap conn */
6470 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6471 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006472
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006473 if (!conn)
6474 conn = l2cap_conn_add(hcon, 0);
6475
6476 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006477 goto drop;
6478
6479 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6480
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006481 switch (flags) {
6482 case ACL_START:
6483 case ACL_START_NO_FLUSH:
6484 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006485 if (conn->rx_len) {
6486 BT_ERR("Unexpected start frame (len %d)", skb->len);
6487 kfree_skb(conn->rx_skb);
6488 conn->rx_skb = NULL;
6489 conn->rx_len = 0;
6490 l2cap_conn_unreliable(conn, ECOMM);
6491 }
6492
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006493 /* Start fragment always begin with Basic L2CAP header */
6494 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006495 BT_ERR("Frame is too short (len %d)", skb->len);
6496 l2cap_conn_unreliable(conn, ECOMM);
6497 goto drop;
6498 }
6499
6500 hdr = (struct l2cap_hdr *) skb->data;
6501 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6502
6503 if (len == skb->len) {
6504 /* Complete frame received */
6505 l2cap_recv_frame(conn, skb);
6506 return 0;
6507 }
6508
6509 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6510
6511 if (skb->len > len) {
6512 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006513 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006514 l2cap_conn_unreliable(conn, ECOMM);
6515 goto drop;
6516 }
6517
6518 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006519 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006520 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006521 goto drop;
6522
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006523 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006524 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006525 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006526 break;
6527
6528 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006529 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6530
6531 if (!conn->rx_len) {
6532 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6533 l2cap_conn_unreliable(conn, ECOMM);
6534 goto drop;
6535 }
6536
6537 if (skb->len > conn->rx_len) {
6538 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006539 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006540 kfree_skb(conn->rx_skb);
6541 conn->rx_skb = NULL;
6542 conn->rx_len = 0;
6543 l2cap_conn_unreliable(conn, ECOMM);
6544 goto drop;
6545 }
6546
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006547 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006548 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006549 conn->rx_len -= skb->len;
6550
6551 if (!conn->rx_len) {
6552 /* Complete frame received */
6553 l2cap_recv_frame(conn, conn->rx_skb);
6554 conn->rx_skb = NULL;
6555 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006556 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006557 }
6558
6559drop:
6560 kfree_skb(skb);
6561 return 0;
6562}
6563
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006564static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006565{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006566 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006567
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006568 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006569
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006570 list_for_each_entry(c, &chan_list, global_l) {
6571 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006572
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006573 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
6574 &bt_sk(sk)->src, &bt_sk(sk)->dst,
6575 c->state, __le16_to_cpu(c->psm),
6576 c->scid, c->dcid, c->imtu, c->omtu,
6577 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006578 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006579
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006580 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006581
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006582 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006583}
6584
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006585static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6586{
6587 return single_open(file, l2cap_debugfs_show, inode->i_private);
6588}
6589
6590static const struct file_operations l2cap_debugfs_fops = {
6591 .open = l2cap_debugfs_open,
6592 .read = seq_read,
6593 .llseek = seq_lseek,
6594 .release = single_release,
6595};
6596
6597static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006598
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006599int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006600{
6601 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006602
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006603 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006604 if (err < 0)
6605 return err;
6606
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006607 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006608 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6609 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006610 if (!l2cap_debugfs)
6611 BT_ERR("Failed to create L2CAP debug file");
6612 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006613
Linus Torvalds1da177e2005-04-16 15:20:36 -07006614 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006615}
6616
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006617void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006618{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006619 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006620 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006621}
6622
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006623module_param(disable_ertm, bool, 0644);
6624MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");