blob: 93f1ebbd75025a673df4ea38eec0e5a68e5de38b [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
Gustavo F. Padovance5706b2010-07-13 11:57:11 -03004 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
Gustavo F. Padovan5d8868f2010-07-16 16:18:39 -03005 Copyright (C) 2010 Google Inc.
Gustavo F. Padovan590051d2011-12-18 13:39:33 -02006 Copyright (C) 2011 ProFUSION Embedded Systems
Mat Martineau422e9252012-04-27 16:50:55 -07007 Copyright (c) 2012 Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07008
9 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License version 2 as
13 published by the Free Software Foundation;
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
18 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090019 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090024 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
25 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 SOFTWARE IS DISCLAIMED.
27*/
28
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020029/* Bluetooth L2CAP core. */
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/module.h>
32
Marcel Holtmannaef7d972010-03-21 05:27:45 +010033#include <linux/debugfs.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030034#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#include <net/bluetooth/bluetooth.h>
37#include <net/bluetooth/hci_core.h>
38#include <net/bluetooth/l2cap.h>
Anderson Brigliab501d6a2011-06-07 18:46:31 -030039#include <net/bluetooth/smp.h>
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +030040#include <net/bluetooth/a2mp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041
Mat Martineaud1de6d42012-05-17 20:53:55 -070042bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020043
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070044static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Mat Martineau50a147c2011-11-02 16:18:34 -070045static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
Johannes Bergb5ad8b72011-06-01 08:54:45 +020047static LIST_HEAD(chan_list);
48static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
Linus Torvalds1da177e2005-04-16 15:20:36 -070050static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010051 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030052static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010053 void *data);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -030054static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030055static void l2cap_send_disconn_req(struct l2cap_conn *conn,
Gustavo Padovanc5daa682012-05-16 12:17:10 -030056 struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Gustavo Padovand6603662012-05-21 13:58:22 -030058static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010059 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070060
Marcel Holtmann01394182006-07-03 10:02:46 +020061/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030062
Gustavo Padovan2d792812012-10-06 10:07:01 +010063static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
64 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020065{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020066 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030067
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020068 list_for_each_entry(c, &conn->chan_l, list) {
69 if (c->dcid == cid)
70 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020071 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020072 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020073}
74
Gustavo Padovan2d792812012-10-06 10:07:01 +010075static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
76 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020077{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020078 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030079
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020080 list_for_each_entry(c, &conn->chan_l, list) {
81 if (c->scid == cid)
82 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020083 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020084 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020085}
86
87/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -070088 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +010089static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
90 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020091{
Gustavo F. Padovan48454072011-03-25 00:22:30 -030092 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030093
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020094 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030095 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -070096 if (c)
97 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020098 mutex_unlock(&conn->chan_lock);
99
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300100 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200101}
102
Mat Martineaub1a130b2012-10-23 15:24:09 -0700103/* Find channel with given DCID.
104 * Returns locked channel.
105 */
106static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
107 u16 cid)
108{
109 struct l2cap_chan *c;
110
111 mutex_lock(&conn->chan_lock);
112 c = __l2cap_get_chan_by_dcid(conn, cid);
113 if (c)
114 l2cap_chan_lock(c);
115 mutex_unlock(&conn->chan_lock);
116
117 return c;
118}
119
Gustavo Padovan2d792812012-10-06 10:07:01 +0100120static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
121 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200122{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200123 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300124
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200125 list_for_each_entry(c, &conn->chan_l, list) {
126 if (c->ident == ident)
127 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200128 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200129 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200130}
131
Mat Martineau5b155ef2012-10-23 15:24:14 -0700132static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
133 u8 ident)
134{
135 struct l2cap_chan *c;
136
137 mutex_lock(&conn->chan_lock);
138 c = __l2cap_get_chan_by_ident(conn, ident);
139 if (c)
140 l2cap_chan_lock(c);
141 mutex_unlock(&conn->chan_lock);
142
143 return c;
144}
145
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300146static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300147{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300148 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300149
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300150 list_for_each_entry(c, &chan_list, global_l) {
151 if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100152 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300153 }
Szymon Janc250938c2011-11-16 09:32:22 +0100154 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300155}
156
157int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
158{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300159 int err;
160
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200161 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300162
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300163 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300164 err = -EADDRINUSE;
165 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300166 }
167
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300168 if (psm) {
169 chan->psm = psm;
170 chan->sport = psm;
171 err = 0;
172 } else {
173 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300174
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300175 err = -EINVAL;
176 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300177 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300178 chan->psm = cpu_to_le16(p);
179 chan->sport = cpu_to_le16(p);
180 err = 0;
181 break;
182 }
183 }
184
185done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200186 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300187 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300188}
189
190int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
191{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200192 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300193
194 chan->scid = scid;
195
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200196 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300197
198 return 0;
199}
200
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300201static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200202{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300203 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200204
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300205 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300206 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200207 return cid;
208 }
209
210 return 0;
211}
212
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200213static void __l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300214{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200215 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100216 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200217
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300218 chan->state = state;
Gustavo Padovan80b98022012-05-27 22:27:51 -0300219 chan->ops->state_change(chan, state);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300220}
221
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200222static void l2cap_state_change(struct l2cap_chan *chan, int state)
223{
224 struct sock *sk = chan->sk;
225
226 lock_sock(sk);
227 __l2cap_state_change(chan, state);
228 release_sock(sk);
229}
230
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200231static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
232{
233 struct sock *sk = chan->sk;
234
235 sk->sk_err = err;
236}
237
238static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
239{
240 struct sock *sk = chan->sk;
241
242 lock_sock(sk);
243 __l2cap_chan_set_err(chan, err);
244 release_sock(sk);
245}
246
Mat Martineau4239d162012-05-17 20:53:49 -0700247static void __set_retrans_timer(struct l2cap_chan *chan)
248{
249 if (!delayed_work_pending(&chan->monitor_timer) &&
250 chan->retrans_timeout) {
251 l2cap_set_timer(chan, &chan->retrans_timer,
252 msecs_to_jiffies(chan->retrans_timeout));
253 }
254}
255
256static void __set_monitor_timer(struct l2cap_chan *chan)
257{
258 __clear_retrans_timer(chan);
259 if (chan->monitor_timeout) {
260 l2cap_set_timer(chan, &chan->monitor_timer,
261 msecs_to_jiffies(chan->monitor_timeout));
262 }
263}
264
Mat Martineau608bcc62012-05-17 20:53:32 -0700265static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
266 u16 seq)
267{
268 struct sk_buff *skb;
269
270 skb_queue_walk(head, skb) {
271 if (bt_cb(skb)->control.txseq == seq)
272 return skb;
273 }
274
275 return NULL;
276}
277
Mat Martineau3c588192012-04-11 10:48:42 -0700278/* ---- L2CAP sequence number lists ---- */
279
280/* For ERTM, ordered lists of sequence numbers must be tracked for
281 * SREJ requests that are received and for frames that are to be
282 * retransmitted. These seq_list functions implement a singly-linked
283 * list in an array, where membership in the list can also be checked
284 * in constant time. Items can also be added to the tail of the list
285 * and removed from the head in constant time, without further memory
286 * allocs or frees.
287 */
288
289static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
290{
291 size_t alloc_size, i;
292
293 /* Allocated size is a power of 2 to map sequence numbers
294 * (which may be up to 14 bits) in to a smaller array that is
295 * sized for the negotiated ERTM transmit windows.
296 */
297 alloc_size = roundup_pow_of_two(size);
298
299 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
300 if (!seq_list->list)
301 return -ENOMEM;
302
303 seq_list->mask = alloc_size - 1;
304 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
305 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
306 for (i = 0; i < alloc_size; i++)
307 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
308
309 return 0;
310}
311
312static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
313{
314 kfree(seq_list->list);
315}
316
317static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
318 u16 seq)
319{
320 /* Constant-time check for list membership */
321 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
322}
323
324static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
325{
326 u16 mask = seq_list->mask;
327
328 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
329 /* In case someone tries to pop the head of an empty list */
330 return L2CAP_SEQ_LIST_CLEAR;
331 } else if (seq_list->head == seq) {
332 /* Head can be removed in constant time */
333 seq_list->head = seq_list->list[seq & mask];
334 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
335
336 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
337 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
338 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
339 }
340 } else {
341 /* Walk the list to find the sequence number */
342 u16 prev = seq_list->head;
343 while (seq_list->list[prev & mask] != seq) {
344 prev = seq_list->list[prev & mask];
345 if (prev == L2CAP_SEQ_LIST_TAIL)
346 return L2CAP_SEQ_LIST_CLEAR;
347 }
348
349 /* Unlink the number from the list and clear it */
350 seq_list->list[prev & mask] = seq_list->list[seq & mask];
351 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
352 if (seq_list->tail == seq)
353 seq_list->tail = prev;
354 }
355 return seq;
356}
357
358static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
359{
360 /* Remove the head in constant time */
361 return l2cap_seq_list_remove(seq_list, seq_list->head);
362}
363
364static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
365{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300366 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700367
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300368 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
369 return;
370
371 for (i = 0; i <= seq_list->mask; i++)
372 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
373
374 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
375 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700376}
377
378static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
379{
380 u16 mask = seq_list->mask;
381
382 /* All appends happen in constant time */
383
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300384 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
385 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700386
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300387 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
388 seq_list->head = seq;
389 else
390 seq_list->list[seq_list->tail & mask] = seq;
391
392 seq_list->tail = seq;
393 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700394}
395
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300396static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300397{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300398 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100399 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200400 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300401 int reason;
402
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200403 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300404
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200405 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200406 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300407
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300408 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300409 reason = ECONNREFUSED;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300410 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100411 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300412 reason = ECONNREFUSED;
413 else
414 reason = ETIMEDOUT;
415
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300416 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300417
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200418 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300419
Gustavo Padovan80b98022012-05-27 22:27:51 -0300420 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200421 mutex_unlock(&conn->chan_lock);
422
Ulisses Furquim371fd832011-12-21 20:02:36 -0200423 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300424}
425
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300426struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200427{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300428 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200429
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300430 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
431 if (!chan)
432 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200433
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200434 mutex_init(&chan->lock);
435
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200436 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300437 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200438 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300439
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300440 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300441
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300442 chan->state = BT_OPEN;
443
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530444 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300445
Mat Martineau28270112012-05-17 21:14:09 -0700446 /* This flag is cleared in l2cap_chan_ready() */
447 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
448
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300449 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100450
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300451 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200452}
453
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530454static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300455{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530456 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
457
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530458 BT_DBG("chan %p", chan);
459
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200460 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300461 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200462 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300463
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530464 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300465}
466
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530467void l2cap_chan_hold(struct l2cap_chan *c)
468{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530469 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530470
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530471 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530472}
473
474void l2cap_chan_put(struct l2cap_chan *c)
475{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530476 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530477
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530478 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530479}
480
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300481void l2cap_chan_set_defaults(struct l2cap_chan *chan)
482{
483 chan->fcs = L2CAP_FCS_CRC16;
484 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
485 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
486 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700487 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300488 chan->sec_level = BT_SECURITY_LOW;
489
490 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
491}
492
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300493void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200494{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300495 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200496 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200497
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200498 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100499
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300500 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200501
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200502 switch (chan->chan_type) {
503 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300504 if (conn->hcon->type == LE_LINK) {
505 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300506 chan->omtu = L2CAP_DEFAULT_MTU;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300507 chan->scid = L2CAP_CID_LE_DATA;
508 chan->dcid = L2CAP_CID_LE_DATA;
Ville Tervob62f3282011-02-10 22:38:50 -0300509 } else {
510 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300511 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300512 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300513 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200514 break;
515
516 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200517 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300518 chan->scid = L2CAP_CID_CONN_LESS;
519 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300520 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200521 break;
522
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300523 case L2CAP_CHAN_CONN_FIX_A2MP:
524 chan->scid = L2CAP_CID_A2MP;
525 chan->dcid = L2CAP_CID_A2MP;
526 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
527 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
528 break;
529
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200530 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200531 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300532 chan->scid = L2CAP_CID_SIGNALING;
533 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300534 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200535 }
536
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300537 chan->local_id = L2CAP_BESTEFFORT_ID;
538 chan->local_stype = L2CAP_SERV_BESTEFFORT;
539 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
540 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
541 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300542 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300543
Ulisses Furquim371fd832011-12-21 20:02:36 -0200544 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300545
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200546 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200547}
548
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300549void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200550{
551 mutex_lock(&conn->chan_lock);
552 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200553 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200554}
555
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300556void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200557{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300558 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200559
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300560 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200561
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300562 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200563
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900564 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300565 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300566 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200567 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200568
Ulisses Furquim371fd832011-12-21 20:02:36 -0200569 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300570
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300571 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300572
573 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
574 hci_conn_put(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300575
576 if (mgr && mgr->bredr_chan == chan)
577 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200578 }
579
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100580 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200581
Mat Martineau28270112012-05-17 21:14:09 -0700582 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300583 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300584
Gustavo Padovanee556f62012-05-18 20:22:38 -0300585 switch(chan->mode) {
586 case L2CAP_MODE_BASIC:
587 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300588
Gustavo Padovanee556f62012-05-18 20:22:38 -0300589 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300590 __clear_retrans_timer(chan);
591 __clear_monitor_timer(chan);
592 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300593
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300594 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300595
Mat Martineau3c588192012-04-11 10:48:42 -0700596 l2cap_seq_list_free(&chan->srej_list);
597 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300598
599 /* fall through */
600
601 case L2CAP_MODE_STREAMING:
602 skb_queue_purge(&chan->tx_q);
603 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300604 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300605
606 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200607}
608
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300609void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300610{
611 struct l2cap_conn *conn = chan->conn;
612 struct sock *sk = chan->sk;
613
Gustavo Padovan2d792812012-10-06 10:07:01 +0100614 BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state),
615 sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300616
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300617 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300618 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100619 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300620 break;
621
622 case BT_CONNECTED:
623 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300624 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100625 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300626 __set_chan_timer(chan, sk->sk_sndtimeo);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300627 l2cap_send_disconn_req(conn, chan, reason);
628 } else
629 l2cap_chan_del(chan, reason);
630 break;
631
632 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300633 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100634 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300635 struct l2cap_conn_rsp rsp;
636 __u16 result;
637
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300638 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300639 result = L2CAP_CR_SEC_BLOCK;
640 else
641 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300642 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300643
644 rsp.scid = cpu_to_le16(chan->dcid);
645 rsp.dcid = cpu_to_le16(chan->scid);
646 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300647 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300648 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100649 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300650 }
651
652 l2cap_chan_del(chan, reason);
653 break;
654
655 case BT_CONNECT:
656 case BT_DISCONN:
657 l2cap_chan_del(chan, reason);
658 break;
659
660 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100661 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300662 break;
663 }
664}
665
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300666static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530667{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300668 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300669 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530670 case BT_SECURITY_HIGH:
671 return HCI_AT_DEDICATED_BONDING_MITM;
672 case BT_SECURITY_MEDIUM:
673 return HCI_AT_DEDICATED_BONDING;
674 default:
675 return HCI_AT_NO_BONDING;
676 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300677 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300678 if (chan->sec_level == BT_SECURITY_LOW)
679 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530680
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300681 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530682 return HCI_AT_NO_BONDING_MITM;
683 else
684 return HCI_AT_NO_BONDING;
685 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300686 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530687 case BT_SECURITY_HIGH:
688 return HCI_AT_GENERAL_BONDING_MITM;
689 case BT_SECURITY_MEDIUM:
690 return HCI_AT_GENERAL_BONDING;
691 default:
692 return HCI_AT_NO_BONDING;
693 }
694 }
695}
696
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200697/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200698int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200699{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300700 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100701 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200702
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300703 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100704
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300705 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200706}
707
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200708static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200709{
710 u8 id;
711
712 /* Get next available identificator.
713 * 1 - 128 are used by kernel.
714 * 129 - 199 are reserved.
715 * 200 - 254 are used by utilities like l2ping, etc.
716 */
717
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200718 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200719
720 if (++conn->tx_ident > 128)
721 conn->tx_ident = 1;
722
723 id = conn->tx_ident;
724
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200725 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200726
727 return id;
728}
729
Gustavo Padovan2d792812012-10-06 10:07:01 +0100730static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
731 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200732{
733 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200734 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200735
736 BT_DBG("code 0x%2.2x", code);
737
738 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300739 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200740
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200741 if (lmp_no_flush_capable(conn->hcon->hdev))
742 flags = ACL_START_NO_FLUSH;
743 else
744 flags = ACL_START;
745
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700746 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200747 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700748
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200749 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200750}
751
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700752static bool __chan_is_moving(struct l2cap_chan *chan)
753{
754 return chan->move_state != L2CAP_MOVE_STABLE &&
755 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
756}
757
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200758static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
759{
760 struct hci_conn *hcon = chan->conn->hcon;
761 u16 flags;
762
763 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100764 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200765
Mat Martineaud5f8a752012-10-23 15:24:18 -0700766 if (chan->hs_hcon && !__chan_is_moving(chan)) {
767 if (chan->hs_hchan)
768 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
769 else
770 kfree_skb(skb);
771
772 return;
773 }
774
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200775 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100776 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200777 flags = ACL_START_NO_FLUSH;
778 else
779 flags = ACL_START;
780
781 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
782 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783}
784
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700785static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
786{
787 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
788 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
789
790 if (enh & L2CAP_CTRL_FRAME_TYPE) {
791 /* S-Frame */
792 control->sframe = 1;
793 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
794 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
795
796 control->sar = 0;
797 control->txseq = 0;
798 } else {
799 /* I-Frame */
800 control->sframe = 0;
801 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
802 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
803
804 control->poll = 0;
805 control->super = 0;
806 }
807}
808
809static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
810{
811 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
812 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
813
814 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
815 /* S-Frame */
816 control->sframe = 1;
817 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
818 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
819
820 control->sar = 0;
821 control->txseq = 0;
822 } else {
823 /* I-Frame */
824 control->sframe = 0;
825 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
826 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
827
828 control->poll = 0;
829 control->super = 0;
830 }
831}
832
833static inline void __unpack_control(struct l2cap_chan *chan,
834 struct sk_buff *skb)
835{
836 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
837 __unpack_extended_control(get_unaligned_le32(skb->data),
838 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700839 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700840 } else {
841 __unpack_enhanced_control(get_unaligned_le16(skb->data),
842 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700843 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700844 }
845}
846
847static u32 __pack_extended_control(struct l2cap_ctrl *control)
848{
849 u32 packed;
850
851 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
852 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
853
854 if (control->sframe) {
855 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
856 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
857 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
858 } else {
859 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
860 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
861 }
862
863 return packed;
864}
865
866static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
867{
868 u16 packed;
869
870 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
871 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
872
873 if (control->sframe) {
874 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
875 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
876 packed |= L2CAP_CTRL_FRAME_TYPE;
877 } else {
878 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
879 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
880 }
881
882 return packed;
883}
884
885static inline void __pack_control(struct l2cap_chan *chan,
886 struct l2cap_ctrl *control,
887 struct sk_buff *skb)
888{
889 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
890 put_unaligned_le32(__pack_extended_control(control),
891 skb->data + L2CAP_HDR_SIZE);
892 } else {
893 put_unaligned_le16(__pack_enhanced_control(control),
894 skb->data + L2CAP_HDR_SIZE);
895 }
896}
897
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300898static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
899{
900 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
901 return L2CAP_EXT_HDR_SIZE;
902 else
903 return L2CAP_ENH_HDR_SIZE;
904}
905
Mat Martineaua67d7f62012-05-17 20:53:35 -0700906static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
907 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300908{
909 struct sk_buff *skb;
910 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300911 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300912
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300913 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300914 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300915
Mat Martineaua67d7f62012-05-17 20:53:35 -0700916 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300917
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300918 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700919 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300920
921 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300922 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300923 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300924
Mat Martineaua67d7f62012-05-17 20:53:35 -0700925 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
926 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
927 else
928 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300929
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300930 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700931 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300932 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300933 }
934
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200935 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700936 return skb;
937}
938
939static void l2cap_send_sframe(struct l2cap_chan *chan,
940 struct l2cap_ctrl *control)
941{
942 struct sk_buff *skb;
943 u32 control_field;
944
945 BT_DBG("chan %p, control %p", chan, control);
946
947 if (!control->sframe)
948 return;
949
Mat Martineaub99e13a2012-10-23 15:24:19 -0700950 if (__chan_is_moving(chan))
951 return;
952
Mat Martineaua67d7f62012-05-17 20:53:35 -0700953 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
954 !control->poll)
955 control->final = 1;
956
957 if (control->super == L2CAP_SUPER_RR)
958 clear_bit(CONN_RNR_SENT, &chan->conn_state);
959 else if (control->super == L2CAP_SUPER_RNR)
960 set_bit(CONN_RNR_SENT, &chan->conn_state);
961
962 if (control->super != L2CAP_SUPER_SREJ) {
963 chan->last_acked_seq = control->reqseq;
964 __clear_ack_timer(chan);
965 }
966
967 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
968 control->final, control->poll, control->super);
969
970 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
971 control_field = __pack_extended_control(control);
972 else
973 control_field = __pack_enhanced_control(control);
974
975 skb = l2cap_create_sframe_pdu(chan, control_field);
976 if (!IS_ERR(skb))
977 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300978}
979
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700980static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300981{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700982 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300983
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700984 BT_DBG("chan %p, poll %d", chan, poll);
985
986 memset(&control, 0, sizeof(control));
987 control.sframe = 1;
988 control.poll = poll;
989
990 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
991 control.super = L2CAP_SUPER_RNR;
992 else
993 control.super = L2CAP_SUPER_RR;
994
995 control.reqseq = chan->buffer_seq;
996 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300997}
998
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300999static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001000{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001001 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001002}
1003
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001004static bool __amp_capable(struct l2cap_chan *chan)
1005{
1006 struct l2cap_conn *conn = chan->conn;
1007
1008 if (enable_hs &&
1009 chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED &&
1010 conn->fixed_chan_mask & L2CAP_FC_A2MP)
1011 return true;
1012 else
1013 return false;
1014}
1015
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001016void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001017{
1018 struct l2cap_conn *conn = chan->conn;
1019 struct l2cap_conn_req req;
1020
1021 req.scid = cpu_to_le16(chan->scid);
1022 req.psm = chan->psm;
1023
1024 chan->ident = l2cap_get_ident(conn);
1025
1026 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1027
1028 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1029}
1030
Mat Martineau8eb200b2012-10-23 15:24:17 -07001031static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1032{
1033 struct l2cap_create_chan_req req;
1034 req.scid = cpu_to_le16(chan->scid);
1035 req.psm = chan->psm;
1036 req.amp_id = amp_id;
1037
1038 chan->ident = l2cap_get_ident(chan->conn);
1039
1040 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1041 sizeof(req), &req);
1042}
1043
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001044static void l2cap_move_setup(struct l2cap_chan *chan)
1045{
1046 struct sk_buff *skb;
1047
1048 BT_DBG("chan %p", chan);
1049
1050 if (chan->mode != L2CAP_MODE_ERTM)
1051 return;
1052
1053 __clear_retrans_timer(chan);
1054 __clear_monitor_timer(chan);
1055 __clear_ack_timer(chan);
1056
1057 chan->retry_count = 0;
1058 skb_queue_walk(&chan->tx_q, skb) {
1059 if (bt_cb(skb)->control.retries)
1060 bt_cb(skb)->control.retries = 1;
1061 else
1062 break;
1063 }
1064
1065 chan->expected_tx_seq = chan->buffer_seq;
1066
1067 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1068 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1069 l2cap_seq_list_clear(&chan->retrans_list);
1070 l2cap_seq_list_clear(&chan->srej_list);
1071 skb_queue_purge(&chan->srej_q);
1072
1073 chan->tx_state = L2CAP_TX_STATE_XMIT;
1074 chan->rx_state = L2CAP_RX_STATE_MOVE;
1075
1076 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1077}
1078
Mat Martineau5f3847a2012-10-23 15:24:12 -07001079static void l2cap_move_done(struct l2cap_chan *chan)
1080{
1081 u8 move_role = chan->move_role;
1082 BT_DBG("chan %p", chan);
1083
1084 chan->move_state = L2CAP_MOVE_STABLE;
1085 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1086
1087 if (chan->mode != L2CAP_MODE_ERTM)
1088 return;
1089
1090 switch (move_role) {
1091 case L2CAP_MOVE_ROLE_INITIATOR:
1092 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1093 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1094 break;
1095 case L2CAP_MOVE_ROLE_RESPONDER:
1096 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1097 break;
1098 }
1099}
1100
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001101static void l2cap_chan_ready(struct l2cap_chan *chan)
1102{
Mat Martineau28270112012-05-17 21:14:09 -07001103 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001104 chan->conf_state = 0;
1105 __clear_chan_timer(chan);
1106
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001107 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001108
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001109 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001110}
1111
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001112static void l2cap_start_connection(struct l2cap_chan *chan)
1113{
1114 if (__amp_capable(chan)) {
1115 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1116 a2mp_discover_amp(chan);
1117 } else {
1118 l2cap_send_conn_req(chan);
1119 }
1120}
1121
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001122static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001123{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001124 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001125
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001126 if (conn->hcon->type == LE_LINK) {
1127 l2cap_chan_ready(chan);
1128 return;
1129 }
1130
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001131 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001132 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1133 return;
1134
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001135 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001136 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001137 l2cap_start_connection(chan);
1138 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001139 } else {
1140 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001141 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001142
1143 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1144 conn->info_ident = l2cap_get_ident(conn);
1145
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001146 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001147
Gustavo Padovan2d792812012-10-06 10:07:01 +01001148 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1149 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001150 }
1151}
1152
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001153static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1154{
1155 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001156 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001157 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1158
1159 switch (mode) {
1160 case L2CAP_MODE_ERTM:
1161 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1162 case L2CAP_MODE_STREAMING:
1163 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1164 default:
1165 return 0x00;
1166 }
1167}
1168
Gustavo Padovan2d792812012-10-06 10:07:01 +01001169static void l2cap_send_disconn_req(struct l2cap_conn *conn,
1170 struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001171{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001172 struct sock *sk = chan->sk;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001173 struct l2cap_disconn_req req;
1174
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001175 if (!conn)
1176 return;
1177
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001178 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001179 __clear_retrans_timer(chan);
1180 __clear_monitor_timer(chan);
1181 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001182 }
1183
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001184 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001185 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001186 return;
1187 }
1188
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001189 req.dcid = cpu_to_le16(chan->dcid);
1190 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001191 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1192 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001193
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001194 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001195 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001196 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001197 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001198}
1199
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001201static void l2cap_conn_start(struct l2cap_conn *conn)
1202{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001203 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001204
1205 BT_DBG("conn %p", conn);
1206
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001207 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001208
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001209 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001210 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001211
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001212 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001213
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001214 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001215 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001216 continue;
1217 }
1218
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001219 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001220 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001221 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001222 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001223 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001224 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001225
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001226 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001227 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001228 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001229 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001230 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001231 continue;
1232 }
1233
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001234 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001235
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001236 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001237 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001238 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001239 rsp.scid = cpu_to_le16(chan->dcid);
1240 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001241
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001242 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001243 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001244 if (test_bit(BT_SK_DEFER_SETUP,
1245 &bt_sk(sk)->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001246 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1247 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001248 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001249
1250 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001251 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001252 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1253 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001254 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001255 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001256 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001257 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1258 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001259 }
1260
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001261 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001262 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001263
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001264 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001265 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001266 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001267 continue;
1268 }
1269
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001270 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001271 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001272 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001273 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001274 }
1275
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001276 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001277 }
1278
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001279 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001280}
1281
Ido Yarivc2287682012-04-20 15:46:07 -03001282/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001283 * Returns closest match, locked.
1284 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001285static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001286 bdaddr_t *src,
1287 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001288{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001289 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001290
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001291 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001292
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001293 list_for_each_entry(c, &chan_list, global_l) {
1294 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001295
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001296 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001297 continue;
1298
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001299 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001300 int src_match, dst_match;
1301 int src_any, dst_any;
1302
Ville Tervob62f3282011-02-10 22:38:50 -03001303 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001304 src_match = !bacmp(&bt_sk(sk)->src, src);
1305 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1306 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001307 read_unlock(&chan_list_lock);
1308 return c;
1309 }
Ville Tervob62f3282011-02-10 22:38:50 -03001310
1311 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001312 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1313 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1314 if ((src_match && dst_any) || (src_any && dst_match) ||
1315 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001316 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001317 }
1318 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001319
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001320 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001321
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001322 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001323}
1324
1325static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1326{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001327 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001328 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001329
1330 BT_DBG("");
1331
1332 /* Check if we have socket listening on cid */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001333 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
Ido Yarivc2287682012-04-20 15:46:07 -03001334 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001335 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001336 return;
1337
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001338 parent = pchan->sk;
1339
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001340 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001341
Gustavo Padovan80b98022012-05-27 22:27:51 -03001342 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001343 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001344 goto clean;
1345
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001346 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001347
Ville Tervob62f3282011-02-10 22:38:50 -03001348 hci_conn_hold(conn->hcon);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001349 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
Ville Tervob62f3282011-02-10 22:38:50 -03001350
Ville Tervob62f3282011-02-10 22:38:50 -03001351 bacpy(&bt_sk(sk)->src, conn->src);
1352 bacpy(&bt_sk(sk)->dst, conn->dst);
1353
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001354 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001355
Gustavo Padovan6754e0d2012-05-25 09:30:56 -03001356 l2cap_chan_ready(chan);
Ville Tervob62f3282011-02-10 22:38:50 -03001357
Ville Tervob62f3282011-02-10 22:38:50 -03001358clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001359 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001360}
1361
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001362static void l2cap_conn_ready(struct l2cap_conn *conn)
1363{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001364 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001365 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001366
1367 BT_DBG("conn %p", conn);
1368
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001369 if (!hcon->out && hcon->type == LE_LINK)
Ville Tervob62f3282011-02-10 22:38:50 -03001370 l2cap_le_conn_ready(conn);
1371
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001372 if (hcon->out && hcon->type == LE_LINK)
1373 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001374
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001375 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001376
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001377 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001378
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001379 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001380
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001381 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1382 l2cap_chan_unlock(chan);
1383 continue;
1384 }
1385
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001386 if (hcon->type == LE_LINK) {
1387 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001388 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001389
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001390 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001391 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001392 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001393 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001394 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001395 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001396 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001397
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001398 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001399 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001400
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001401 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001402 }
1403
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001404 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001405}
1406
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001407/* Notify sockets that we cannot guaranty reliability anymore */
1408static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1409{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001410 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001411
1412 BT_DBG("conn %p", conn);
1413
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001414 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001415
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001416 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001417 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001418 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001419 }
1420
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001421 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001422}
1423
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001424static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001425{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001426 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001427 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001428
Marcel Holtmann984947d2009-02-06 23:35:19 +01001429 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001430 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001431
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001432 l2cap_conn_start(conn);
1433}
1434
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001435static void l2cap_conn_del(struct hci_conn *hcon, int err)
1436{
1437 struct l2cap_conn *conn = hcon->l2cap_data;
1438 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001439
1440 if (!conn)
1441 return;
1442
1443 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1444
1445 kfree_skb(conn->rx_skb);
1446
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001447 mutex_lock(&conn->chan_lock);
1448
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001449 /* Kill channels */
1450 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001451 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001452 l2cap_chan_lock(chan);
1453
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001454 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001455
1456 l2cap_chan_unlock(chan);
1457
Gustavo Padovan80b98022012-05-27 22:27:51 -03001458 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001459 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001460 }
1461
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001462 mutex_unlock(&conn->chan_lock);
1463
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001464 hci_chan_del(conn->hchan);
1465
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001466 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001467 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001468
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001469 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001470 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001471 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001472 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001473
1474 hcon->l2cap_data = NULL;
1475 kfree(conn);
1476}
1477
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001478static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001479{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001480 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001481 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001482
Johan Hedbergd06cc412012-06-06 18:44:11 +08001483 BT_DBG("conn %p", conn);
1484
1485 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1486 smp_chan_destroy(conn);
1487 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1488 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001489}
1490
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1492{
Marcel Holtmann01394182006-07-03 10:02:46 +02001493 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001494 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495
Marcel Holtmann01394182006-07-03 10:02:46 +02001496 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497 return conn;
1498
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001499 hchan = hci_chan_create(hcon);
1500 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001503 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001504 if (!conn) {
1505 hci_chan_del(hchan);
1506 return NULL;
1507 }
1508
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509 hcon->l2cap_data = conn;
1510 conn->hcon = hcon;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001511 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001513 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001514
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001515 switch (hcon->type) {
1516 case AMP_LINK:
1517 conn->mtu = hcon->hdev->block_mtu;
1518 break;
1519
1520 case LE_LINK:
1521 if (hcon->hdev->le_mtu) {
1522 conn->mtu = hcon->hdev->le_mtu;
1523 break;
1524 }
1525 /* fall through */
1526
1527 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001528 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001529 break;
1530 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001531
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 conn->src = &hcon->hdev->bdaddr;
1533 conn->dst = &hcon->dst;
1534
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001535 conn->feat_mask = 0;
1536
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001538 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001539
1540 INIT_LIST_HEAD(&conn->chan_l);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001542 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001543 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001544 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001545 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001546
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001547 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001548
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 return conn;
1550}
1551
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553
Ido Yarivc2287682012-04-20 15:46:07 -03001554/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001555 * Returns closest match.
1556 */
Ido Yarivc2287682012-04-20 15:46:07 -03001557static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1558 bdaddr_t *src,
1559 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001561 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001563 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001564
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001565 list_for_each_entry(c, &chan_list, global_l) {
1566 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001567
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001568 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569 continue;
1570
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001571 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001572 int src_match, dst_match;
1573 int src_any, dst_any;
1574
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001576 src_match = !bacmp(&bt_sk(sk)->src, src);
1577 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1578 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001579 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001580 return c;
1581 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582
1583 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001584 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1585 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1586 if ((src_match && dst_any) || (src_any && dst_match) ||
1587 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001588 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589 }
1590 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001592 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001593
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001594 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595}
1596
Andre Guedes8e9f9892012-04-24 21:02:55 -03001597int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1598 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001600 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602 struct l2cap_conn *conn;
1603 struct hci_conn *hcon;
1604 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001605 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001606 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001608 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301609 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001611 hdev = hci_get_route(dst, src);
1612 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 return -EHOSTUNREACH;
1614
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001615 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001617 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001618
1619 /* PSM must be odd and lsb of upper byte must be 0 */
1620 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001621 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001622 err = -EINVAL;
1623 goto done;
1624 }
1625
1626 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1627 err = -EINVAL;
1628 goto done;
1629 }
1630
1631 switch (chan->mode) {
1632 case L2CAP_MODE_BASIC:
1633 break;
1634 case L2CAP_MODE_ERTM:
1635 case L2CAP_MODE_STREAMING:
1636 if (!disable_ertm)
1637 break;
1638 /* fall through */
1639 default:
1640 err = -ENOTSUPP;
1641 goto done;
1642 }
1643
Gustavo Padovan0797e012012-05-27 22:27:54 -03001644 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001645 case BT_CONNECT:
1646 case BT_CONNECT2:
1647 case BT_CONFIG:
1648 /* Already connecting */
1649 err = 0;
1650 goto done;
1651
1652 case BT_CONNECTED:
1653 /* Already connected */
1654 err = -EISCONN;
1655 goto done;
1656
1657 case BT_OPEN:
1658 case BT_BOUND:
1659 /* Can connect */
1660 break;
1661
1662 default:
1663 err = -EBADFD;
1664 goto done;
1665 }
1666
1667 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001668 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001669 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001670 release_sock(sk);
1671
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001672 chan->psm = psm;
1673 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001675 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001676
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001677 if (chan->dcid == L2CAP_CID_LE_DATA)
Andre Guedes8e9f9892012-04-24 21:02:55 -03001678 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001679 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001680 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001681 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001682 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001683
Ville Tervo30e76272011-02-22 16:10:53 -03001684 if (IS_ERR(hcon)) {
1685 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001687 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688
1689 conn = l2cap_conn_add(hcon, 0);
1690 if (!conn) {
1691 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001692 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 goto done;
1694 }
1695
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001696 if (hcon->type == LE_LINK) {
1697 err = 0;
1698
1699 if (!list_empty(&conn->chan_l)) {
1700 err = -EBUSY;
1701 hci_conn_put(hcon);
1702 }
1703
1704 if (err)
1705 goto done;
1706 }
1707
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 /* Update source addr of the socket */
1709 bacpy(src, conn->src);
1710
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001711 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001712 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001713 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001714
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001715 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001716 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717
1718 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001719 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001720 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001721 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001722 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001723 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001724 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 }
1726
Ville Tervo30e76272011-02-22 16:10:53 -03001727 err = 0;
1728
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001730 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001731 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 hci_dev_put(hdev);
1733 return err;
1734}
1735
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001736int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001737{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001738 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001739 DECLARE_WAITQUEUE(wait, current);
1740 int err = 0;
1741 int timeo = HZ/5;
1742
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001743 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001744 set_current_state(TASK_INTERRUPTIBLE);
1745 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001746 if (!timeo)
1747 timeo = HZ/5;
1748
1749 if (signal_pending(current)) {
1750 err = sock_intr_errno(timeo);
1751 break;
1752 }
1753
1754 release_sock(sk);
1755 timeo = schedule_timeout(timeo);
1756 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001757 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001758
1759 err = sock_error(sk);
1760 if (err)
1761 break;
1762 }
1763 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001764 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001765 return err;
1766}
1767
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001768static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001769{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001770 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001771 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001772
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001773 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001774
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001775 l2cap_chan_lock(chan);
1776
Mat Martineau80909e02012-05-17 20:53:50 -07001777 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001778 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001779 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001780 return;
1781 }
1782
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001783 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001784
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001785 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001786 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001787}
1788
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001789static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001790{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001791 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001792 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001793
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001794 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001795
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001796 l2cap_chan_lock(chan);
1797
Mat Martineau80909e02012-05-17 20:53:50 -07001798 if (!chan->conn) {
1799 l2cap_chan_unlock(chan);
1800 l2cap_chan_put(chan);
1801 return;
1802 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001803
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001804 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001805 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001806 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001807}
1808
Gustavo Padovand6603662012-05-21 13:58:22 -03001809static void l2cap_streaming_send(struct l2cap_chan *chan,
1810 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001811{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001812 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001813 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001814
Mat Martineau37339372012-05-17 20:53:33 -07001815 BT_DBG("chan %p, skbs %p", chan, skbs);
1816
Mat Martineaub99e13a2012-10-23 15:24:19 -07001817 if (__chan_is_moving(chan))
1818 return;
1819
Mat Martineau37339372012-05-17 20:53:33 -07001820 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1821
1822 while (!skb_queue_empty(&chan->tx_q)) {
1823
1824 skb = skb_dequeue(&chan->tx_q);
1825
1826 bt_cb(skb)->control.retries = 1;
1827 control = &bt_cb(skb)->control;
1828
1829 control->reqseq = 0;
1830 control->txseq = chan->next_tx_seq;
1831
1832 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001833
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001834 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001835 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1836 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001837 }
1838
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001839 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001840
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001841 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001842
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001843 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001844 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001845 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001846}
1847
Szymon Janc67c9e842011-07-28 16:24:33 +02001848static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001849{
1850 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001851 struct l2cap_ctrl *control;
1852 int sent = 0;
1853
1854 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001855
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001856 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001857 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001858
Mat Martineau94122bb2012-05-02 09:42:02 -07001859 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1860 return 0;
1861
Mat Martineaub99e13a2012-10-23 15:24:19 -07001862 if (__chan_is_moving(chan))
1863 return 0;
1864
Mat Martineau18a48e72012-05-17 20:53:34 -07001865 while (chan->tx_send_head &&
1866 chan->unacked_frames < chan->remote_tx_win &&
1867 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001868
Mat Martineau18a48e72012-05-17 20:53:34 -07001869 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001870
Mat Martineau18a48e72012-05-17 20:53:34 -07001871 bt_cb(skb)->control.retries = 1;
1872 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001873
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001874 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001875 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001876
Mat Martineau18a48e72012-05-17 20:53:34 -07001877 control->reqseq = chan->buffer_seq;
1878 chan->last_acked_seq = chan->buffer_seq;
1879 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001880
Mat Martineau18a48e72012-05-17 20:53:34 -07001881 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001882
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001883 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001884 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1885 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001886 }
1887
Mat Martineau18a48e72012-05-17 20:53:34 -07001888 /* Clone after data has been modified. Data is assumed to be
1889 read-only (for locking purposes) on cloned sk_buffs.
1890 */
1891 tx_skb = skb_clone(skb, GFP_KERNEL);
1892
1893 if (!tx_skb)
1894 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001895
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001896 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001897
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001898 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001899 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001900 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001901 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001902
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001903 if (skb_queue_is_last(&chan->tx_q, skb))
1904 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001905 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001906 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001907
1908 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001909 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001910 }
1911
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001912 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
1913 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07001914
1915 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001916}
1917
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001918static void l2cap_ertm_resend(struct l2cap_chan *chan)
1919{
1920 struct l2cap_ctrl control;
1921 struct sk_buff *skb;
1922 struct sk_buff *tx_skb;
1923 u16 seq;
1924
1925 BT_DBG("chan %p", chan);
1926
1927 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1928 return;
1929
Mat Martineaub99e13a2012-10-23 15:24:19 -07001930 if (__chan_is_moving(chan))
1931 return;
1932
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001933 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1934 seq = l2cap_seq_list_pop(&chan->retrans_list);
1935
1936 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1937 if (!skb) {
1938 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01001939 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001940 continue;
1941 }
1942
1943 bt_cb(skb)->control.retries++;
1944 control = bt_cb(skb)->control;
1945
1946 if (chan->max_tx != 0 &&
1947 bt_cb(skb)->control.retries > chan->max_tx) {
1948 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
1949 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
1950 l2cap_seq_list_clear(&chan->retrans_list);
1951 break;
1952 }
1953
1954 control.reqseq = chan->buffer_seq;
1955 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
1956 control.final = 1;
1957 else
1958 control.final = 0;
1959
1960 if (skb_cloned(skb)) {
1961 /* Cloned sk_buffs are read-only, so we need a
1962 * writeable copy
1963 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001964 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001965 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001966 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001967 }
1968
1969 if (!tx_skb) {
1970 l2cap_seq_list_clear(&chan->retrans_list);
1971 break;
1972 }
1973
1974 /* Update skb contents */
1975 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1976 put_unaligned_le32(__pack_extended_control(&control),
1977 tx_skb->data + L2CAP_HDR_SIZE);
1978 } else {
1979 put_unaligned_le16(__pack_enhanced_control(&control),
1980 tx_skb->data + L2CAP_HDR_SIZE);
1981 }
1982
1983 if (chan->fcs == L2CAP_FCS_CRC16) {
1984 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
1985 put_unaligned_le16(fcs, skb_put(tx_skb,
1986 L2CAP_FCS_SIZE));
1987 }
1988
1989 l2cap_do_send(chan, tx_skb);
1990
1991 BT_DBG("Resent txseq %d", control.txseq);
1992
1993 chan->last_acked_seq = chan->buffer_seq;
1994 }
1995}
1996
Mat Martineauf80842a2012-05-17 20:53:46 -07001997static void l2cap_retransmit(struct l2cap_chan *chan,
1998 struct l2cap_ctrl *control)
1999{
2000 BT_DBG("chan %p, control %p", chan, control);
2001
2002 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2003 l2cap_ertm_resend(chan);
2004}
2005
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002006static void l2cap_retransmit_all(struct l2cap_chan *chan,
2007 struct l2cap_ctrl *control)
2008{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002009 struct sk_buff *skb;
2010
2011 BT_DBG("chan %p, control %p", chan, control);
2012
2013 if (control->poll)
2014 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2015
2016 l2cap_seq_list_clear(&chan->retrans_list);
2017
2018 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2019 return;
2020
2021 if (chan->unacked_frames) {
2022 skb_queue_walk(&chan->tx_q, skb) {
2023 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002024 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002025 break;
2026 }
2027
2028 skb_queue_walk_from(&chan->tx_q, skb) {
2029 if (skb == chan->tx_send_head)
2030 break;
2031
2032 l2cap_seq_list_append(&chan->retrans_list,
2033 bt_cb(skb)->control.txseq);
2034 }
2035
2036 l2cap_ertm_resend(chan);
2037 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002038}
2039
Szymon Jancb17e73b2012-01-11 10:59:47 +01002040static void l2cap_send_ack(struct l2cap_chan *chan)
2041{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002042 struct l2cap_ctrl control;
2043 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2044 chan->last_acked_seq);
2045 int threshold;
2046
2047 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2048 chan, chan->last_acked_seq, chan->buffer_seq);
2049
2050 memset(&control, 0, sizeof(control));
2051 control.sframe = 1;
2052
2053 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2054 chan->rx_state == L2CAP_RX_STATE_RECV) {
2055 __clear_ack_timer(chan);
2056 control.super = L2CAP_SUPER_RNR;
2057 control.reqseq = chan->buffer_seq;
2058 l2cap_send_sframe(chan, &control);
2059 } else {
2060 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2061 l2cap_ertm_send(chan);
2062 /* If any i-frames were sent, they included an ack */
2063 if (chan->buffer_seq == chan->last_acked_seq)
2064 frames_to_ack = 0;
2065 }
2066
Mat Martineauc20f8e32012-07-10 05:47:07 -07002067 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002068 * Calculate without mul or div
2069 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002070 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002071 threshold += threshold << 1;
2072 threshold >>= 2;
2073
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002074 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002075 threshold);
2076
2077 if (frames_to_ack >= threshold) {
2078 __clear_ack_timer(chan);
2079 control.super = L2CAP_SUPER_RR;
2080 control.reqseq = chan->buffer_seq;
2081 l2cap_send_sframe(chan, &control);
2082 frames_to_ack = 0;
2083 }
2084
2085 if (frames_to_ack)
2086 __set_ack_timer(chan);
2087 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002088}
2089
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002090static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2091 struct msghdr *msg, int len,
2092 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002093{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002094 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002095 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002096 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002098 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002099 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002100
2101 sent += count;
2102 len -= count;
2103
2104 /* Continuation fragments (no L2CAP header) */
2105 frag = &skb_shinfo(skb)->frag_list;
2106 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002107 struct sk_buff *tmp;
2108
Linus Torvalds1da177e2005-04-16 15:20:36 -07002109 count = min_t(unsigned int, conn->mtu, len);
2110
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002111 tmp = chan->ops->alloc_skb(chan, count,
2112 msg->msg_flags & MSG_DONTWAIT);
2113 if (IS_ERR(tmp))
2114 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002115
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002116 *frag = tmp;
2117
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002118 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2119 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002120
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002121 (*frag)->priority = skb->priority;
2122
Linus Torvalds1da177e2005-04-16 15:20:36 -07002123 sent += count;
2124 len -= count;
2125
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002126 skb->len += (*frag)->len;
2127 skb->data_len += (*frag)->len;
2128
Linus Torvalds1da177e2005-04-16 15:20:36 -07002129 frag = &(*frag)->next;
2130 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002131
2132 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002133}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002134
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002135static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002136 struct msghdr *msg, size_t len,
2137 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002138{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002139 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002140 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002141 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002142 struct l2cap_hdr *lh;
2143
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002144 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002145
2146 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002147
2148 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002149 msg->msg_flags & MSG_DONTWAIT);
2150 if (IS_ERR(skb))
2151 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002152
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002153 skb->priority = priority;
2154
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002155 /* Create L2CAP header */
2156 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002157 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002158 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
2159 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002160
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002161 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002162 if (unlikely(err < 0)) {
2163 kfree_skb(skb);
2164 return ERR_PTR(err);
2165 }
2166 return skb;
2167}
2168
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002169static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002170 struct msghdr *msg, size_t len,
2171 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002172{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002173 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002174 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002175 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002176 struct l2cap_hdr *lh;
2177
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002178 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002179
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002180 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002181
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002182 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002183 msg->msg_flags & MSG_DONTWAIT);
2184 if (IS_ERR(skb))
2185 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002186
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002187 skb->priority = priority;
2188
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002189 /* Create L2CAP header */
2190 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002191 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002192 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002193
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002194 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002195 if (unlikely(err < 0)) {
2196 kfree_skb(skb);
2197 return ERR_PTR(err);
2198 }
2199 return skb;
2200}
2201
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002202static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002203 struct msghdr *msg, size_t len,
2204 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002205{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002206 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002207 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002208 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002209 struct l2cap_hdr *lh;
2210
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002211 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002212
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002213 if (!conn)
2214 return ERR_PTR(-ENOTCONN);
2215
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002216 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002217
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002218 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002219 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002220
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002221 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002222 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002223
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002224 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002225
2226 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002227 msg->msg_flags & MSG_DONTWAIT);
2228 if (IS_ERR(skb))
2229 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002230
2231 /* Create L2CAP header */
2232 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002233 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002234 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002235
Mat Martineau18a48e72012-05-17 20:53:34 -07002236 /* Control header is populated later */
2237 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2238 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2239 else
2240 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002241
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002242 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002243 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002244
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002245 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002246 if (unlikely(err < 0)) {
2247 kfree_skb(skb);
2248 return ERR_PTR(err);
2249 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002250
Mat Martineau18a48e72012-05-17 20:53:34 -07002251 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002252 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002253 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002254}
2255
Mat Martineau94122bb2012-05-02 09:42:02 -07002256static int l2cap_segment_sdu(struct l2cap_chan *chan,
2257 struct sk_buff_head *seg_queue,
2258 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002259{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002260 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002261 u16 sdu_len;
2262 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002263 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002264
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002265 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002266
Mat Martineau94122bb2012-05-02 09:42:02 -07002267 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2268 * so fragmented skbs are not used. The HCI layer's handling
2269 * of fragmented skbs is not compatible with ERTM's queueing.
2270 */
2271
2272 /* PDU size is derived from the HCI MTU */
2273 pdu_len = chan->conn->mtu;
2274
Mat Martineaua5495742012-10-23 15:24:21 -07002275 /* Constrain PDU size for BR/EDR connections */
2276 if (!chan->hs_hcon)
2277 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002278
2279 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002280 if (chan->fcs)
2281 pdu_len -= L2CAP_FCS_SIZE;
2282
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002283 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002284
2285 /* Remote device may have requested smaller PDUs */
2286 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2287
2288 if (len <= pdu_len) {
2289 sar = L2CAP_SAR_UNSEGMENTED;
2290 sdu_len = 0;
2291 pdu_len = len;
2292 } else {
2293 sar = L2CAP_SAR_START;
2294 sdu_len = len;
2295 pdu_len -= L2CAP_SDULEN_SIZE;
2296 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002297
2298 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002299 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002300
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002301 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002302 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002303 return PTR_ERR(skb);
2304 }
2305
Mat Martineau94122bb2012-05-02 09:42:02 -07002306 bt_cb(skb)->control.sar = sar;
2307 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002308
Mat Martineau94122bb2012-05-02 09:42:02 -07002309 len -= pdu_len;
2310 if (sdu_len) {
2311 sdu_len = 0;
2312 pdu_len += L2CAP_SDULEN_SIZE;
2313 }
2314
2315 if (len <= pdu_len) {
2316 sar = L2CAP_SAR_END;
2317 pdu_len = len;
2318 } else {
2319 sar = L2CAP_SAR_CONTINUE;
2320 }
2321 }
2322
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002323 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002324}
2325
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002326int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002327 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002328{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002329 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002330 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002331 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002332
2333 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002334 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002335 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002336 if (IS_ERR(skb))
2337 return PTR_ERR(skb);
2338
2339 l2cap_do_send(chan, skb);
2340 return len;
2341 }
2342
2343 switch (chan->mode) {
2344 case L2CAP_MODE_BASIC:
2345 /* Check outgoing MTU */
2346 if (len > chan->omtu)
2347 return -EMSGSIZE;
2348
2349 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002350 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002351 if (IS_ERR(skb))
2352 return PTR_ERR(skb);
2353
2354 l2cap_do_send(chan, skb);
2355 err = len;
2356 break;
2357
2358 case L2CAP_MODE_ERTM:
2359 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002360 /* Check outgoing MTU */
2361 if (len > chan->omtu) {
2362 err = -EMSGSIZE;
2363 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002364 }
2365
Mat Martineau94122bb2012-05-02 09:42:02 -07002366 __skb_queue_head_init(&seg_queue);
2367
2368 /* Do segmentation before calling in to the state machine,
2369 * since it's possible to block while waiting for memory
2370 * allocation.
2371 */
2372 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2373
2374 /* The channel could have been closed while segmenting,
2375 * check that it is still connected.
2376 */
2377 if (chan->state != BT_CONNECTED) {
2378 __skb_queue_purge(&seg_queue);
2379 err = -ENOTCONN;
2380 }
2381
2382 if (err)
2383 break;
2384
Mat Martineau37339372012-05-17 20:53:33 -07002385 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002386 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002387 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002388 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002389
Gustavo Padovand6603662012-05-21 13:58:22 -03002390 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002391
Mat Martineau94122bb2012-05-02 09:42:02 -07002392 /* If the skbs were not queued for sending, they'll still be in
2393 * seg_queue and need to be purged.
2394 */
2395 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002396 break;
2397
2398 default:
2399 BT_DBG("bad state %1.1x", chan->mode);
2400 err = -EBADFD;
2401 }
2402
2403 return err;
2404}
2405
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002406static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2407{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002408 struct l2cap_ctrl control;
2409 u16 seq;
2410
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002411 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002412
2413 memset(&control, 0, sizeof(control));
2414 control.sframe = 1;
2415 control.super = L2CAP_SUPER_SREJ;
2416
2417 for (seq = chan->expected_tx_seq; seq != txseq;
2418 seq = __next_seq(chan, seq)) {
2419 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2420 control.reqseq = seq;
2421 l2cap_send_sframe(chan, &control);
2422 l2cap_seq_list_append(&chan->srej_list, seq);
2423 }
2424 }
2425
2426 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002427}
2428
2429static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2430{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002431 struct l2cap_ctrl control;
2432
2433 BT_DBG("chan %p", chan);
2434
2435 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2436 return;
2437
2438 memset(&control, 0, sizeof(control));
2439 control.sframe = 1;
2440 control.super = L2CAP_SUPER_SREJ;
2441 control.reqseq = chan->srej_list.tail;
2442 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002443}
2444
2445static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2446{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002447 struct l2cap_ctrl control;
2448 u16 initial_head;
2449 u16 seq;
2450
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002451 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002452
2453 memset(&control, 0, sizeof(control));
2454 control.sframe = 1;
2455 control.super = L2CAP_SUPER_SREJ;
2456
2457 /* Capture initial list head to allow only one pass through the list. */
2458 initial_head = chan->srej_list.head;
2459
2460 do {
2461 seq = l2cap_seq_list_pop(&chan->srej_list);
2462 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2463 break;
2464
2465 control.reqseq = seq;
2466 l2cap_send_sframe(chan, &control);
2467 l2cap_seq_list_append(&chan->srej_list, seq);
2468 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002469}
2470
Mat Martineau608bcc62012-05-17 20:53:32 -07002471static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2472{
2473 struct sk_buff *acked_skb;
2474 u16 ackseq;
2475
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002476 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002477
2478 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2479 return;
2480
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002481 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002482 chan->expected_ack_seq, chan->unacked_frames);
2483
2484 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2485 ackseq = __next_seq(chan, ackseq)) {
2486
2487 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2488 if (acked_skb) {
2489 skb_unlink(acked_skb, &chan->tx_q);
2490 kfree_skb(acked_skb);
2491 chan->unacked_frames--;
2492 }
2493 }
2494
2495 chan->expected_ack_seq = reqseq;
2496
2497 if (chan->unacked_frames == 0)
2498 __clear_retrans_timer(chan);
2499
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002500 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002501}
2502
2503static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2504{
2505 BT_DBG("chan %p", chan);
2506
2507 chan->expected_tx_seq = chan->buffer_seq;
2508 l2cap_seq_list_clear(&chan->srej_list);
2509 skb_queue_purge(&chan->srej_q);
2510 chan->rx_state = L2CAP_RX_STATE_RECV;
2511}
2512
Gustavo Padovand6603662012-05-21 13:58:22 -03002513static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2514 struct l2cap_ctrl *control,
2515 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002516{
Mat Martineau608bcc62012-05-17 20:53:32 -07002517 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2518 event);
2519
2520 switch (event) {
2521 case L2CAP_EV_DATA_REQUEST:
2522 if (chan->tx_send_head == NULL)
2523 chan->tx_send_head = skb_peek(skbs);
2524
2525 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2526 l2cap_ertm_send(chan);
2527 break;
2528 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2529 BT_DBG("Enter LOCAL_BUSY");
2530 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2531
2532 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2533 /* The SREJ_SENT state must be aborted if we are to
2534 * enter the LOCAL_BUSY state.
2535 */
2536 l2cap_abort_rx_srej_sent(chan);
2537 }
2538
2539 l2cap_send_ack(chan);
2540
2541 break;
2542 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2543 BT_DBG("Exit LOCAL_BUSY");
2544 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2545
2546 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2547 struct l2cap_ctrl local_control;
2548
2549 memset(&local_control, 0, sizeof(local_control));
2550 local_control.sframe = 1;
2551 local_control.super = L2CAP_SUPER_RR;
2552 local_control.poll = 1;
2553 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002554 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002555
2556 chan->retry_count = 1;
2557 __set_monitor_timer(chan);
2558 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2559 }
2560 break;
2561 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2562 l2cap_process_reqseq(chan, control->reqseq);
2563 break;
2564 case L2CAP_EV_EXPLICIT_POLL:
2565 l2cap_send_rr_or_rnr(chan, 1);
2566 chan->retry_count = 1;
2567 __set_monitor_timer(chan);
2568 __clear_ack_timer(chan);
2569 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2570 break;
2571 case L2CAP_EV_RETRANS_TO:
2572 l2cap_send_rr_or_rnr(chan, 1);
2573 chan->retry_count = 1;
2574 __set_monitor_timer(chan);
2575 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2576 break;
2577 case L2CAP_EV_RECV_FBIT:
2578 /* Nothing to process */
2579 break;
2580 default:
2581 break;
2582 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002583}
2584
Gustavo Padovand6603662012-05-21 13:58:22 -03002585static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2586 struct l2cap_ctrl *control,
2587 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002588{
Mat Martineau608bcc62012-05-17 20:53:32 -07002589 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2590 event);
2591
2592 switch (event) {
2593 case L2CAP_EV_DATA_REQUEST:
2594 if (chan->tx_send_head == NULL)
2595 chan->tx_send_head = skb_peek(skbs);
2596 /* Queue data, but don't send. */
2597 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2598 break;
2599 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2600 BT_DBG("Enter LOCAL_BUSY");
2601 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2602
2603 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2604 /* The SREJ_SENT state must be aborted if we are to
2605 * enter the LOCAL_BUSY state.
2606 */
2607 l2cap_abort_rx_srej_sent(chan);
2608 }
2609
2610 l2cap_send_ack(chan);
2611
2612 break;
2613 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2614 BT_DBG("Exit LOCAL_BUSY");
2615 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2616
2617 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2618 struct l2cap_ctrl local_control;
2619 memset(&local_control, 0, sizeof(local_control));
2620 local_control.sframe = 1;
2621 local_control.super = L2CAP_SUPER_RR;
2622 local_control.poll = 1;
2623 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002624 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002625
2626 chan->retry_count = 1;
2627 __set_monitor_timer(chan);
2628 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2629 }
2630 break;
2631 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2632 l2cap_process_reqseq(chan, control->reqseq);
2633
2634 /* Fall through */
2635
2636 case L2CAP_EV_RECV_FBIT:
2637 if (control && control->final) {
2638 __clear_monitor_timer(chan);
2639 if (chan->unacked_frames > 0)
2640 __set_retrans_timer(chan);
2641 chan->retry_count = 0;
2642 chan->tx_state = L2CAP_TX_STATE_XMIT;
2643 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2644 }
2645 break;
2646 case L2CAP_EV_EXPLICIT_POLL:
2647 /* Ignore */
2648 break;
2649 case L2CAP_EV_MONITOR_TO:
2650 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2651 l2cap_send_rr_or_rnr(chan, 1);
2652 __set_monitor_timer(chan);
2653 chan->retry_count++;
2654 } else {
2655 l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
2656 }
2657 break;
2658 default:
2659 break;
2660 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002661}
2662
Gustavo Padovand6603662012-05-21 13:58:22 -03002663static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2664 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002665{
Mat Martineau608bcc62012-05-17 20:53:32 -07002666 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2667 chan, control, skbs, event, chan->tx_state);
2668
2669 switch (chan->tx_state) {
2670 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002671 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002672 break;
2673 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002674 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002675 break;
2676 default:
2677 /* Ignore event */
2678 break;
2679 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002680}
2681
Mat Martineau4b51dae92012-05-17 20:53:37 -07002682static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2683 struct l2cap_ctrl *control)
2684{
2685 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002686 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002687}
2688
Mat Martineauf80842a2012-05-17 20:53:46 -07002689static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2690 struct l2cap_ctrl *control)
2691{
2692 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002693 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002694}
2695
Linus Torvalds1da177e2005-04-16 15:20:36 -07002696/* Copy frame to all raw sockets on that connection */
2697static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2698{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002699 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002700 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002701
2702 BT_DBG("conn %p", conn);
2703
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002704 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002705
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002706 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002707 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002708 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002709 continue;
2710
2711 /* Don't send frame to the socket it came from */
2712 if (skb->sk == sk)
2713 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002714 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002715 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716 continue;
2717
Gustavo Padovan80b98022012-05-27 22:27:51 -03002718 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719 kfree_skb(nskb);
2720 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002721
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002722 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002723}
2724
2725/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002726static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2727 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728{
2729 struct sk_buff *skb, **frag;
2730 struct l2cap_cmd_hdr *cmd;
2731 struct l2cap_hdr *lh;
2732 int len, count;
2733
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002734 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2735 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002736
2737 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2738 count = min_t(unsigned int, conn->mtu, len);
2739
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002740 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002741 if (!skb)
2742 return NULL;
2743
2744 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002745 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002746
2747 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002748 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002749 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002750 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751
2752 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2753 cmd->code = code;
2754 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002755 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002756
2757 if (dlen) {
2758 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2759 memcpy(skb_put(skb, count), data, count);
2760 data += count;
2761 }
2762
2763 len -= skb->len;
2764
2765 /* Continuation fragments (no L2CAP header) */
2766 frag = &skb_shinfo(skb)->frag_list;
2767 while (len) {
2768 count = min_t(unsigned int, conn->mtu, len);
2769
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002770 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002771 if (!*frag)
2772 goto fail;
2773
2774 memcpy(skb_put(*frag, count), data, count);
2775
2776 len -= count;
2777 data += count;
2778
2779 frag = &(*frag)->next;
2780 }
2781
2782 return skb;
2783
2784fail:
2785 kfree_skb(skb);
2786 return NULL;
2787}
2788
Gustavo Padovan2d792812012-10-06 10:07:01 +01002789static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2790 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002791{
2792 struct l2cap_conf_opt *opt = *ptr;
2793 int len;
2794
2795 len = L2CAP_CONF_OPT_SIZE + opt->len;
2796 *ptr += len;
2797
2798 *type = opt->type;
2799 *olen = opt->len;
2800
2801 switch (opt->len) {
2802 case 1:
2803 *val = *((u8 *) opt->val);
2804 break;
2805
2806 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002807 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002808 break;
2809
2810 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002811 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002812 break;
2813
2814 default:
2815 *val = (unsigned long) opt->val;
2816 break;
2817 }
2818
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002819 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002820 return len;
2821}
2822
Linus Torvalds1da177e2005-04-16 15:20:36 -07002823static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2824{
2825 struct l2cap_conf_opt *opt = *ptr;
2826
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002827 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002828
2829 opt->type = type;
2830 opt->len = len;
2831
2832 switch (len) {
2833 case 1:
2834 *((u8 *) opt->val) = val;
2835 break;
2836
2837 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002838 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002839 break;
2840
2841 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002842 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002843 break;
2844
2845 default:
2846 memcpy(opt->val, (void *) val, len);
2847 break;
2848 }
2849
2850 *ptr += L2CAP_CONF_OPT_SIZE + len;
2851}
2852
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002853static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2854{
2855 struct l2cap_conf_efs efs;
2856
Szymon Janc1ec918c2011-11-16 09:32:21 +01002857 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002858 case L2CAP_MODE_ERTM:
2859 efs.id = chan->local_id;
2860 efs.stype = chan->local_stype;
2861 efs.msdu = cpu_to_le16(chan->local_msdu);
2862 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002863 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002864 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002865 break;
2866
2867 case L2CAP_MODE_STREAMING:
2868 efs.id = 1;
2869 efs.stype = L2CAP_SERV_BESTEFFORT;
2870 efs.msdu = cpu_to_le16(chan->local_msdu);
2871 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2872 efs.acc_lat = 0;
2873 efs.flush_to = 0;
2874 break;
2875
2876 default:
2877 return;
2878 }
2879
2880 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002881 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002882}
2883
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002884static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002885{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002886 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07002887 ack_timer.work);
2888 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002889
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02002890 BT_DBG("chan %p", chan);
2891
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002892 l2cap_chan_lock(chan);
2893
Mat Martineau03625202012-05-17 20:53:51 -07002894 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2895 chan->last_acked_seq);
2896
2897 if (frames_to_ack)
2898 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002899
2900 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01002901 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002902}
2903
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03002904int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002905{
Mat Martineau3c588192012-04-11 10:48:42 -07002906 int err;
2907
Mat Martineau105bdf92012-04-27 16:50:48 -07002908 chan->next_tx_seq = 0;
2909 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002910 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002911 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002912 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002913 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07002914 chan->last_acked_seq = 0;
2915 chan->sdu = NULL;
2916 chan->sdu_last_frag = NULL;
2917 chan->sdu_len = 0;
2918
Mat Martineaud34c34f2012-05-14 14:49:27 -07002919 skb_queue_head_init(&chan->tx_q);
2920
Mat Martineau08333282012-10-23 15:24:06 -07002921 chan->local_amp_id = 0;
2922 chan->move_id = 0;
2923 chan->move_state = L2CAP_MOVE_STABLE;
2924 chan->move_role = L2CAP_MOVE_ROLE_NONE;
2925
Mat Martineau105bdf92012-04-27 16:50:48 -07002926 if (chan->mode != L2CAP_MODE_ERTM)
2927 return 0;
2928
2929 chan->rx_state = L2CAP_RX_STATE_RECV;
2930 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002931
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002932 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
2933 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
2934 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002935
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03002936 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002937
Mat Martineau3c588192012-04-11 10:48:42 -07002938 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
2939 if (err < 0)
2940 return err;
2941
Mat Martineau9dc9aff2012-05-17 16:20:14 -07002942 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
2943 if (err < 0)
2944 l2cap_seq_list_free(&chan->srej_list);
2945
2946 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002947}
2948
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002949static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2950{
2951 switch (mode) {
2952 case L2CAP_MODE_STREAMING:
2953 case L2CAP_MODE_ERTM:
2954 if (l2cap_mode_supported(mode, remote_feat_mask))
2955 return mode;
2956 /* fall through */
2957 default:
2958 return L2CAP_MODE_BASIC;
2959 }
2960}
2961
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002962static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
2963{
2964 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
2965}
2966
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002967static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
2968{
2969 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
2970}
2971
Mat Martineau36c86c82012-10-23 15:24:20 -07002972static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
2973 struct l2cap_conf_rfc *rfc)
2974{
2975 if (chan->local_amp_id && chan->hs_hcon) {
2976 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
2977
2978 /* Class 1 devices have must have ERTM timeouts
2979 * exceeding the Link Supervision Timeout. The
2980 * default Link Supervision Timeout for AMP
2981 * controllers is 10 seconds.
2982 *
2983 * Class 1 devices use 0xffffffff for their
2984 * best-effort flush timeout, so the clamping logic
2985 * will result in a timeout that meets the above
2986 * requirement. ERTM timeouts are 16-bit values, so
2987 * the maximum timeout is 65.535 seconds.
2988 */
2989
2990 /* Convert timeout to milliseconds and round */
2991 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
2992
2993 /* This is the recommended formula for class 2 devices
2994 * that start ERTM timers when packets are sent to the
2995 * controller.
2996 */
2997 ertm_to = 3 * ertm_to + 500;
2998
2999 if (ertm_to > 0xffff)
3000 ertm_to = 0xffff;
3001
3002 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3003 rfc->monitor_timeout = rfc->retrans_timeout;
3004 } else {
3005 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3006 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3007 }
3008}
3009
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003010static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3011{
3012 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003013 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003014 /* use extended control field */
3015 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003016 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3017 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003018 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003019 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003020 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3021 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003022 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003023}
3024
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003025static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003026{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003027 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003028 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003029 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003030 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003031
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003032 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003033
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003034 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003035 goto done;
3036
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003037 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003038 case L2CAP_MODE_STREAMING:
3039 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003040 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003041 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003042
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003043 if (__l2cap_efs_supported(chan))
3044 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3045
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003046 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003047 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003048 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003049 break;
3050 }
3051
3052done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003053 if (chan->imtu != L2CAP_DEFAULT_MTU)
3054 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003055
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003056 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003057 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003058 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003059 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003060 break;
3061
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003062 rfc.mode = L2CAP_MODE_BASIC;
3063 rfc.txwin_size = 0;
3064 rfc.max_transmit = 0;
3065 rfc.retrans_timeout = 0;
3066 rfc.monitor_timeout = 0;
3067 rfc.max_pdu_size = 0;
3068
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003069 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003070 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003071 break;
3072
3073 case L2CAP_MODE_ERTM:
3074 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003075 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003076
3077 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003078
3079 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003080 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3081 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003082 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003083
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003084 l2cap_txwin_setup(chan);
3085
3086 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003087 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003088
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003089 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003090 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003091
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003092 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3093 l2cap_add_opt_efs(&ptr, chan);
3094
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003095 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003096 break;
3097
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003098 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01003099 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003100 chan->fcs = L2CAP_FCS_NONE;
3101 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003102 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003103
3104 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3105 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003106 chan->tx_win);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003107 break;
3108
3109 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003110 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003111 rfc.mode = L2CAP_MODE_STREAMING;
3112 rfc.txwin_size = 0;
3113 rfc.max_transmit = 0;
3114 rfc.retrans_timeout = 0;
3115 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003116
3117 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003118 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3119 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003120 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003121
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003122 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003123 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003124
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003125 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3126 l2cap_add_opt_efs(&ptr, chan);
3127
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003128 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003129 break;
3130
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003131 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01003132 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003133 chan->fcs = L2CAP_FCS_NONE;
3134 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003135 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003136 break;
3137 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003138
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003139 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003140 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003141
3142 return ptr - data;
3143}
3144
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003145static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003146{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003147 struct l2cap_conf_rsp *rsp = data;
3148 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003149 void *req = chan->conf_req;
3150 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003151 int type, hint, olen;
3152 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003153 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003154 struct l2cap_conf_efs efs;
3155 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003156 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003157 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003158 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003159
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003160 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003161
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003162 while (len >= L2CAP_CONF_OPT_SIZE) {
3163 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003164
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003165 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003166 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003167
3168 switch (type) {
3169 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003170 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003171 break;
3172
3173 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003174 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003175 break;
3176
3177 case L2CAP_CONF_QOS:
3178 break;
3179
Marcel Holtmann6464f352007-10-20 13:39:51 +02003180 case L2CAP_CONF_RFC:
3181 if (olen == sizeof(rfc))
3182 memcpy(&rfc, (void *) val, olen);
3183 break;
3184
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003185 case L2CAP_CONF_FCS:
3186 if (val == L2CAP_FCS_NONE)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003187 set_bit(CONF_NO_FCS_RECV, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003188 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003189
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003190 case L2CAP_CONF_EFS:
3191 remote_efs = 1;
3192 if (olen == sizeof(efs))
3193 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003194 break;
3195
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003196 case L2CAP_CONF_EWS:
3197 if (!enable_hs)
3198 return -ECONNREFUSED;
3199
3200 set_bit(FLAG_EXT_CTRL, &chan->flags);
3201 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003202 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003203 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003204 break;
3205
3206 default:
3207 if (hint)
3208 break;
3209
3210 result = L2CAP_CONF_UNKNOWN;
3211 *((u8 *) ptr++) = type;
3212 break;
3213 }
3214 }
3215
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003216 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003217 goto done;
3218
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003219 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003220 case L2CAP_MODE_STREAMING:
3221 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003222 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003223 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003224 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003225 break;
3226 }
3227
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003228 if (remote_efs) {
3229 if (__l2cap_efs_supported(chan))
3230 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3231 else
3232 return -ECONNREFUSED;
3233 }
3234
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003235 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003236 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003237
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003238 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003239 }
3240
3241done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003242 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003243 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003244 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003245
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003246 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003247 return -ECONNREFUSED;
3248
Gustavo Padovan2d792812012-10-06 10:07:01 +01003249 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3250 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003251 }
3252
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003253 if (result == L2CAP_CONF_SUCCESS) {
3254 /* Configure output options and let the other side know
3255 * which ones we don't like. */
3256
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003257 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3258 result = L2CAP_CONF_UNACCEPT;
3259 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003260 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003261 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003262 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003263 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003264
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003265 if (remote_efs) {
3266 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003267 efs.stype != L2CAP_SERV_NOTRAFIC &&
3268 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003269
3270 result = L2CAP_CONF_UNACCEPT;
3271
3272 if (chan->num_conf_req >= 1)
3273 return -ECONNREFUSED;
3274
3275 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003276 sizeof(efs),
3277 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003278 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003279 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003280 result = L2CAP_CONF_PENDING;
3281 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003282 }
3283 }
3284
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003285 switch (rfc.mode) {
3286 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003287 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003288 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003289 break;
3290
3291 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003292 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3293 chan->remote_tx_win = rfc.txwin_size;
3294 else
3295 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3296
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003297 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003298
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003299 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003300 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3301 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003302 rfc.max_pdu_size = cpu_to_le16(size);
3303 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003304
Mat Martineau36c86c82012-10-23 15:24:20 -07003305 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003306
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003307 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003308
3309 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003310 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003311
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003312 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3313 chan->remote_id = efs.id;
3314 chan->remote_stype = efs.stype;
3315 chan->remote_msdu = le16_to_cpu(efs.msdu);
3316 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003317 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003318 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003319 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003320 chan->remote_sdu_itime =
3321 le32_to_cpu(efs.sdu_itime);
3322 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003323 sizeof(efs),
3324 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003325 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003326 break;
3327
3328 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003329 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003330 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3331 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003332 rfc.max_pdu_size = cpu_to_le16(size);
3333 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003334
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003335 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003336
Gustavo Padovan2d792812012-10-06 10:07:01 +01003337 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3338 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003339
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003340 break;
3341
3342 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003343 result = L2CAP_CONF_UNACCEPT;
3344
3345 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003346 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003347 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003348
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003349 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003350 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003351 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003352 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003353 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003354 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003355
3356 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003357}
3358
Gustavo Padovan2d792812012-10-06 10:07:01 +01003359static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3360 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003361{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003362 struct l2cap_conf_req *req = data;
3363 void *ptr = req->data;
3364 int type, olen;
3365 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003366 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003367 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003368
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003369 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003370
3371 while (len >= L2CAP_CONF_OPT_SIZE) {
3372 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3373
3374 switch (type) {
3375 case L2CAP_CONF_MTU:
3376 if (val < L2CAP_DEFAULT_MIN_MTU) {
3377 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003378 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003379 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003380 chan->imtu = val;
3381 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003382 break;
3383
3384 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003385 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003386 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003387 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003388 break;
3389
3390 case L2CAP_CONF_RFC:
3391 if (olen == sizeof(rfc))
3392 memcpy(&rfc, (void *)val, olen);
3393
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003394 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003395 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003396 return -ECONNREFUSED;
3397
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003398 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003399
3400 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003401 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003402 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003403
3404 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003405 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003406 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003407 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003408 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003409
3410 case L2CAP_CONF_EFS:
3411 if (olen == sizeof(efs))
3412 memcpy(&efs, (void *)val, olen);
3413
3414 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003415 efs.stype != L2CAP_SERV_NOTRAFIC &&
3416 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003417 return -ECONNREFUSED;
3418
Gustavo Padovan2d792812012-10-06 10:07:01 +01003419 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3420 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003421 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003422 }
3423 }
3424
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003425 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003426 return -ECONNREFUSED;
3427
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003428 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003429
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003430 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003431 switch (rfc.mode) {
3432 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003433 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3434 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3435 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003436 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3437 chan->ack_win = min_t(u16, chan->ack_win,
3438 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003439
3440 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3441 chan->local_msdu = le16_to_cpu(efs.msdu);
3442 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003443 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003444 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3445 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003446 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003447 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003448 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003449
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003450 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003451 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003452 }
3453 }
3454
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003455 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003456 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003457
3458 return ptr - data;
3459}
3460
Gustavo Padovan2d792812012-10-06 10:07:01 +01003461static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3462 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003463{
3464 struct l2cap_conf_rsp *rsp = data;
3465 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003466
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003467 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003468
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003469 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003470 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003471 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003472
3473 return ptr - data;
3474}
3475
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003476void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003477{
3478 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003479 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003480 u8 buf[128];
3481
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003482 rsp.scid = cpu_to_le16(chan->dcid);
3483 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003484 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3485 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo Padovan2d792812012-10-06 10:07:01 +01003486 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003487
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003488 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003489 return;
3490
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003491 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003492 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003493 chan->num_conf_req++;
3494}
3495
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003496static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003497{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003498 int type, olen;
3499 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003500 /* Use sane default values in case a misbehaving remote device
3501 * did not send an RFC or extended window size option.
3502 */
3503 u16 txwin_ext = chan->ack_win;
3504 struct l2cap_conf_rfc rfc = {
3505 .mode = chan->mode,
3506 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3507 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3508 .max_pdu_size = cpu_to_le16(chan->imtu),
3509 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3510 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003511
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003512 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003513
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003514 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003515 return;
3516
3517 while (len >= L2CAP_CONF_OPT_SIZE) {
3518 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3519
Mat Martineauc20f8e32012-07-10 05:47:07 -07003520 switch (type) {
3521 case L2CAP_CONF_RFC:
3522 if (olen == sizeof(rfc))
3523 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003524 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003525 case L2CAP_CONF_EWS:
3526 txwin_ext = val;
3527 break;
3528 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003529 }
3530
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003531 switch (rfc.mode) {
3532 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003533 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3534 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003535 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3536 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3537 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3538 else
3539 chan->ack_win = min_t(u16, chan->ack_win,
3540 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003541 break;
3542 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003543 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003544 }
3545}
3546
Gustavo Padovan2d792812012-10-06 10:07:01 +01003547static inline int l2cap_command_rej(struct l2cap_conn *conn,
3548 struct l2cap_cmd_hdr *cmd, u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003549{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003550 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003551
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003552 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003553 return 0;
3554
3555 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003556 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003557 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003558
3559 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003560 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003561
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003562 l2cap_conn_start(conn);
3563 }
3564
3565 return 0;
3566}
3567
Mat Martineau17009152012-10-23 15:24:07 -07003568static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3569 struct l2cap_cmd_hdr *cmd,
3570 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003571{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003572 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3573 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003574 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003575 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003576 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003577
3578 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003579 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003580
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003581 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003582
3583 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003584 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003585 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003586 result = L2CAP_CR_BAD_PSM;
3587 goto sendresp;
3588 }
3589
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003590 parent = pchan->sk;
3591
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003592 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003593 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003594
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003595 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003596 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003597 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003598 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003599 result = L2CAP_CR_SEC_BLOCK;
3600 goto response;
3601 }
3602
Linus Torvalds1da177e2005-04-16 15:20:36 -07003603 result = L2CAP_CR_NO_MEM;
3604
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003605 /* Check if we already have channel with that dcid */
3606 if (__l2cap_get_chan_by_dcid(conn, scid))
3607 goto response;
3608
Gustavo Padovan80b98022012-05-27 22:27:51 -03003609 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003610 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003611 goto response;
3612
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003613 sk = chan->sk;
3614
Linus Torvalds1da177e2005-04-16 15:20:36 -07003615 hci_conn_hold(conn->hcon);
3616
Linus Torvalds1da177e2005-04-16 15:20:36 -07003617 bacpy(&bt_sk(sk)->src, conn->src);
3618 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003619 chan->psm = psm;
3620 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003621 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003622
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003623 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003624
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003625 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003626
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003627 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003628
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003629 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003630
Marcel Holtmann984947d2009-02-06 23:35:19 +01003631 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003632 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003633 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003634 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003635 result = L2CAP_CR_PEND;
3636 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003637 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003638 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003639 /* Force pending result for AMP controllers.
3640 * The connection will succeed after the
3641 * physical link is up.
3642 */
3643 if (amp_id) {
3644 __l2cap_state_change(chan, BT_CONNECT2);
3645 result = L2CAP_CR_PEND;
3646 } else {
3647 __l2cap_state_change(chan, BT_CONFIG);
3648 result = L2CAP_CR_SUCCESS;
3649 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003650 status = L2CAP_CS_NO_INFO;
3651 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003652 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003653 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003654 result = L2CAP_CR_PEND;
3655 status = L2CAP_CS_AUTHEN_PEND;
3656 }
3657 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003658 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003659 result = L2CAP_CR_PEND;
3660 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003661 }
3662
Linus Torvalds1da177e2005-04-16 15:20:36 -07003663response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003664 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003665 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003666
3667sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003668 rsp.scid = cpu_to_le16(scid);
3669 rsp.dcid = cpu_to_le16(dcid);
3670 rsp.result = cpu_to_le16(result);
3671 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003672 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003673
3674 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3675 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003676 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003677
3678 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3679 conn->info_ident = l2cap_get_ident(conn);
3680
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003681 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003682
Gustavo Padovan2d792812012-10-06 10:07:01 +01003683 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3684 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003685 }
3686
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003687 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003688 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003689 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003690 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003691 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003692 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003693 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003694 }
Mat Martineau17009152012-10-23 15:24:07 -07003695
3696 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003697}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003698
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003699static int l2cap_connect_req(struct l2cap_conn *conn,
3700 struct l2cap_cmd_hdr *cmd, u8 *data)
3701{
Gustavo Padovan300229f2012-10-12 19:40:40 +08003702 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003703 return 0;
3704}
3705
Mat Martineau5909cf32012-10-23 15:24:08 -07003706static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003707 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003708{
3709 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3710 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003711 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003712 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003713 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003714
3715 scid = __le16_to_cpu(rsp->scid);
3716 dcid = __le16_to_cpu(rsp->dcid);
3717 result = __le16_to_cpu(rsp->result);
3718 status = __le16_to_cpu(rsp->status);
3719
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003720 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 +01003721 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003722
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003723 mutex_lock(&conn->chan_lock);
3724
Linus Torvalds1da177e2005-04-16 15:20:36 -07003725 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003726 chan = __l2cap_get_chan_by_scid(conn, scid);
3727 if (!chan) {
3728 err = -EFAULT;
3729 goto unlock;
3730 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003731 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003732 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3733 if (!chan) {
3734 err = -EFAULT;
3735 goto unlock;
3736 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003737 }
3738
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003739 err = 0;
3740
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003741 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003742
Linus Torvalds1da177e2005-04-16 15:20:36 -07003743 switch (result) {
3744 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003745 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003746 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003747 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003748 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003749
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003750 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003751 break;
3752
Linus Torvalds1da177e2005-04-16 15:20:36 -07003753 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003754 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003755 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003756 break;
3757
3758 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003759 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003760 break;
3761
3762 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003763 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003764 break;
3765 }
3766
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003767 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003768
3769unlock:
3770 mutex_unlock(&conn->chan_lock);
3771
3772 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003773}
3774
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003775static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003776{
3777 /* FCS is enabled only in ERTM or streaming mode, if one or both
3778 * sides request it.
3779 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003780 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003781 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003782 else if (!test_bit(CONF_NO_FCS_RECV, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003783 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003784}
3785
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003786static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3787 u8 ident, u16 flags)
3788{
3789 struct l2cap_conn *conn = chan->conn;
3790
3791 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3792 flags);
3793
3794 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3795 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3796
3797 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3798 l2cap_build_conf_rsp(chan, data,
3799 L2CAP_CONF_SUCCESS, flags), data);
3800}
3801
Gustavo Padovan2d792812012-10-06 10:07:01 +01003802static inline int l2cap_config_req(struct l2cap_conn *conn,
3803 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3804 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003805{
3806 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3807 u16 dcid, flags;
3808 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003809 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003810 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003811
3812 dcid = __le16_to_cpu(req->dcid);
3813 flags = __le16_to_cpu(req->flags);
3814
3815 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3816
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003817 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003818 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003819 return -ENOENT;
3820
David S. Miller033b1142011-07-21 13:38:42 -07003821 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003822 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003823
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003824 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003825 rej.scid = cpu_to_le16(chan->scid);
3826 rej.dcid = cpu_to_le16(chan->dcid);
3827
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003828 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003829 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003830 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003831 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003832
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003833 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003834 len = cmd_len - sizeof(*req);
Dan Rosenberg7ac28812011-06-24 08:38:05 -04003835 if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003836 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003837 l2cap_build_conf_rsp(chan, rsp,
3838 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003839 goto unlock;
3840 }
3841
3842 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003843 memcpy(chan->conf_req + chan->conf_len, req->data, len);
3844 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003845
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003846 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003847 /* Incomplete config. Send empty response. */
3848 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003849 l2cap_build_conf_rsp(chan, rsp,
3850 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003851 goto unlock;
3852 }
3853
3854 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003855 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003856 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003857 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003858 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003859 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003860
Mat Martineau1500109b2012-10-23 15:24:15 -07003861 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003862 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003863 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003864
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003865 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003866 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003867
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003868 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02003869 goto unlock;
3870
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003871 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003872 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003873
Mat Martineau105bdf92012-04-27 16:50:48 -07003874 if (chan->mode == L2CAP_MODE_ERTM ||
3875 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003876 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003877
Mat Martineau3c588192012-04-11 10:48:42 -07003878 if (err < 0)
3879 l2cap_send_disconn_req(chan->conn, chan, -err);
3880 else
3881 l2cap_chan_ready(chan);
3882
Marcel Holtmann876d9482007-10-20 13:35:42 +02003883 goto unlock;
3884 }
3885
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003886 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003887 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003888 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003889 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003890 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003891 }
3892
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003893 /* Got Conf Rsp PENDING from remote side and asume we sent
3894 Conf Rsp PENDING in the code above */
3895 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003896 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003897
3898 /* check compatibility */
3899
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03003900 /* Send rsp for BR/EDR channel */
3901 if (!chan->ctrl_id)
3902 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
3903 else
3904 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003905 }
3906
Linus Torvalds1da177e2005-04-16 15:20:36 -07003907unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003908 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003909 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003910}
3911
Gustavo Padovan2d792812012-10-06 10:07:01 +01003912static inline int l2cap_config_rsp(struct l2cap_conn *conn,
3913 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003914{
3915 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3916 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003917 struct l2cap_chan *chan;
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003918 int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07003919 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003920
3921 scid = __le16_to_cpu(rsp->scid);
3922 flags = __le16_to_cpu(rsp->flags);
3923 result = __le16_to_cpu(rsp->result);
3924
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003925 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
3926 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003927
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003928 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003929 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003930 return 0;
3931
3932 switch (result) {
3933 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003934 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003935 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003936 break;
3937
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003938 case L2CAP_CONF_PENDING:
3939 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
3940
3941 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3942 char buf[64];
3943
3944 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003945 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003946 if (len < 0) {
3947 l2cap_send_disconn_req(conn, chan, ECONNRESET);
3948 goto done;
3949 }
3950
3951 /* check compatibility */
3952
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03003953 if (!chan->ctrl_id)
3954 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
3955 0);
3956 else
3957 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003958 }
3959 goto done;
3960
Linus Torvalds1da177e2005-04-16 15:20:36 -07003961 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003962 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003963 char req[64];
3964
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003965 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003966 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003967 goto done;
3968 }
3969
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003970 /* throw out any old stored conf requests */
3971 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003972 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003973 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003974 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003975 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003976 goto done;
3977 }
3978
3979 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003980 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003981 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003982 if (result != L2CAP_CONF_SUCCESS)
3983 goto done;
3984 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003985 }
3986
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003987 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003988 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02003989
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003990 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003991 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003992 goto done;
3993 }
3994
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003995 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003996 goto done;
3997
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003998 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003999
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004000 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004001 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004002
Mat Martineau105bdf92012-04-27 16:50:48 -07004003 if (chan->mode == L2CAP_MODE_ERTM ||
4004 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004005 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004006
Mat Martineau3c588192012-04-11 10:48:42 -07004007 if (err < 0)
4008 l2cap_send_disconn_req(chan->conn, chan, -err);
4009 else
4010 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004011 }
4012
4013done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004014 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004015 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004016}
4017
Gustavo Padovan2d792812012-10-06 10:07:01 +01004018static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
4019 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004020{
4021 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4022 struct l2cap_disconn_rsp rsp;
4023 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004024 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004025 struct sock *sk;
4026
4027 scid = __le16_to_cpu(req->scid);
4028 dcid = __le16_to_cpu(req->dcid);
4029
4030 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4031
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004032 mutex_lock(&conn->chan_lock);
4033
4034 chan = __l2cap_get_chan_by_scid(conn, dcid);
4035 if (!chan) {
4036 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004037 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004038 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004039
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004040 l2cap_chan_lock(chan);
4041
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004042 sk = chan->sk;
4043
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004044 rsp.dcid = cpu_to_le16(chan->scid);
4045 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004046 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4047
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004048 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004049 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004050 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004051
Mat Martineau61d6ef32012-04-27 16:50:50 -07004052 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004053 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004054
4055 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004056
Gustavo Padovan80b98022012-05-27 22:27:51 -03004057 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004058 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004059
4060 mutex_unlock(&conn->chan_lock);
4061
Linus Torvalds1da177e2005-04-16 15:20:36 -07004062 return 0;
4063}
4064
Gustavo Padovan2d792812012-10-06 10:07:01 +01004065static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
4066 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004067{
4068 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4069 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004070 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004071
4072 scid = __le16_to_cpu(rsp->scid);
4073 dcid = __le16_to_cpu(rsp->dcid);
4074
4075 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4076
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004077 mutex_lock(&conn->chan_lock);
4078
4079 chan = __l2cap_get_chan_by_scid(conn, scid);
4080 if (!chan) {
4081 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004082 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004083 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004084
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004085 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004086
Mat Martineau61d6ef32012-04-27 16:50:50 -07004087 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004088 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004089
4090 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004091
Gustavo Padovan80b98022012-05-27 22:27:51 -03004092 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004093 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004094
4095 mutex_unlock(&conn->chan_lock);
4096
Linus Torvalds1da177e2005-04-16 15:20:36 -07004097 return 0;
4098}
4099
Gustavo Padovan2d792812012-10-06 10:07:01 +01004100static inline int l2cap_information_req(struct l2cap_conn *conn,
4101 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004102{
4103 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004104 u16 type;
4105
4106 type = __le16_to_cpu(req->type);
4107
4108 BT_DBG("type 0x%4.4x", type);
4109
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004110 if (type == L2CAP_IT_FEAT_MASK) {
4111 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004112 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004113 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004114 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4115 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004116 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004117 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004118 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004119 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004120 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004121 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004122
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004123 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004124 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4125 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004126 } else if (type == L2CAP_IT_FIXED_CHAN) {
4127 u8 buf[12];
4128 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004129
4130 if (enable_hs)
4131 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4132 else
4133 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4134
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004135 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4136 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004137 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004138 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4139 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004140 } else {
4141 struct l2cap_info_rsp rsp;
4142 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004143 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004144 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4145 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004146 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004147
4148 return 0;
4149}
4150
Gustavo Padovan2d792812012-10-06 10:07:01 +01004151static inline int l2cap_information_rsp(struct l2cap_conn *conn,
4152 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004153{
4154 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4155 u16 type, result;
4156
4157 type = __le16_to_cpu(rsp->type);
4158 result = __le16_to_cpu(rsp->result);
4159
4160 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4161
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004162 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4163 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004164 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004165 return 0;
4166
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004167 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004168
Ville Tervoadb08ed2010-08-04 09:43:33 +03004169 if (result != L2CAP_IR_SUCCESS) {
4170 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4171 conn->info_ident = 0;
4172
4173 l2cap_conn_start(conn);
4174
4175 return 0;
4176 }
4177
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004178 switch (type) {
4179 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004180 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004181
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004182 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004183 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004184 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004185
4186 conn->info_ident = l2cap_get_ident(conn);
4187
4188 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004189 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004190 } else {
4191 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4192 conn->info_ident = 0;
4193
4194 l2cap_conn_start(conn);
4195 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004196 break;
4197
4198 case L2CAP_IT_FIXED_CHAN:
4199 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004200 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004201 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004202
4203 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004204 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004205 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004206
Linus Torvalds1da177e2005-04-16 15:20:36 -07004207 return 0;
4208}
4209
Mat Martineau17009152012-10-23 15:24:07 -07004210static int l2cap_create_channel_req(struct l2cap_conn *conn,
4211 struct l2cap_cmd_hdr *cmd,
4212 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004213{
4214 struct l2cap_create_chan_req *req = data;
Mat Martineau17009152012-10-23 15:24:07 -07004215 struct l2cap_chan *chan;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004216 u16 psm, scid;
4217
4218 if (cmd_len != sizeof(*req))
4219 return -EPROTO;
4220
4221 if (!enable_hs)
4222 return -EINVAL;
4223
4224 psm = le16_to_cpu(req->psm);
4225 scid = le16_to_cpu(req->scid);
4226
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004227 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 -07004228
Mat Martineau17009152012-10-23 15:24:07 -07004229 if (req->amp_id) {
4230 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004231
Mat Martineau17009152012-10-23 15:24:07 -07004232 /* Validate AMP controller id */
4233 hdev = hci_dev_get(req->amp_id);
4234 if (!hdev || hdev->dev_type != HCI_AMP ||
4235 !test_bit(HCI_UP, &hdev->flags)) {
4236 struct l2cap_create_chan_rsp rsp;
4237
4238 rsp.dcid = 0;
4239 rsp.scid = cpu_to_le16(scid);
4240 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4241 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4242
4243 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4244 sizeof(rsp), &rsp);
4245
4246 if (hdev)
4247 hci_dev_put(hdev);
4248
4249 return 0;
4250 }
4251
4252 hci_dev_put(hdev);
4253 }
4254
4255 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4256 req->amp_id);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004257
4258 return 0;
4259}
4260
Mat Martineau8eb200b2012-10-23 15:24:17 -07004261static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4262{
4263 struct l2cap_move_chan_req req;
4264 u8 ident;
4265
4266 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4267
4268 ident = l2cap_get_ident(chan->conn);
4269 chan->ident = ident;
4270
4271 req.icid = cpu_to_le16(chan->scid);
4272 req.dest_amp_id = dest_amp_id;
4273
4274 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4275 &req);
4276
4277 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4278}
4279
Mat Martineau1500109b2012-10-23 15:24:15 -07004280static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004281{
4282 struct l2cap_move_chan_rsp rsp;
4283
Mat Martineau1500109b2012-10-23 15:24:15 -07004284 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004285
Mat Martineau1500109b2012-10-23 15:24:15 -07004286 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004287 rsp.result = cpu_to_le16(result);
4288
Mat Martineau1500109b2012-10-23 15:24:15 -07004289 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4290 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004291}
4292
Mat Martineau5b155ef2012-10-23 15:24:14 -07004293static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004294{
4295 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004296
Mat Martineau5b155ef2012-10-23 15:24:14 -07004297 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004298
Mat Martineau5b155ef2012-10-23 15:24:14 -07004299 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004300
Mat Martineau5b155ef2012-10-23 15:24:14 -07004301 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004302 cfm.result = cpu_to_le16(result);
4303
Mat Martineau5b155ef2012-10-23 15:24:14 -07004304 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4305 sizeof(cfm), &cfm);
4306
4307 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4308}
4309
4310static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4311{
4312 struct l2cap_move_chan_cfm cfm;
4313
4314 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4315
4316 cfm.icid = cpu_to_le16(icid);
4317 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4318
4319 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4320 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004321}
4322
4323static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004324 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004325{
4326 struct l2cap_move_chan_cfm_rsp rsp;
4327
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004328 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004329
4330 rsp.icid = cpu_to_le16(icid);
4331 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4332}
4333
Mat Martineau5f3847a2012-10-23 15:24:12 -07004334static void __release_logical_link(struct l2cap_chan *chan)
4335{
4336 chan->hs_hchan = NULL;
4337 chan->hs_hcon = NULL;
4338
4339 /* Placeholder - release the logical link */
4340}
4341
Mat Martineau1500109b2012-10-23 15:24:15 -07004342static void l2cap_logical_fail(struct l2cap_chan *chan)
4343{
4344 /* Logical link setup failed */
4345 if (chan->state != BT_CONNECTED) {
4346 /* Create channel failure, disconnect */
4347 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4348 return;
4349 }
4350
4351 switch (chan->move_role) {
4352 case L2CAP_MOVE_ROLE_RESPONDER:
4353 l2cap_move_done(chan);
4354 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4355 break;
4356 case L2CAP_MOVE_ROLE_INITIATOR:
4357 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4358 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4359 /* Remote has only sent pending or
4360 * success responses, clean up
4361 */
4362 l2cap_move_done(chan);
4363 }
4364
4365 /* Other amp move states imply that the move
4366 * has already aborted
4367 */
4368 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4369 break;
4370 }
4371}
4372
4373static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4374 struct hci_chan *hchan)
4375{
4376 struct l2cap_conf_rsp rsp;
4377 u8 code;
4378
4379 chan->hs_hcon = hchan->conn;
4380 chan->hs_hcon->l2cap_data = chan->conn;
4381
4382 code = l2cap_build_conf_rsp(chan, &rsp,
4383 L2CAP_CONF_SUCCESS, 0);
4384 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CONF_RSP, code,
4385 &rsp);
4386 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
4387
4388 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
4389 int err = 0;
4390
4391 set_default_fcs(chan);
4392
4393 err = l2cap_ertm_init(chan);
4394 if (err < 0)
4395 l2cap_send_disconn_req(chan->conn, chan, -err);
4396 else
4397 l2cap_chan_ready(chan);
4398 }
4399}
4400
4401static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4402 struct hci_chan *hchan)
4403{
4404 chan->hs_hcon = hchan->conn;
4405 chan->hs_hcon->l2cap_data = chan->conn;
4406
4407 BT_DBG("move_state %d", chan->move_state);
4408
4409 switch (chan->move_state) {
4410 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4411 /* Move confirm will be sent after a success
4412 * response is received
4413 */
4414 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4415 break;
4416 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4417 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4418 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4419 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4420 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4421 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4422 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4423 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4424 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4425 }
4426 break;
4427 default:
4428 /* Move was not in expected state, free the channel */
4429 __release_logical_link(chan);
4430
4431 chan->move_state = L2CAP_MOVE_STABLE;
4432 }
4433}
4434
4435/* Call with chan locked */
Mat Martineau5b155ef2012-10-23 15:24:14 -07004436static void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4437 u8 status)
4438{
Mat Martineau1500109b2012-10-23 15:24:15 -07004439 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4440
4441 if (status) {
4442 l2cap_logical_fail(chan);
4443 __release_logical_link(chan);
4444 return;
4445 }
4446
4447 if (chan->state != BT_CONNECTED) {
4448 /* Ignore logical link if channel is on BR/EDR */
4449 if (chan->local_amp_id)
4450 l2cap_logical_finish_create(chan, hchan);
4451 } else {
4452 l2cap_logical_finish_move(chan, hchan);
4453 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004454}
4455
Mat Martineau8eb200b2012-10-23 15:24:17 -07004456static void l2cap_do_create(struct l2cap_chan *chan, int result,
4457 u8 local_amp_id, u8 remote_amp_id)
4458{
4459 if (!test_bit(CONF_CONNECT_PEND, &chan->conf_state)) {
4460 struct l2cap_conn_rsp rsp;
4461 char buf[128];
4462 rsp.scid = cpu_to_le16(chan->dcid);
4463 rsp.dcid = cpu_to_le16(chan->scid);
4464
4465 /* Incoming channel on AMP */
4466 if (result == L2CAP_CR_SUCCESS) {
4467 /* Send successful response */
4468 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
4469 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
4470 } else {
4471 /* Send negative response */
4472 rsp.result = cpu_to_le16(L2CAP_CR_NO_MEM);
4473 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
4474 }
4475
4476 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4477 sizeof(rsp), &rsp);
4478
4479 if (result == L2CAP_CR_SUCCESS) {
4480 __l2cap_state_change(chan, BT_CONFIG);
4481 set_bit(CONF_REQ_SENT, &chan->conf_state);
4482 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4483 L2CAP_CONF_REQ,
4484 l2cap_build_conf_req(chan, buf), buf);
4485 chan->num_conf_req++;
4486 }
4487 } else {
4488 /* Outgoing channel on AMP */
4489 if (result == L2CAP_CR_SUCCESS) {
4490 chan->local_amp_id = local_amp_id;
4491 l2cap_send_create_chan_req(chan, remote_amp_id);
4492 } else {
4493 /* Revert to BR/EDR connect */
4494 l2cap_send_conn_req(chan);
4495 }
4496 }
4497}
4498
4499static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4500 u8 remote_amp_id)
4501{
4502 l2cap_move_setup(chan);
4503 chan->move_id = local_amp_id;
4504 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4505
4506 l2cap_send_move_chan_req(chan, remote_amp_id);
4507}
4508
4509static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4510{
4511 struct hci_chan *hchan = NULL;
4512
4513 /* Placeholder - get hci_chan for logical link */
4514
4515 if (hchan) {
4516 if (hchan->state == BT_CONNECTED) {
4517 /* Logical link is ready to go */
4518 chan->hs_hcon = hchan->conn;
4519 chan->hs_hcon->l2cap_data = chan->conn;
4520 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4521 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4522
4523 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4524 } else {
4525 /* Wait for logical link to be ready */
4526 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4527 }
4528 } else {
4529 /* Logical link not available */
4530 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4531 }
4532}
4533
4534static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4535{
4536 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4537 u8 rsp_result;
4538 if (result == -EINVAL)
4539 rsp_result = L2CAP_MR_BAD_ID;
4540 else
4541 rsp_result = L2CAP_MR_NOT_ALLOWED;
4542
4543 l2cap_send_move_chan_rsp(chan, rsp_result);
4544 }
4545
4546 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4547 chan->move_state = L2CAP_MOVE_STABLE;
4548
4549 /* Restart data transmission */
4550 l2cap_ertm_send(chan);
4551}
4552
4553void l2cap_physical_cfm(struct l2cap_chan *chan, int result, u8 local_amp_id,
4554 u8 remote_amp_id)
4555{
4556 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4557 chan, result, local_amp_id, remote_amp_id);
4558
4559 l2cap_chan_lock(chan);
4560
4561 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4562 l2cap_chan_unlock(chan);
4563 return;
4564 }
4565
4566 if (chan->state != BT_CONNECTED) {
4567 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4568 } else if (result != L2CAP_MR_SUCCESS) {
4569 l2cap_do_move_cancel(chan, result);
4570 } else {
4571 switch (chan->move_role) {
4572 case L2CAP_MOVE_ROLE_INITIATOR:
4573 l2cap_do_move_initiate(chan, local_amp_id,
4574 remote_amp_id);
4575 break;
4576 case L2CAP_MOVE_ROLE_RESPONDER:
4577 l2cap_do_move_respond(chan, result);
4578 break;
4579 default:
4580 l2cap_do_move_cancel(chan, result);
4581 break;
4582 }
4583 }
4584
4585 l2cap_chan_unlock(chan);
4586}
4587
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004588static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004589 struct l2cap_cmd_hdr *cmd,
4590 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004591{
4592 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004593 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004594 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004595 u16 icid = 0;
4596 u16 result = L2CAP_MR_NOT_ALLOWED;
4597
4598 if (cmd_len != sizeof(*req))
4599 return -EPROTO;
4600
4601 icid = le16_to_cpu(req->icid);
4602
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004603 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004604
4605 if (!enable_hs)
4606 return -EINVAL;
4607
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004608 chan = l2cap_get_chan_by_dcid(conn, icid);
4609 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004610 rsp.icid = cpu_to_le16(icid);
4611 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4612 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4613 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004614 return 0;
4615 }
4616
Mat Martineau1500109b2012-10-23 15:24:15 -07004617 chan->ident = cmd->ident;
4618
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004619 if (chan->scid < L2CAP_CID_DYN_START ||
4620 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4621 (chan->mode != L2CAP_MODE_ERTM &&
4622 chan->mode != L2CAP_MODE_STREAMING)) {
4623 result = L2CAP_MR_NOT_ALLOWED;
4624 goto send_move_response;
4625 }
4626
4627 if (chan->local_amp_id == req->dest_amp_id) {
4628 result = L2CAP_MR_SAME_ID;
4629 goto send_move_response;
4630 }
4631
4632 if (req->dest_amp_id) {
4633 struct hci_dev *hdev;
4634 hdev = hci_dev_get(req->dest_amp_id);
4635 if (!hdev || hdev->dev_type != HCI_AMP ||
4636 !test_bit(HCI_UP, &hdev->flags)) {
4637 if (hdev)
4638 hci_dev_put(hdev);
4639
4640 result = L2CAP_MR_BAD_ID;
4641 goto send_move_response;
4642 }
4643 hci_dev_put(hdev);
4644 }
4645
4646 /* Detect a move collision. Only send a collision response
4647 * if this side has "lost", otherwise proceed with the move.
4648 * The winner has the larger bd_addr.
4649 */
4650 if ((__chan_is_moving(chan) ||
4651 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
4652 bacmp(conn->src, conn->dst) > 0) {
4653 result = L2CAP_MR_COLLISION;
4654 goto send_move_response;
4655 }
4656
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004657 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4658 l2cap_move_setup(chan);
4659 chan->move_id = req->dest_amp_id;
4660 icid = chan->dcid;
4661
4662 if (!req->dest_amp_id) {
4663 /* Moving to BR/EDR */
4664 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4665 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4666 result = L2CAP_MR_PEND;
4667 } else {
4668 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4669 result = L2CAP_MR_SUCCESS;
4670 }
4671 } else {
4672 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4673 /* Placeholder - uncomment when amp functions are available */
4674 /*amp_accept_physical(chan, req->dest_amp_id);*/
4675 result = L2CAP_MR_PEND;
4676 }
4677
4678send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004679 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004680
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004681 l2cap_chan_unlock(chan);
4682
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004683 return 0;
4684}
4685
Mat Martineau5b155ef2012-10-23 15:24:14 -07004686static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4687{
4688 struct l2cap_chan *chan;
4689 struct hci_chan *hchan = NULL;
4690
4691 chan = l2cap_get_chan_by_scid(conn, icid);
4692 if (!chan) {
4693 l2cap_send_move_chan_cfm_icid(conn, icid);
4694 return;
4695 }
4696
4697 __clear_chan_timer(chan);
4698 if (result == L2CAP_MR_PEND)
4699 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4700
4701 switch (chan->move_state) {
4702 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4703 /* Move confirm will be sent when logical link
4704 * is complete.
4705 */
4706 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4707 break;
4708 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4709 if (result == L2CAP_MR_PEND) {
4710 break;
4711 } else if (test_bit(CONN_LOCAL_BUSY,
4712 &chan->conn_state)) {
4713 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4714 } else {
4715 /* Logical link is up or moving to BR/EDR,
4716 * proceed with move
4717 */
4718 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4719 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4720 }
4721 break;
4722 case L2CAP_MOVE_WAIT_RSP:
4723 /* Moving to AMP */
4724 if (result == L2CAP_MR_SUCCESS) {
4725 /* Remote is ready, send confirm immediately
4726 * after logical link is ready
4727 */
4728 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4729 } else {
4730 /* Both logical link and move success
4731 * are required to confirm
4732 */
4733 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4734 }
4735
4736 /* Placeholder - get hci_chan for logical link */
4737 if (!hchan) {
4738 /* Logical link not available */
4739 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4740 break;
4741 }
4742
4743 /* If the logical link is not yet connected, do not
4744 * send confirmation.
4745 */
4746 if (hchan->state != BT_CONNECTED)
4747 break;
4748
4749 /* Logical link is already ready to go */
4750
4751 chan->hs_hcon = hchan->conn;
4752 chan->hs_hcon->l2cap_data = chan->conn;
4753
4754 if (result == L2CAP_MR_SUCCESS) {
4755 /* Can confirm now */
4756 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4757 } else {
4758 /* Now only need move success
4759 * to confirm
4760 */
4761 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4762 }
4763
4764 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4765 break;
4766 default:
4767 /* Any other amp move state means the move failed. */
4768 chan->move_id = chan->local_amp_id;
4769 l2cap_move_done(chan);
4770 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4771 }
4772
4773 l2cap_chan_unlock(chan);
4774}
4775
4776static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
4777 u16 result)
4778{
4779 struct l2cap_chan *chan;
4780
4781 chan = l2cap_get_chan_by_ident(conn, ident);
4782 if (!chan) {
4783 /* Could not locate channel, icid is best guess */
4784 l2cap_send_move_chan_cfm_icid(conn, icid);
4785 return;
4786 }
4787
4788 __clear_chan_timer(chan);
4789
4790 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4791 if (result == L2CAP_MR_COLLISION) {
4792 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4793 } else {
4794 /* Cleanup - cancel move */
4795 chan->move_id = chan->local_amp_id;
4796 l2cap_move_done(chan);
4797 }
4798 }
4799
4800 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4801
4802 l2cap_chan_unlock(chan);
4803}
4804
4805static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
4806 struct l2cap_cmd_hdr *cmd,
4807 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004808{
4809 struct l2cap_move_chan_rsp *rsp = data;
4810 u16 icid, result;
4811
4812 if (cmd_len != sizeof(*rsp))
4813 return -EPROTO;
4814
4815 icid = le16_to_cpu(rsp->icid);
4816 result = le16_to_cpu(rsp->result);
4817
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004818 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004819
Mat Martineau5b155ef2012-10-23 15:24:14 -07004820 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
4821 l2cap_move_continue(conn, icid, result);
4822 else
4823 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004824
4825 return 0;
4826}
4827
Mat Martineau5f3847a2012-10-23 15:24:12 -07004828static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
4829 struct l2cap_cmd_hdr *cmd,
4830 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004831{
4832 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07004833 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004834 u16 icid, result;
4835
4836 if (cmd_len != sizeof(*cfm))
4837 return -EPROTO;
4838
4839 icid = le16_to_cpu(cfm->icid);
4840 result = le16_to_cpu(cfm->result);
4841
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004842 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004843
Mat Martineau5f3847a2012-10-23 15:24:12 -07004844 chan = l2cap_get_chan_by_dcid(conn, icid);
4845 if (!chan) {
4846 /* Spec requires a response even if the icid was not found */
4847 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4848 return 0;
4849 }
4850
4851 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
4852 if (result == L2CAP_MC_CONFIRMED) {
4853 chan->local_amp_id = chan->move_id;
4854 if (!chan->local_amp_id)
4855 __release_logical_link(chan);
4856 } else {
4857 chan->move_id = chan->local_amp_id;
4858 }
4859
4860 l2cap_move_done(chan);
4861 }
4862
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004863 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4864
Mat Martineau5f3847a2012-10-23 15:24:12 -07004865 l2cap_chan_unlock(chan);
4866
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004867 return 0;
4868}
4869
4870static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004871 struct l2cap_cmd_hdr *cmd,
4872 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004873{
4874 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07004875 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004876 u16 icid;
4877
4878 if (cmd_len != sizeof(*rsp))
4879 return -EPROTO;
4880
4881 icid = le16_to_cpu(rsp->icid);
4882
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004883 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004884
Mat Martineau3fd71a02012-10-23 15:24:16 -07004885 chan = l2cap_get_chan_by_scid(conn, icid);
4886 if (!chan)
4887 return 0;
4888
4889 __clear_chan_timer(chan);
4890
4891 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
4892 chan->local_amp_id = chan->move_id;
4893
4894 if (!chan->local_amp_id && chan->hs_hchan)
4895 __release_logical_link(chan);
4896
4897 l2cap_move_done(chan);
4898 }
4899
4900 l2cap_chan_unlock(chan);
4901
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004902 return 0;
4903}
4904
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004905static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004906 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02004907{
4908 u16 max_latency;
4909
4910 if (min > max || min < 6 || max > 3200)
4911 return -EINVAL;
4912
4913 if (to_multiplier < 10 || to_multiplier > 3200)
4914 return -EINVAL;
4915
4916 if (max >= to_multiplier * 8)
4917 return -EINVAL;
4918
4919 max_latency = (to_multiplier * 8 / max) - 1;
4920 if (latency > 499 || latency > max_latency)
4921 return -EINVAL;
4922
4923 return 0;
4924}
4925
4926static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004927 struct l2cap_cmd_hdr *cmd,
4928 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02004929{
4930 struct hci_conn *hcon = conn->hcon;
4931 struct l2cap_conn_param_update_req *req;
4932 struct l2cap_conn_param_update_rsp rsp;
4933 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004934 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02004935
4936 if (!(hcon->link_mode & HCI_LM_MASTER))
4937 return -EINVAL;
4938
4939 cmd_len = __le16_to_cpu(cmd->len);
4940 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
4941 return -EPROTO;
4942
4943 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004944 min = __le16_to_cpu(req->min);
4945 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02004946 latency = __le16_to_cpu(req->latency);
4947 to_multiplier = __le16_to_cpu(req->to_multiplier);
4948
4949 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 +01004950 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02004951
4952 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004953
4954 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
4955 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004956 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004957 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004958 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004959
4960 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004961 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02004962
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004963 if (!err)
4964 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
4965
Claudio Takahaside731152011-02-11 19:28:55 -02004966 return 0;
4967}
4968
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004969static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004970 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4971 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004972{
4973 int err = 0;
4974
4975 switch (cmd->code) {
4976 case L2CAP_COMMAND_REJ:
4977 l2cap_command_rej(conn, cmd, data);
4978 break;
4979
4980 case L2CAP_CONN_REQ:
4981 err = l2cap_connect_req(conn, cmd, data);
4982 break;
4983
4984 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03004985 case L2CAP_CREATE_CHAN_RSP:
Mat Martineau5909cf32012-10-23 15:24:08 -07004986 err = l2cap_connect_create_rsp(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004987 break;
4988
4989 case L2CAP_CONF_REQ:
4990 err = l2cap_config_req(conn, cmd, cmd_len, data);
4991 break;
4992
4993 case L2CAP_CONF_RSP:
4994 err = l2cap_config_rsp(conn, cmd, data);
4995 break;
4996
4997 case L2CAP_DISCONN_REQ:
4998 err = l2cap_disconnect_req(conn, cmd, data);
4999 break;
5000
5001 case L2CAP_DISCONN_RSP:
5002 err = l2cap_disconnect_rsp(conn, cmd, data);
5003 break;
5004
5005 case L2CAP_ECHO_REQ:
5006 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5007 break;
5008
5009 case L2CAP_ECHO_RSP:
5010 break;
5011
5012 case L2CAP_INFO_REQ:
5013 err = l2cap_information_req(conn, cmd, data);
5014 break;
5015
5016 case L2CAP_INFO_RSP:
5017 err = l2cap_information_rsp(conn, cmd, data);
5018 break;
5019
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005020 case L2CAP_CREATE_CHAN_REQ:
5021 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5022 break;
5023
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005024 case L2CAP_MOVE_CHAN_REQ:
5025 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5026 break;
5027
5028 case L2CAP_MOVE_CHAN_RSP:
5029 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
5030 break;
5031
5032 case L2CAP_MOVE_CHAN_CFM:
5033 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5034 break;
5035
5036 case L2CAP_MOVE_CHAN_CFM_RSP:
5037 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
5038 break;
5039
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005040 default:
5041 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5042 err = -EINVAL;
5043 break;
5044 }
5045
5046 return err;
5047}
5048
5049static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005050 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005051{
5052 switch (cmd->code) {
5053 case L2CAP_COMMAND_REJ:
5054 return 0;
5055
5056 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005057 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005058
5059 case L2CAP_CONN_PARAM_UPDATE_RSP:
5060 return 0;
5061
5062 default:
5063 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5064 return -EINVAL;
5065 }
5066}
5067
5068static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005069 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005070{
5071 u8 *data = skb->data;
5072 int len = skb->len;
5073 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005074 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005075
5076 l2cap_raw_recv(conn, skb);
5077
5078 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005079 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005080 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5081 data += L2CAP_CMD_HDR_SIZE;
5082 len -= L2CAP_CMD_HDR_SIZE;
5083
Al Viro88219a02007-07-29 00:17:25 -07005084 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005085
Gustavo Padovan2d792812012-10-06 10:07:01 +01005086 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5087 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005088
Al Viro88219a02007-07-29 00:17:25 -07005089 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005090 BT_DBG("corrupted command");
5091 break;
5092 }
5093
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005094 if (conn->hcon->type == LE_LINK)
5095 err = l2cap_le_sig_cmd(conn, &cmd, data);
5096 else
5097 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005098
5099 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005100 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005101
5102 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005103
5104 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005105 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005106 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5107 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005108 }
5109
Al Viro88219a02007-07-29 00:17:25 -07005110 data += cmd_len;
5111 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005112 }
5113
5114 kfree_skb(skb);
5115}
5116
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005117static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005118{
5119 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005120 int hdr_size;
5121
5122 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5123 hdr_size = L2CAP_EXT_HDR_SIZE;
5124 else
5125 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005126
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005127 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005128 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005129 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5130 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5131
5132 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005133 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005134 }
5135 return 0;
5136}
5137
Mat Martineau6ea00482012-05-17 20:53:52 -07005138static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005139{
Mat Martineaue31f7632012-05-17 20:53:41 -07005140 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005141
Mat Martineaue31f7632012-05-17 20:53:41 -07005142 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005143
Mat Martineaue31f7632012-05-17 20:53:41 -07005144 memset(&control, 0, sizeof(control));
5145 control.sframe = 1;
5146 control.final = 1;
5147 control.reqseq = chan->buffer_seq;
5148 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005149
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005150 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005151 control.super = L2CAP_SUPER_RNR;
5152 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005153 }
5154
Mat Martineaue31f7632012-05-17 20:53:41 -07005155 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5156 chan->unacked_frames > 0)
5157 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005158
Mat Martineaue31f7632012-05-17 20:53:41 -07005159 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005160 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005161
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005162 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005163 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5164 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5165 * send it now.
5166 */
5167 control.super = L2CAP_SUPER_RR;
5168 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005169 }
5170}
5171
Gustavo Padovan2d792812012-10-06 10:07:01 +01005172static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5173 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005174{
Mat Martineau84084a32011-07-22 14:54:00 -07005175 /* skb->len reflects data in skb as well as all fragments
5176 * skb->data_len reflects only data in fragments
5177 */
5178 if (!skb_has_frag_list(skb))
5179 skb_shinfo(skb)->frag_list = new_frag;
5180
5181 new_frag->next = NULL;
5182
5183 (*last_frag)->next = new_frag;
5184 *last_frag = new_frag;
5185
5186 skb->len += new_frag->len;
5187 skb->data_len += new_frag->len;
5188 skb->truesize += new_frag->truesize;
5189}
5190
Mat Martineau4b51dae92012-05-17 20:53:37 -07005191static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5192 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005193{
5194 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005195
Mat Martineau4b51dae92012-05-17 20:53:37 -07005196 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005197 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005198 if (chan->sdu)
5199 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005200
Gustavo Padovan80b98022012-05-27 22:27:51 -03005201 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005202 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005203
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005204 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005205 if (chan->sdu)
5206 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005207
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005208 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005209 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005210
Mat Martineau84084a32011-07-22 14:54:00 -07005211 if (chan->sdu_len > chan->imtu) {
5212 err = -EMSGSIZE;
5213 break;
5214 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005215
Mat Martineau84084a32011-07-22 14:54:00 -07005216 if (skb->len >= chan->sdu_len)
5217 break;
5218
5219 chan->sdu = skb;
5220 chan->sdu_last_frag = skb;
5221
5222 skb = NULL;
5223 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005224 break;
5225
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005226 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005227 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005228 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005229
Mat Martineau84084a32011-07-22 14:54:00 -07005230 append_skb_frag(chan->sdu, skb,
5231 &chan->sdu_last_frag);
5232 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005233
Mat Martineau84084a32011-07-22 14:54:00 -07005234 if (chan->sdu->len >= chan->sdu_len)
5235 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005236
Mat Martineau84084a32011-07-22 14:54:00 -07005237 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005238 break;
5239
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005240 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005241 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005242 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005243
Mat Martineau84084a32011-07-22 14:54:00 -07005244 append_skb_frag(chan->sdu, skb,
5245 &chan->sdu_last_frag);
5246 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005247
Mat Martineau84084a32011-07-22 14:54:00 -07005248 if (chan->sdu->len != chan->sdu_len)
5249 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005250
Gustavo Padovan80b98022012-05-27 22:27:51 -03005251 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005252
Mat Martineau84084a32011-07-22 14:54:00 -07005253 if (!err) {
5254 /* Reassembly complete */
5255 chan->sdu = NULL;
5256 chan->sdu_last_frag = NULL;
5257 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005258 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005259 break;
5260 }
5261
Mat Martineau84084a32011-07-22 14:54:00 -07005262 if (err) {
5263 kfree_skb(skb);
5264 kfree_skb(chan->sdu);
5265 chan->sdu = NULL;
5266 chan->sdu_last_frag = NULL;
5267 chan->sdu_len = 0;
5268 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005269
Mat Martineau84084a32011-07-22 14:54:00 -07005270 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005271}
5272
Mat Martineau32b32732012-10-23 15:24:11 -07005273static int l2cap_resegment(struct l2cap_chan *chan)
5274{
5275 /* Placeholder */
5276 return 0;
5277}
5278
Mat Martineaue3281402011-07-07 09:39:02 -07005279void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005280{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005281 u8 event;
5282
5283 if (chan->mode != L2CAP_MODE_ERTM)
5284 return;
5285
5286 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005287 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005288}
5289
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005290static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5291{
Mat Martineau63838722012-05-17 20:53:45 -07005292 int err = 0;
5293 /* Pass sequential frames to l2cap_reassemble_sdu()
5294 * until a gap is encountered.
5295 */
5296
5297 BT_DBG("chan %p", chan);
5298
5299 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5300 struct sk_buff *skb;
5301 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5302 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5303
5304 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5305
5306 if (!skb)
5307 break;
5308
5309 skb_unlink(skb, &chan->srej_q);
5310 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5311 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5312 if (err)
5313 break;
5314 }
5315
5316 if (skb_queue_empty(&chan->srej_q)) {
5317 chan->rx_state = L2CAP_RX_STATE_RECV;
5318 l2cap_send_ack(chan);
5319 }
5320
5321 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005322}
5323
5324static void l2cap_handle_srej(struct l2cap_chan *chan,
5325 struct l2cap_ctrl *control)
5326{
Mat Martineauf80842a2012-05-17 20:53:46 -07005327 struct sk_buff *skb;
5328
5329 BT_DBG("chan %p, control %p", chan, control);
5330
5331 if (control->reqseq == chan->next_tx_seq) {
5332 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
5333 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5334 return;
5335 }
5336
5337 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5338
5339 if (skb == NULL) {
5340 BT_DBG("Seq %d not available for retransmission",
5341 control->reqseq);
5342 return;
5343 }
5344
5345 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5346 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
5347 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5348 return;
5349 }
5350
5351 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5352
5353 if (control->poll) {
5354 l2cap_pass_to_tx(chan, control);
5355
5356 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5357 l2cap_retransmit(chan, control);
5358 l2cap_ertm_send(chan);
5359
5360 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5361 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5362 chan->srej_save_reqseq = control->reqseq;
5363 }
5364 } else {
5365 l2cap_pass_to_tx_fbit(chan, control);
5366
5367 if (control->final) {
5368 if (chan->srej_save_reqseq != control->reqseq ||
5369 !test_and_clear_bit(CONN_SREJ_ACT,
5370 &chan->conn_state))
5371 l2cap_retransmit(chan, control);
5372 } else {
5373 l2cap_retransmit(chan, control);
5374 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5375 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5376 chan->srej_save_reqseq = control->reqseq;
5377 }
5378 }
5379 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005380}
5381
5382static void l2cap_handle_rej(struct l2cap_chan *chan,
5383 struct l2cap_ctrl *control)
5384{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005385 struct sk_buff *skb;
5386
5387 BT_DBG("chan %p, control %p", chan, control);
5388
5389 if (control->reqseq == chan->next_tx_seq) {
5390 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
5391 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5392 return;
5393 }
5394
5395 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5396
5397 if (chan->max_tx && skb &&
5398 bt_cb(skb)->control.retries >= chan->max_tx) {
5399 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
5400 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5401 return;
5402 }
5403
5404 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5405
5406 l2cap_pass_to_tx(chan, control);
5407
5408 if (control->final) {
5409 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5410 l2cap_retransmit_all(chan, control);
5411 } else {
5412 l2cap_retransmit_all(chan, control);
5413 l2cap_ertm_send(chan);
5414 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5415 set_bit(CONN_REJ_ACT, &chan->conn_state);
5416 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005417}
5418
Mat Martineau4b51dae92012-05-17 20:53:37 -07005419static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5420{
5421 BT_DBG("chan %p, txseq %d", chan, txseq);
5422
5423 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5424 chan->expected_tx_seq);
5425
5426 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5427 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005428 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005429 /* See notes below regarding "double poll" and
5430 * invalid packets.
5431 */
5432 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5433 BT_DBG("Invalid/Ignore - after SREJ");
5434 return L2CAP_TXSEQ_INVALID_IGNORE;
5435 } else {
5436 BT_DBG("Invalid - in window after SREJ sent");
5437 return L2CAP_TXSEQ_INVALID;
5438 }
5439 }
5440
5441 if (chan->srej_list.head == txseq) {
5442 BT_DBG("Expected SREJ");
5443 return L2CAP_TXSEQ_EXPECTED_SREJ;
5444 }
5445
5446 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5447 BT_DBG("Duplicate SREJ - txseq already stored");
5448 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5449 }
5450
5451 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5452 BT_DBG("Unexpected SREJ - not requested");
5453 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5454 }
5455 }
5456
5457 if (chan->expected_tx_seq == txseq) {
5458 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5459 chan->tx_win) {
5460 BT_DBG("Invalid - txseq outside tx window");
5461 return L2CAP_TXSEQ_INVALID;
5462 } else {
5463 BT_DBG("Expected");
5464 return L2CAP_TXSEQ_EXPECTED;
5465 }
5466 }
5467
5468 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005469 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005470 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5471 return L2CAP_TXSEQ_DUPLICATE;
5472 }
5473
5474 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5475 /* A source of invalid packets is a "double poll" condition,
5476 * where delays cause us to send multiple poll packets. If
5477 * the remote stack receives and processes both polls,
5478 * sequence numbers can wrap around in such a way that a
5479 * resent frame has a sequence number that looks like new data
5480 * with a sequence gap. This would trigger an erroneous SREJ
5481 * request.
5482 *
5483 * Fortunately, this is impossible with a tx window that's
5484 * less than half of the maximum sequence number, which allows
5485 * invalid frames to be safely ignored.
5486 *
5487 * With tx window sizes greater than half of the tx window
5488 * maximum, the frame is invalid and cannot be ignored. This
5489 * causes a disconnect.
5490 */
5491
5492 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5493 BT_DBG("Invalid/Ignore - txseq outside tx window");
5494 return L2CAP_TXSEQ_INVALID_IGNORE;
5495 } else {
5496 BT_DBG("Invalid - txseq outside tx window");
5497 return L2CAP_TXSEQ_INVALID;
5498 }
5499 } else {
5500 BT_DBG("Unexpected - txseq indicates missing frames");
5501 return L2CAP_TXSEQ_UNEXPECTED;
5502 }
5503}
5504
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005505static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5506 struct l2cap_ctrl *control,
5507 struct sk_buff *skb, u8 event)
5508{
5509 int err = 0;
5510 bool skb_in_use = 0;
5511
5512 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5513 event);
5514
5515 switch (event) {
5516 case L2CAP_EV_RECV_IFRAME:
5517 switch (l2cap_classify_txseq(chan, control->txseq)) {
5518 case L2CAP_TXSEQ_EXPECTED:
5519 l2cap_pass_to_tx(chan, control);
5520
5521 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5522 BT_DBG("Busy, discarding expected seq %d",
5523 control->txseq);
5524 break;
5525 }
5526
5527 chan->expected_tx_seq = __next_seq(chan,
5528 control->txseq);
5529
5530 chan->buffer_seq = chan->expected_tx_seq;
5531 skb_in_use = 1;
5532
5533 err = l2cap_reassemble_sdu(chan, skb, control);
5534 if (err)
5535 break;
5536
5537 if (control->final) {
5538 if (!test_and_clear_bit(CONN_REJ_ACT,
5539 &chan->conn_state)) {
5540 control->final = 0;
5541 l2cap_retransmit_all(chan, control);
5542 l2cap_ertm_send(chan);
5543 }
5544 }
5545
5546 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5547 l2cap_send_ack(chan);
5548 break;
5549 case L2CAP_TXSEQ_UNEXPECTED:
5550 l2cap_pass_to_tx(chan, control);
5551
5552 /* Can't issue SREJ frames in the local busy state.
5553 * Drop this frame, it will be seen as missing
5554 * when local busy is exited.
5555 */
5556 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5557 BT_DBG("Busy, discarding unexpected seq %d",
5558 control->txseq);
5559 break;
5560 }
5561
5562 /* There was a gap in the sequence, so an SREJ
5563 * must be sent for each missing frame. The
5564 * current frame is stored for later use.
5565 */
5566 skb_queue_tail(&chan->srej_q, skb);
5567 skb_in_use = 1;
5568 BT_DBG("Queued %p (queue len %d)", skb,
5569 skb_queue_len(&chan->srej_q));
5570
5571 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5572 l2cap_seq_list_clear(&chan->srej_list);
5573 l2cap_send_srej(chan, control->txseq);
5574
5575 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5576 break;
5577 case L2CAP_TXSEQ_DUPLICATE:
5578 l2cap_pass_to_tx(chan, control);
5579 break;
5580 case L2CAP_TXSEQ_INVALID_IGNORE:
5581 break;
5582 case L2CAP_TXSEQ_INVALID:
5583 default:
5584 l2cap_send_disconn_req(chan->conn, chan,
5585 ECONNRESET);
5586 break;
5587 }
5588 break;
5589 case L2CAP_EV_RECV_RR:
5590 l2cap_pass_to_tx(chan, control);
5591 if (control->final) {
5592 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5593
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005594 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5595 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005596 control->final = 0;
5597 l2cap_retransmit_all(chan, control);
5598 }
5599
5600 l2cap_ertm_send(chan);
5601 } else if (control->poll) {
5602 l2cap_send_i_or_rr_or_rnr(chan);
5603 } else {
5604 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5605 &chan->conn_state) &&
5606 chan->unacked_frames)
5607 __set_retrans_timer(chan);
5608
5609 l2cap_ertm_send(chan);
5610 }
5611 break;
5612 case L2CAP_EV_RECV_RNR:
5613 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5614 l2cap_pass_to_tx(chan, control);
5615 if (control && control->poll) {
5616 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5617 l2cap_send_rr_or_rnr(chan, 0);
5618 }
5619 __clear_retrans_timer(chan);
5620 l2cap_seq_list_clear(&chan->retrans_list);
5621 break;
5622 case L2CAP_EV_RECV_REJ:
5623 l2cap_handle_rej(chan, control);
5624 break;
5625 case L2CAP_EV_RECV_SREJ:
5626 l2cap_handle_srej(chan, control);
5627 break;
5628 default:
5629 break;
5630 }
5631
5632 if (skb && !skb_in_use) {
5633 BT_DBG("Freeing %p", skb);
5634 kfree_skb(skb);
5635 }
5636
5637 return err;
5638}
5639
5640static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5641 struct l2cap_ctrl *control,
5642 struct sk_buff *skb, u8 event)
5643{
5644 int err = 0;
5645 u16 txseq = control->txseq;
5646 bool skb_in_use = 0;
5647
5648 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5649 event);
5650
5651 switch (event) {
5652 case L2CAP_EV_RECV_IFRAME:
5653 switch (l2cap_classify_txseq(chan, txseq)) {
5654 case L2CAP_TXSEQ_EXPECTED:
5655 /* Keep frame for reassembly later */
5656 l2cap_pass_to_tx(chan, control);
5657 skb_queue_tail(&chan->srej_q, skb);
5658 skb_in_use = 1;
5659 BT_DBG("Queued %p (queue len %d)", skb,
5660 skb_queue_len(&chan->srej_q));
5661
5662 chan->expected_tx_seq = __next_seq(chan, txseq);
5663 break;
5664 case L2CAP_TXSEQ_EXPECTED_SREJ:
5665 l2cap_seq_list_pop(&chan->srej_list);
5666
5667 l2cap_pass_to_tx(chan, control);
5668 skb_queue_tail(&chan->srej_q, skb);
5669 skb_in_use = 1;
5670 BT_DBG("Queued %p (queue len %d)", skb,
5671 skb_queue_len(&chan->srej_q));
5672
5673 err = l2cap_rx_queued_iframes(chan);
5674 if (err)
5675 break;
5676
5677 break;
5678 case L2CAP_TXSEQ_UNEXPECTED:
5679 /* Got a frame that can't be reassembled yet.
5680 * Save it for later, and send SREJs to cover
5681 * the missing frames.
5682 */
5683 skb_queue_tail(&chan->srej_q, skb);
5684 skb_in_use = 1;
5685 BT_DBG("Queued %p (queue len %d)", skb,
5686 skb_queue_len(&chan->srej_q));
5687
5688 l2cap_pass_to_tx(chan, control);
5689 l2cap_send_srej(chan, control->txseq);
5690 break;
5691 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
5692 /* This frame was requested with an SREJ, but
5693 * some expected retransmitted frames are
5694 * missing. Request retransmission of missing
5695 * SREJ'd frames.
5696 */
5697 skb_queue_tail(&chan->srej_q, skb);
5698 skb_in_use = 1;
5699 BT_DBG("Queued %p (queue len %d)", skb,
5700 skb_queue_len(&chan->srej_q));
5701
5702 l2cap_pass_to_tx(chan, control);
5703 l2cap_send_srej_list(chan, control->txseq);
5704 break;
5705 case L2CAP_TXSEQ_DUPLICATE_SREJ:
5706 /* We've already queued this frame. Drop this copy. */
5707 l2cap_pass_to_tx(chan, control);
5708 break;
5709 case L2CAP_TXSEQ_DUPLICATE:
5710 /* Expecting a later sequence number, so this frame
5711 * was already received. Ignore it completely.
5712 */
5713 break;
5714 case L2CAP_TXSEQ_INVALID_IGNORE:
5715 break;
5716 case L2CAP_TXSEQ_INVALID:
5717 default:
5718 l2cap_send_disconn_req(chan->conn, chan,
5719 ECONNRESET);
5720 break;
5721 }
5722 break;
5723 case L2CAP_EV_RECV_RR:
5724 l2cap_pass_to_tx(chan, control);
5725 if (control->final) {
5726 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5727
5728 if (!test_and_clear_bit(CONN_REJ_ACT,
5729 &chan->conn_state)) {
5730 control->final = 0;
5731 l2cap_retransmit_all(chan, control);
5732 }
5733
5734 l2cap_ertm_send(chan);
5735 } else if (control->poll) {
5736 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5737 &chan->conn_state) &&
5738 chan->unacked_frames) {
5739 __set_retrans_timer(chan);
5740 }
5741
5742 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5743 l2cap_send_srej_tail(chan);
5744 } else {
5745 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5746 &chan->conn_state) &&
5747 chan->unacked_frames)
5748 __set_retrans_timer(chan);
5749
5750 l2cap_send_ack(chan);
5751 }
5752 break;
5753 case L2CAP_EV_RECV_RNR:
5754 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5755 l2cap_pass_to_tx(chan, control);
5756 if (control->poll) {
5757 l2cap_send_srej_tail(chan);
5758 } else {
5759 struct l2cap_ctrl rr_control;
5760 memset(&rr_control, 0, sizeof(rr_control));
5761 rr_control.sframe = 1;
5762 rr_control.super = L2CAP_SUPER_RR;
5763 rr_control.reqseq = chan->buffer_seq;
5764 l2cap_send_sframe(chan, &rr_control);
5765 }
5766
5767 break;
5768 case L2CAP_EV_RECV_REJ:
5769 l2cap_handle_rej(chan, control);
5770 break;
5771 case L2CAP_EV_RECV_SREJ:
5772 l2cap_handle_srej(chan, control);
5773 break;
5774 }
5775
5776 if (skb && !skb_in_use) {
5777 BT_DBG("Freeing %p", skb);
5778 kfree_skb(skb);
5779 }
5780
5781 return err;
5782}
5783
Mat Martineau32b32732012-10-23 15:24:11 -07005784static int l2cap_finish_move(struct l2cap_chan *chan)
5785{
5786 BT_DBG("chan %p", chan);
5787
5788 chan->rx_state = L2CAP_RX_STATE_RECV;
5789
5790 if (chan->hs_hcon)
5791 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
5792 else
5793 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
5794
5795 return l2cap_resegment(chan);
5796}
5797
5798static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
5799 struct l2cap_ctrl *control,
5800 struct sk_buff *skb, u8 event)
5801{
5802 int err;
5803
5804 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5805 event);
5806
5807 if (!control->poll)
5808 return -EPROTO;
5809
5810 l2cap_process_reqseq(chan, control->reqseq);
5811
5812 if (!skb_queue_empty(&chan->tx_q))
5813 chan->tx_send_head = skb_peek(&chan->tx_q);
5814 else
5815 chan->tx_send_head = NULL;
5816
5817 /* Rewind next_tx_seq to the point expected
5818 * by the receiver.
5819 */
5820 chan->next_tx_seq = control->reqseq;
5821 chan->unacked_frames = 0;
5822
5823 err = l2cap_finish_move(chan);
5824 if (err)
5825 return err;
5826
5827 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5828 l2cap_send_i_or_rr_or_rnr(chan);
5829
5830 if (event == L2CAP_EV_RECV_IFRAME)
5831 return -EPROTO;
5832
5833 return l2cap_rx_state_recv(chan, control, NULL, event);
5834}
5835
5836static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
5837 struct l2cap_ctrl *control,
5838 struct sk_buff *skb, u8 event)
5839{
5840 int err;
5841
5842 if (!control->final)
5843 return -EPROTO;
5844
5845 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5846
5847 chan->rx_state = L2CAP_RX_STATE_RECV;
5848 l2cap_process_reqseq(chan, control->reqseq);
5849
5850 if (!skb_queue_empty(&chan->tx_q))
5851 chan->tx_send_head = skb_peek(&chan->tx_q);
5852 else
5853 chan->tx_send_head = NULL;
5854
5855 /* Rewind next_tx_seq to the point expected
5856 * by the receiver.
5857 */
5858 chan->next_tx_seq = control->reqseq;
5859 chan->unacked_frames = 0;
5860
5861 if (chan->hs_hcon)
5862 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
5863 else
5864 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
5865
5866 err = l2cap_resegment(chan);
5867
5868 if (!err)
5869 err = l2cap_rx_state_recv(chan, control, skb, event);
5870
5871 return err;
5872}
5873
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005874static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
5875{
5876 /* Make sure reqseq is for a packet that has been sent but not acked */
5877 u16 unacked;
5878
5879 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
5880 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
5881}
5882
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005883static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5884 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005885{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005886 int err = 0;
5887
5888 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
5889 control, skb, event, chan->rx_state);
5890
5891 if (__valid_reqseq(chan, control->reqseq)) {
5892 switch (chan->rx_state) {
5893 case L2CAP_RX_STATE_RECV:
5894 err = l2cap_rx_state_recv(chan, control, skb, event);
5895 break;
5896 case L2CAP_RX_STATE_SREJ_SENT:
5897 err = l2cap_rx_state_srej_sent(chan, control, skb,
5898 event);
5899 break;
Mat Martineau32b32732012-10-23 15:24:11 -07005900 case L2CAP_RX_STATE_WAIT_P:
5901 err = l2cap_rx_state_wait_p(chan, control, skb, event);
5902 break;
5903 case L2CAP_RX_STATE_WAIT_F:
5904 err = l2cap_rx_state_wait_f(chan, control, skb, event);
5905 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005906 default:
5907 /* shut it down */
5908 break;
5909 }
5910 } else {
5911 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
5912 control->reqseq, chan->next_tx_seq,
5913 chan->expected_ack_seq);
5914 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5915 }
5916
5917 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005918}
5919
5920static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5921 struct sk_buff *skb)
5922{
Mat Martineau4b51dae92012-05-17 20:53:37 -07005923 int err = 0;
5924
5925 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
5926 chan->rx_state);
5927
5928 if (l2cap_classify_txseq(chan, control->txseq) ==
5929 L2CAP_TXSEQ_EXPECTED) {
5930 l2cap_pass_to_tx(chan, control);
5931
5932 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
5933 __next_seq(chan, chan->buffer_seq));
5934
5935 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5936
5937 l2cap_reassemble_sdu(chan, skb, control);
5938 } else {
5939 if (chan->sdu) {
5940 kfree_skb(chan->sdu);
5941 chan->sdu = NULL;
5942 }
5943 chan->sdu_last_frag = NULL;
5944 chan->sdu_len = 0;
5945
5946 if (skb) {
5947 BT_DBG("Freeing %p", skb);
5948 kfree_skb(skb);
5949 }
5950 }
5951
5952 chan->last_acked_seq = control->txseq;
5953 chan->expected_tx_seq = __next_seq(chan, control->txseq);
5954
5955 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005956}
5957
5958static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
5959{
5960 struct l2cap_ctrl *control = &bt_cb(skb)->control;
5961 u16 len;
5962 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005963
Mat Martineaub76bbd62012-04-11 10:48:43 -07005964 __unpack_control(chan, skb);
5965
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005966 len = skb->len;
5967
5968 /*
5969 * We can just drop the corrupted I-frame here.
5970 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005971 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005972 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005973 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005974 goto drop;
5975
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005976 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005977 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005978
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005979 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005980 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005981
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005982 if (len > chan->mps) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005983 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005984 goto drop;
5985 }
5986
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005987 if (!control->sframe) {
5988 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005989
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005990 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
5991 control->sar, control->reqseq, control->final,
5992 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03005993
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005994 /* Validate F-bit - F=0 always valid, F=1 only
5995 * valid in TX WAIT_F
5996 */
5997 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005998 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005999
6000 if (chan->mode != L2CAP_MODE_STREAMING) {
6001 event = L2CAP_EV_RECV_IFRAME;
6002 err = l2cap_rx(chan, control, skb, event);
6003 } else {
6004 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006005 }
6006
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006007 if (err)
6008 l2cap_send_disconn_req(chan->conn, chan,
6009 ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006010 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006011 const u8 rx_func_to_event[4] = {
6012 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6013 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6014 };
6015
6016 /* Only I-frames are expected in streaming mode */
6017 if (chan->mode == L2CAP_MODE_STREAMING)
6018 goto drop;
6019
6020 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6021 control->reqseq, control->final, control->poll,
6022 control->super);
6023
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006024 if (len != 0) {
6025 BT_ERR("%d", len);
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03006026 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006027 goto drop;
6028 }
6029
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006030 /* Validate F and P bits */
6031 if (control->final && (control->poll ||
6032 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6033 goto drop;
6034
6035 event = rx_func_to_event[control->super];
6036 if (l2cap_rx(chan, control, skb, event))
6037 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006038 }
6039
6040 return 0;
6041
6042drop:
6043 kfree_skb(skb);
6044 return 0;
6045}
6046
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006047static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6048 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006049{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006050 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006051
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006052 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006053 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006054 if (cid == L2CAP_CID_A2MP) {
6055 chan = a2mp_channel_create(conn, skb);
6056 if (!chan) {
6057 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006058 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006059 }
6060
6061 l2cap_chan_lock(chan);
6062 } else {
6063 BT_DBG("unknown cid 0x%4.4x", cid);
6064 /* Drop packet and return */
6065 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006066 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006067 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006068 }
6069
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006070 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006071
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006072 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006073 goto drop;
6074
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006075 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006076 case L2CAP_MODE_BASIC:
6077 /* If socket recv buffers overflows we drop data here
6078 * which is *bad* because L2CAP has to be reliable.
6079 * But we don't have any other choice. L2CAP doesn't
6080 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006081
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006082 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006083 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006084
Gustavo Padovan80b98022012-05-27 22:27:51 -03006085 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006086 goto done;
6087 break;
6088
6089 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006090 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006091 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006092 goto done;
6093
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006094 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006095 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006096 break;
6097 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006098
6099drop:
6100 kfree_skb(skb);
6101
6102done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006103 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006104}
6105
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006106static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6107 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006108{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006109 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006110
Ido Yarivc2287682012-04-20 15:46:07 -03006111 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006112 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006113 goto drop;
6114
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006115 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006116
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006117 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006118 goto drop;
6119
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006120 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006121 goto drop;
6122
Gustavo Padovan80b98022012-05-27 22:27:51 -03006123 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006124 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006125
6126drop:
6127 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006128}
6129
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006130static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
6131 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006132{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006133 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006134
Ido Yarivc2287682012-04-20 15:46:07 -03006135 chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006136 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006137 goto drop;
6138
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006139 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006140
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006141 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006142 goto drop;
6143
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006144 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006145 goto drop;
6146
Gustavo Padovan80b98022012-05-27 22:27:51 -03006147 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006148 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006149
6150drop:
6151 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006152}
6153
Linus Torvalds1da177e2005-04-16 15:20:36 -07006154static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6155{
6156 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006157 u16 cid, len;
6158 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006159
6160 skb_pull(skb, L2CAP_HDR_SIZE);
6161 cid = __le16_to_cpu(lh->cid);
6162 len = __le16_to_cpu(lh->len);
6163
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006164 if (len != skb->len) {
6165 kfree_skb(skb);
6166 return;
6167 }
6168
Linus Torvalds1da177e2005-04-16 15:20:36 -07006169 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6170
6171 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02006172 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006173 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006174 l2cap_sig_channel(conn, skb);
6175 break;
6176
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006177 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006178 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006179 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006180 l2cap_conless_channel(conn, psm, skb);
6181 break;
6182
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006183 case L2CAP_CID_LE_DATA:
6184 l2cap_att_channel(conn, cid, skb);
6185 break;
6186
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006187 case L2CAP_CID_SMP:
6188 if (smp_sig_channel(conn, skb))
6189 l2cap_conn_del(conn->hcon, EACCES);
6190 break;
6191
Linus Torvalds1da177e2005-04-16 15:20:36 -07006192 default:
6193 l2cap_data_channel(conn, cid, skb);
6194 break;
6195 }
6196}
6197
6198/* ---- L2CAP interface with lower layer (HCI) ---- */
6199
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006200int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006201{
6202 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006203 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006204
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006205 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006206
6207 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006208 read_lock(&chan_list_lock);
6209 list_for_each_entry(c, &chan_list, global_l) {
6210 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006211
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006212 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006213 continue;
6214
6215 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006216 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006217 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006218 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006219 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006220 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
6221 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006222 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006223 lm2 |= HCI_LM_MASTER;
6224 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006225 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006226 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006227
6228 return exact ? lm1 : lm2;
6229}
6230
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006231void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006232{
Marcel Holtmann01394182006-07-03 10:02:46 +02006233 struct l2cap_conn *conn;
6234
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006235 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006236
Linus Torvalds1da177e2005-04-16 15:20:36 -07006237 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006238 conn = l2cap_conn_add(hcon, status);
6239 if (conn)
6240 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02006241 } else
Joe Perchese1750722011-06-29 18:18:29 -07006242 l2cap_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006243
Linus Torvalds1da177e2005-04-16 15:20:36 -07006244}
6245
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006246int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006247{
6248 struct l2cap_conn *conn = hcon->l2cap_data;
6249
6250 BT_DBG("hcon %p", hcon);
6251
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006252 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006253 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006254 return conn->disc_reason;
6255}
6256
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006257void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006258{
6259 BT_DBG("hcon %p reason %d", hcon, reason);
6260
Joe Perchese1750722011-06-29 18:18:29 -07006261 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006262}
6263
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006264static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006265{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006266 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006267 return;
6268
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006269 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006270 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006271 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006272 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006273 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006274 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006275 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006276 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006277 }
6278}
6279
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006280int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006281{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006282 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006283 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006284
Marcel Holtmann01394182006-07-03 10:02:46 +02006285 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006286 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006287
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006288 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006289
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006290 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306291 if (!status && encrypt)
6292 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006293 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006294 }
6295
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006296 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006297
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006298 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006299 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006300
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006301 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6302 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006303
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006304 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6305 l2cap_chan_unlock(chan);
6306 continue;
6307 }
6308
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006309 if (chan->scid == L2CAP_CID_LE_DATA) {
6310 if (!status && encrypt) {
6311 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006312 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006313 }
6314
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006315 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006316 continue;
6317 }
6318
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03006319 if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006320 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006321 continue;
6322 }
6323
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006324 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006325 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03006326 struct sock *sk = chan->sk;
6327
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006328 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03006329 sk->sk_state_change(sk);
6330
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006331 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006332 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006333 continue;
6334 }
6335
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006336 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006337 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006338 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006339 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006340 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006341 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006342 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006343 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006344 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006345 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006346
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006347 lock_sock(sk);
6348
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006349 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006350 if (test_bit(BT_SK_DEFER_SETUP,
6351 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006352 res = L2CAP_CR_PEND;
6353 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006354 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006355 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006356 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006357 res = L2CAP_CR_SUCCESS;
6358 stat = L2CAP_CS_NO_INFO;
6359 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006360 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006361 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006362 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006363 res = L2CAP_CR_SEC_BLOCK;
6364 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006365 }
6366
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006367 release_sock(sk);
6368
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006369 rsp.scid = cpu_to_le16(chan->dcid);
6370 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006371 rsp.result = cpu_to_le16(res);
6372 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006373 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006374 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006375
6376 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6377 res == L2CAP_CR_SUCCESS) {
6378 char buf[128];
6379 set_bit(CONF_REQ_SENT, &chan->conf_state);
6380 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6381 L2CAP_CONF_REQ,
6382 l2cap_build_conf_req(chan, buf),
6383 buf);
6384 chan->num_conf_req++;
6385 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006386 }
6387
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006388 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006389 }
6390
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006391 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006392
Linus Torvalds1da177e2005-04-16 15:20:36 -07006393 return 0;
6394}
6395
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006396int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006397{
6398 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006399 struct l2cap_hdr *hdr;
6400 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006401
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006402 /* For AMP controller do not create l2cap conn */
6403 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6404 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006405
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006406 if (!conn)
6407 conn = l2cap_conn_add(hcon, 0);
6408
6409 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006410 goto drop;
6411
6412 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6413
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006414 switch (flags) {
6415 case ACL_START:
6416 case ACL_START_NO_FLUSH:
6417 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006418 if (conn->rx_len) {
6419 BT_ERR("Unexpected start frame (len %d)", skb->len);
6420 kfree_skb(conn->rx_skb);
6421 conn->rx_skb = NULL;
6422 conn->rx_len = 0;
6423 l2cap_conn_unreliable(conn, ECOMM);
6424 }
6425
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006426 /* Start fragment always begin with Basic L2CAP header */
6427 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006428 BT_ERR("Frame is too short (len %d)", skb->len);
6429 l2cap_conn_unreliable(conn, ECOMM);
6430 goto drop;
6431 }
6432
6433 hdr = (struct l2cap_hdr *) skb->data;
6434 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6435
6436 if (len == skb->len) {
6437 /* Complete frame received */
6438 l2cap_recv_frame(conn, skb);
6439 return 0;
6440 }
6441
6442 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6443
6444 if (skb->len > len) {
6445 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006446 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006447 l2cap_conn_unreliable(conn, ECOMM);
6448 goto drop;
6449 }
6450
6451 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006452 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006453 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006454 goto drop;
6455
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006456 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006457 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006458 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006459 break;
6460
6461 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006462 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6463
6464 if (!conn->rx_len) {
6465 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6466 l2cap_conn_unreliable(conn, ECOMM);
6467 goto drop;
6468 }
6469
6470 if (skb->len > conn->rx_len) {
6471 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006472 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006473 kfree_skb(conn->rx_skb);
6474 conn->rx_skb = NULL;
6475 conn->rx_len = 0;
6476 l2cap_conn_unreliable(conn, ECOMM);
6477 goto drop;
6478 }
6479
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006480 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006481 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006482 conn->rx_len -= skb->len;
6483
6484 if (!conn->rx_len) {
6485 /* Complete frame received */
6486 l2cap_recv_frame(conn, conn->rx_skb);
6487 conn->rx_skb = NULL;
6488 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006489 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006490 }
6491
6492drop:
6493 kfree_skb(skb);
6494 return 0;
6495}
6496
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006497static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006498{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006499 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006500
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006501 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006502
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006503 list_for_each_entry(c, &chan_list, global_l) {
6504 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006505
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006506 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
6507 &bt_sk(sk)->src, &bt_sk(sk)->dst,
6508 c->state, __le16_to_cpu(c->psm),
6509 c->scid, c->dcid, c->imtu, c->omtu,
6510 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006511 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006512
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006513 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006514
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006515 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006516}
6517
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006518static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6519{
6520 return single_open(file, l2cap_debugfs_show, inode->i_private);
6521}
6522
6523static const struct file_operations l2cap_debugfs_fops = {
6524 .open = l2cap_debugfs_open,
6525 .read = seq_read,
6526 .llseek = seq_lseek,
6527 .release = single_release,
6528};
6529
6530static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006531
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006532int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006533{
6534 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006535
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006536 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006537 if (err < 0)
6538 return err;
6539
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006540 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006541 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6542 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006543 if (!l2cap_debugfs)
6544 BT_ERR("Failed to create L2CAP debug file");
6545 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006546
Linus Torvalds1da177e2005-04-16 15:20:36 -07006547 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006548}
6549
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006550void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006551{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006552 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006553 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006554}
6555
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006556module_param(disable_ertm, bool, 0644);
6557MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");