blob: 7c7e9321f1ea4263e0c51e792a14e0454d4a0e12 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
Gustavo F. Padovance5706b2010-07-13 11:57:11 -03004 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
Gustavo F. Padovan5d8868f2010-07-16 16:18:39 -03005 Copyright (C) 2010 Google Inc.
Gustavo F. Padovan590051d2011-12-18 13:39:33 -02006 Copyright (C) 2011 ProFUSION Embedded Systems
Mat Martineau422e9252012-04-27 16:50:55 -07007 Copyright (c) 2012 Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07008
9 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License version 2 as
13 published by the Free Software Foundation;
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
18 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090019 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090024 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
25 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 SOFTWARE IS DISCLAIMED.
27*/
28
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020029/* Bluetooth L2CAP core. */
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/module.h>
32
Marcel Holtmannaef7d972010-03-21 05:27:45 +010033#include <linux/debugfs.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030034#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#include <net/bluetooth/bluetooth.h>
37#include <net/bluetooth/hci_core.h>
38#include <net/bluetooth/l2cap.h>
Anderson Brigliab501d6a2011-06-07 18:46:31 -030039#include <net/bluetooth/smp.h>
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +030040#include <net/bluetooth/a2mp.h>
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +020041#include <net/bluetooth/amp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
Mat Martineaud1de6d42012-05-17 20:53:55 -070043bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020044
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070045static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Mat Martineau50a147c2011-11-02 16:18:34 -070046static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070047
Johannes Bergb5ad8b72011-06-01 08:54:45 +020048static LIST_HEAD(chan_list);
49static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Linus Torvalds1da177e2005-04-16 15:20:36 -070051static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010052 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030053static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010054 void *data);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -030055static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +020056static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Gustavo Padovand6603662012-05-21 13:58:22 -030058static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010059 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070060
Marcel Holtmann01394182006-07-03 10:02:46 +020061/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030062
Gustavo Padovan2d792812012-10-06 10:07:01 +010063static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
64 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020065{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020066 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030067
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020068 list_for_each_entry(c, &conn->chan_l, list) {
69 if (c->dcid == cid)
70 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020071 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020072 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020073}
74
Gustavo Padovan2d792812012-10-06 10:07:01 +010075static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
76 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020077{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020078 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030079
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020080 list_for_each_entry(c, &conn->chan_l, list) {
81 if (c->scid == cid)
82 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020083 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020084 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020085}
86
87/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -070088 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +010089static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
90 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020091{
Gustavo F. Padovan48454072011-03-25 00:22:30 -030092 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030093
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020094 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030095 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -070096 if (c)
97 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020098 mutex_unlock(&conn->chan_lock);
99
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300100 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200101}
102
Mat Martineaub1a130b2012-10-23 15:24:09 -0700103/* Find channel with given DCID.
104 * Returns locked channel.
105 */
106static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
107 u16 cid)
108{
109 struct l2cap_chan *c;
110
111 mutex_lock(&conn->chan_lock);
112 c = __l2cap_get_chan_by_dcid(conn, cid);
113 if (c)
114 l2cap_chan_lock(c);
115 mutex_unlock(&conn->chan_lock);
116
117 return c;
118}
119
Gustavo Padovan2d792812012-10-06 10:07:01 +0100120static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
121 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200122{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200123 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300124
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200125 list_for_each_entry(c, &conn->chan_l, list) {
126 if (c->ident == ident)
127 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200128 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200129 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200130}
131
Mat Martineau5b155ef2012-10-23 15:24:14 -0700132static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
133 u8 ident)
134{
135 struct l2cap_chan *c;
136
137 mutex_lock(&conn->chan_lock);
138 c = __l2cap_get_chan_by_ident(conn, ident);
139 if (c)
140 l2cap_chan_lock(c);
141 mutex_unlock(&conn->chan_lock);
142
143 return c;
144}
145
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300146static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300147{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300148 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300149
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300150 list_for_each_entry(c, &chan_list, global_l) {
151 if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100152 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300153 }
Szymon Janc250938c2011-11-16 09:32:22 +0100154 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300155}
156
157int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
158{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300159 int err;
160
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200161 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300162
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300163 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300164 err = -EADDRINUSE;
165 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300166 }
167
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300168 if (psm) {
169 chan->psm = psm;
170 chan->sport = psm;
171 err = 0;
172 } else {
173 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300174
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300175 err = -EINVAL;
176 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300177 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300178 chan->psm = cpu_to_le16(p);
179 chan->sport = cpu_to_le16(p);
180 err = 0;
181 break;
182 }
183 }
184
185done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200186 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300187 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300188}
189
190int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
191{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200192 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300193
194 chan->scid = scid;
195
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200196 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300197
198 return 0;
199}
200
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300201static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200202{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300203 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200204
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300205 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300206 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200207 return cid;
208 }
209
210 return 0;
211}
212
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200213static void __l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300214{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200215 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100216 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200217
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300218 chan->state = state;
Gustavo Padovan80b98022012-05-27 22:27:51 -0300219 chan->ops->state_change(chan, state);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300220}
221
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200222static void l2cap_state_change(struct l2cap_chan *chan, int state)
223{
224 struct sock *sk = chan->sk;
225
226 lock_sock(sk);
227 __l2cap_state_change(chan, state);
228 release_sock(sk);
229}
230
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200231static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
232{
233 struct sock *sk = chan->sk;
234
235 sk->sk_err = err;
236}
237
238static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
239{
240 struct sock *sk = chan->sk;
241
242 lock_sock(sk);
243 __l2cap_chan_set_err(chan, err);
244 release_sock(sk);
245}
246
Mat Martineau4239d162012-05-17 20:53:49 -0700247static void __set_retrans_timer(struct l2cap_chan *chan)
248{
249 if (!delayed_work_pending(&chan->monitor_timer) &&
250 chan->retrans_timeout) {
251 l2cap_set_timer(chan, &chan->retrans_timer,
252 msecs_to_jiffies(chan->retrans_timeout));
253 }
254}
255
256static void __set_monitor_timer(struct l2cap_chan *chan)
257{
258 __clear_retrans_timer(chan);
259 if (chan->monitor_timeout) {
260 l2cap_set_timer(chan, &chan->monitor_timer,
261 msecs_to_jiffies(chan->monitor_timeout));
262 }
263}
264
Mat Martineau608bcc62012-05-17 20:53:32 -0700265static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
266 u16 seq)
267{
268 struct sk_buff *skb;
269
270 skb_queue_walk(head, skb) {
271 if (bt_cb(skb)->control.txseq == seq)
272 return skb;
273 }
274
275 return NULL;
276}
277
Mat Martineau3c588192012-04-11 10:48:42 -0700278/* ---- L2CAP sequence number lists ---- */
279
280/* For ERTM, ordered lists of sequence numbers must be tracked for
281 * SREJ requests that are received and for frames that are to be
282 * retransmitted. These seq_list functions implement a singly-linked
283 * list in an array, where membership in the list can also be checked
284 * in constant time. Items can also be added to the tail of the list
285 * and removed from the head in constant time, without further memory
286 * allocs or frees.
287 */
288
289static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
290{
291 size_t alloc_size, i;
292
293 /* Allocated size is a power of 2 to map sequence numbers
294 * (which may be up to 14 bits) in to a smaller array that is
295 * sized for the negotiated ERTM transmit windows.
296 */
297 alloc_size = roundup_pow_of_two(size);
298
299 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
300 if (!seq_list->list)
301 return -ENOMEM;
302
303 seq_list->mask = alloc_size - 1;
304 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
305 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
306 for (i = 0; i < alloc_size; i++)
307 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
308
309 return 0;
310}
311
312static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
313{
314 kfree(seq_list->list);
315}
316
317static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
318 u16 seq)
319{
320 /* Constant-time check for list membership */
321 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
322}
323
324static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
325{
326 u16 mask = seq_list->mask;
327
328 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
329 /* In case someone tries to pop the head of an empty list */
330 return L2CAP_SEQ_LIST_CLEAR;
331 } else if (seq_list->head == seq) {
332 /* Head can be removed in constant time */
333 seq_list->head = seq_list->list[seq & mask];
334 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
335
336 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
337 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
338 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
339 }
340 } else {
341 /* Walk the list to find the sequence number */
342 u16 prev = seq_list->head;
343 while (seq_list->list[prev & mask] != seq) {
344 prev = seq_list->list[prev & mask];
345 if (prev == L2CAP_SEQ_LIST_TAIL)
346 return L2CAP_SEQ_LIST_CLEAR;
347 }
348
349 /* Unlink the number from the list and clear it */
350 seq_list->list[prev & mask] = seq_list->list[seq & mask];
351 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
352 if (seq_list->tail == seq)
353 seq_list->tail = prev;
354 }
355 return seq;
356}
357
358static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
359{
360 /* Remove the head in constant time */
361 return l2cap_seq_list_remove(seq_list, seq_list->head);
362}
363
364static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
365{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300366 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700367
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300368 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
369 return;
370
371 for (i = 0; i <= seq_list->mask; i++)
372 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
373
374 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
375 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700376}
377
378static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
379{
380 u16 mask = seq_list->mask;
381
382 /* All appends happen in constant time */
383
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300384 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
385 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700386
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300387 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
388 seq_list->head = seq;
389 else
390 seq_list->list[seq_list->tail & mask] = seq;
391
392 seq_list->tail = seq;
393 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700394}
395
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300396static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300397{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300398 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100399 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200400 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300401 int reason;
402
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200403 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300404
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200405 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200406 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300407
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300408 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300409 reason = ECONNREFUSED;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300410 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100411 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300412 reason = ECONNREFUSED;
413 else
414 reason = ETIMEDOUT;
415
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300416 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300417
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200418 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300419
Gustavo Padovan80b98022012-05-27 22:27:51 -0300420 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200421 mutex_unlock(&conn->chan_lock);
422
Ulisses Furquim371fd832011-12-21 20:02:36 -0200423 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300424}
425
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300426struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200427{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300428 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200429
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300430 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
431 if (!chan)
432 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200433
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200434 mutex_init(&chan->lock);
435
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200436 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300437 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200438 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300439
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300440 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300441
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300442 chan->state = BT_OPEN;
443
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530444 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300445
Mat Martineau28270112012-05-17 21:14:09 -0700446 /* This flag is cleared in l2cap_chan_ready() */
447 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
448
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300449 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100450
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300451 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200452}
453
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530454static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300455{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530456 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
457
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530458 BT_DBG("chan %p", chan);
459
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200460 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300461 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200462 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300463
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530464 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300465}
466
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530467void l2cap_chan_hold(struct l2cap_chan *c)
468{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530469 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530470
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530471 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530472}
473
474void l2cap_chan_put(struct l2cap_chan *c)
475{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530476 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530477
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530478 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530479}
480
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300481void l2cap_chan_set_defaults(struct l2cap_chan *chan)
482{
483 chan->fcs = L2CAP_FCS_CRC16;
484 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
485 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
486 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700487 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300488 chan->sec_level = BT_SECURITY_LOW;
489
490 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
491}
492
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300493void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200494{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300495 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200496 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200497
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200498 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100499
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300500 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200501
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200502 switch (chan->chan_type) {
503 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300504 if (conn->hcon->type == LE_LINK) {
505 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300506 chan->omtu = L2CAP_DEFAULT_MTU;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300507 chan->scid = L2CAP_CID_LE_DATA;
508 chan->dcid = L2CAP_CID_LE_DATA;
Ville Tervob62f3282011-02-10 22:38:50 -0300509 } else {
510 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300511 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300512 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300513 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200514 break;
515
516 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200517 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300518 chan->scid = L2CAP_CID_CONN_LESS;
519 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300520 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200521 break;
522
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300523 case L2CAP_CHAN_CONN_FIX_A2MP:
524 chan->scid = L2CAP_CID_A2MP;
525 chan->dcid = L2CAP_CID_A2MP;
526 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
527 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
528 break;
529
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200530 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200531 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300532 chan->scid = L2CAP_CID_SIGNALING;
533 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300534 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200535 }
536
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300537 chan->local_id = L2CAP_BESTEFFORT_ID;
538 chan->local_stype = L2CAP_SERV_BESTEFFORT;
539 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
540 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
541 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300542 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300543
Ulisses Furquim371fd832011-12-21 20:02:36 -0200544 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300545
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200546 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200547}
548
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300549void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200550{
551 mutex_lock(&conn->chan_lock);
552 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200553 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200554}
555
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300556void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200557{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300558 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200559
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300560 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200561
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300562 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200563
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900564 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300565 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300566 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200567 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200568
Ulisses Furquim371fd832011-12-21 20:02:36 -0200569 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300570
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300571 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300572
573 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
574 hci_conn_put(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300575
576 if (mgr && mgr->bredr_chan == chan)
577 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200578 }
579
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200580 if (chan->hs_hchan) {
581 struct hci_chan *hs_hchan = chan->hs_hchan;
582
583 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
584 amp_disconnect_logical_link(hs_hchan);
585 }
586
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100587 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200588
Mat Martineau28270112012-05-17 21:14:09 -0700589 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300590 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300591
Gustavo Padovanee556f62012-05-18 20:22:38 -0300592 switch(chan->mode) {
593 case L2CAP_MODE_BASIC:
594 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300595
Gustavo Padovanee556f62012-05-18 20:22:38 -0300596 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300597 __clear_retrans_timer(chan);
598 __clear_monitor_timer(chan);
599 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300600
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300601 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300602
Mat Martineau3c588192012-04-11 10:48:42 -0700603 l2cap_seq_list_free(&chan->srej_list);
604 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300605
606 /* fall through */
607
608 case L2CAP_MODE_STREAMING:
609 skb_queue_purge(&chan->tx_q);
610 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300611 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300612
613 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200614}
615
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300616void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300617{
618 struct l2cap_conn *conn = chan->conn;
619 struct sock *sk = chan->sk;
620
Gustavo Padovan2d792812012-10-06 10:07:01 +0100621 BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state),
622 sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300623
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300624 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300625 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100626 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300627 break;
628
629 case BT_CONNECTED:
630 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300631 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100632 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300633 __set_chan_timer(chan, sk->sk_sndtimeo);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200634 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300635 } else
636 l2cap_chan_del(chan, reason);
637 break;
638
639 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300640 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100641 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300642 struct l2cap_conn_rsp rsp;
643 __u16 result;
644
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300645 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300646 result = L2CAP_CR_SEC_BLOCK;
647 else
648 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300649 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300650
651 rsp.scid = cpu_to_le16(chan->dcid);
652 rsp.dcid = cpu_to_le16(chan->scid);
653 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300654 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300655 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100656 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300657 }
658
659 l2cap_chan_del(chan, reason);
660 break;
661
662 case BT_CONNECT:
663 case BT_DISCONN:
664 l2cap_chan_del(chan, reason);
665 break;
666
667 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100668 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300669 break;
670 }
671}
672
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300673static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530674{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300675 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300676 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530677 case BT_SECURITY_HIGH:
678 return HCI_AT_DEDICATED_BONDING_MITM;
679 case BT_SECURITY_MEDIUM:
680 return HCI_AT_DEDICATED_BONDING;
681 default:
682 return HCI_AT_NO_BONDING;
683 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300684 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300685 if (chan->sec_level == BT_SECURITY_LOW)
686 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530687
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300688 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530689 return HCI_AT_NO_BONDING_MITM;
690 else
691 return HCI_AT_NO_BONDING;
692 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300693 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530694 case BT_SECURITY_HIGH:
695 return HCI_AT_GENERAL_BONDING_MITM;
696 case BT_SECURITY_MEDIUM:
697 return HCI_AT_GENERAL_BONDING;
698 default:
699 return HCI_AT_NO_BONDING;
700 }
701 }
702}
703
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200704/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200705int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200706{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300707 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100708 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200709
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300710 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100711
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300712 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200713}
714
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200715static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200716{
717 u8 id;
718
719 /* Get next available identificator.
720 * 1 - 128 are used by kernel.
721 * 129 - 199 are reserved.
722 * 200 - 254 are used by utilities like l2ping, etc.
723 */
724
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200725 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200726
727 if (++conn->tx_ident > 128)
728 conn->tx_ident = 1;
729
730 id = conn->tx_ident;
731
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200732 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200733
734 return id;
735}
736
Gustavo Padovan2d792812012-10-06 10:07:01 +0100737static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
738 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200739{
740 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200741 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200742
743 BT_DBG("code 0x%2.2x", code);
744
745 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300746 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200747
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200748 if (lmp_no_flush_capable(conn->hcon->hdev))
749 flags = ACL_START_NO_FLUSH;
750 else
751 flags = ACL_START;
752
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700753 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200754 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700755
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200756 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200757}
758
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700759static bool __chan_is_moving(struct l2cap_chan *chan)
760{
761 return chan->move_state != L2CAP_MOVE_STABLE &&
762 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
763}
764
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200765static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
766{
767 struct hci_conn *hcon = chan->conn->hcon;
768 u16 flags;
769
770 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100771 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200772
Mat Martineaud5f8a752012-10-23 15:24:18 -0700773 if (chan->hs_hcon && !__chan_is_moving(chan)) {
774 if (chan->hs_hchan)
775 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
776 else
777 kfree_skb(skb);
778
779 return;
780 }
781
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200782 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100783 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200784 flags = ACL_START_NO_FLUSH;
785 else
786 flags = ACL_START;
787
788 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
789 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790}
791
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700792static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
793{
794 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
795 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
796
797 if (enh & L2CAP_CTRL_FRAME_TYPE) {
798 /* S-Frame */
799 control->sframe = 1;
800 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
801 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
802
803 control->sar = 0;
804 control->txseq = 0;
805 } else {
806 /* I-Frame */
807 control->sframe = 0;
808 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
809 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
810
811 control->poll = 0;
812 control->super = 0;
813 }
814}
815
816static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
817{
818 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
819 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
820
821 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
822 /* S-Frame */
823 control->sframe = 1;
824 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
825 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
826
827 control->sar = 0;
828 control->txseq = 0;
829 } else {
830 /* I-Frame */
831 control->sframe = 0;
832 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
833 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
834
835 control->poll = 0;
836 control->super = 0;
837 }
838}
839
840static inline void __unpack_control(struct l2cap_chan *chan,
841 struct sk_buff *skb)
842{
843 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
844 __unpack_extended_control(get_unaligned_le32(skb->data),
845 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700846 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700847 } else {
848 __unpack_enhanced_control(get_unaligned_le16(skb->data),
849 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700850 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700851 }
852}
853
854static u32 __pack_extended_control(struct l2cap_ctrl *control)
855{
856 u32 packed;
857
858 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
859 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
860
861 if (control->sframe) {
862 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
863 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
864 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
865 } else {
866 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
867 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
868 }
869
870 return packed;
871}
872
873static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
874{
875 u16 packed;
876
877 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
878 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
879
880 if (control->sframe) {
881 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
882 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
883 packed |= L2CAP_CTRL_FRAME_TYPE;
884 } else {
885 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
886 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
887 }
888
889 return packed;
890}
891
892static inline void __pack_control(struct l2cap_chan *chan,
893 struct l2cap_ctrl *control,
894 struct sk_buff *skb)
895{
896 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
897 put_unaligned_le32(__pack_extended_control(control),
898 skb->data + L2CAP_HDR_SIZE);
899 } else {
900 put_unaligned_le16(__pack_enhanced_control(control),
901 skb->data + L2CAP_HDR_SIZE);
902 }
903}
904
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300905static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
906{
907 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
908 return L2CAP_EXT_HDR_SIZE;
909 else
910 return L2CAP_ENH_HDR_SIZE;
911}
912
Mat Martineaua67d7f62012-05-17 20:53:35 -0700913static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
914 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300915{
916 struct sk_buff *skb;
917 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300918 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300919
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300920 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300921 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300922
Mat Martineaua67d7f62012-05-17 20:53:35 -0700923 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300924
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300925 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700926 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300927
928 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300929 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300930 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300931
Mat Martineaua67d7f62012-05-17 20:53:35 -0700932 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
933 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
934 else
935 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300936
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300937 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700938 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300939 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300940 }
941
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200942 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700943 return skb;
944}
945
946static void l2cap_send_sframe(struct l2cap_chan *chan,
947 struct l2cap_ctrl *control)
948{
949 struct sk_buff *skb;
950 u32 control_field;
951
952 BT_DBG("chan %p, control %p", chan, control);
953
954 if (!control->sframe)
955 return;
956
Mat Martineaub99e13a2012-10-23 15:24:19 -0700957 if (__chan_is_moving(chan))
958 return;
959
Mat Martineaua67d7f62012-05-17 20:53:35 -0700960 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
961 !control->poll)
962 control->final = 1;
963
964 if (control->super == L2CAP_SUPER_RR)
965 clear_bit(CONN_RNR_SENT, &chan->conn_state);
966 else if (control->super == L2CAP_SUPER_RNR)
967 set_bit(CONN_RNR_SENT, &chan->conn_state);
968
969 if (control->super != L2CAP_SUPER_SREJ) {
970 chan->last_acked_seq = control->reqseq;
971 __clear_ack_timer(chan);
972 }
973
974 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
975 control->final, control->poll, control->super);
976
977 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
978 control_field = __pack_extended_control(control);
979 else
980 control_field = __pack_enhanced_control(control);
981
982 skb = l2cap_create_sframe_pdu(chan, control_field);
983 if (!IS_ERR(skb))
984 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300985}
986
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700987static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300988{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700989 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300990
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700991 BT_DBG("chan %p, poll %d", chan, poll);
992
993 memset(&control, 0, sizeof(control));
994 control.sframe = 1;
995 control.poll = poll;
996
997 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
998 control.super = L2CAP_SUPER_RNR;
999 else
1000 control.super = L2CAP_SUPER_RR;
1001
1002 control.reqseq = chan->buffer_seq;
1003 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001004}
1005
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001006static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001007{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001008 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001009}
1010
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001011static bool __amp_capable(struct l2cap_chan *chan)
1012{
1013 struct l2cap_conn *conn = chan->conn;
1014
1015 if (enable_hs &&
Andrei Emeltchenko5d054162012-11-29 17:46:05 +02001016 hci_amp_capable() &&
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001017 chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED &&
1018 conn->fixed_chan_mask & L2CAP_FC_A2MP)
1019 return true;
1020 else
1021 return false;
1022}
1023
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001024static bool l2cap_check_efs(struct l2cap_chan *chan)
1025{
1026 /* Check EFS parameters */
1027 return true;
1028}
1029
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001030void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001031{
1032 struct l2cap_conn *conn = chan->conn;
1033 struct l2cap_conn_req req;
1034
1035 req.scid = cpu_to_le16(chan->scid);
1036 req.psm = chan->psm;
1037
1038 chan->ident = l2cap_get_ident(conn);
1039
1040 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1041
1042 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1043}
1044
Mat Martineau8eb200b2012-10-23 15:24:17 -07001045static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1046{
1047 struct l2cap_create_chan_req req;
1048 req.scid = cpu_to_le16(chan->scid);
1049 req.psm = chan->psm;
1050 req.amp_id = amp_id;
1051
1052 chan->ident = l2cap_get_ident(chan->conn);
1053
1054 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1055 sizeof(req), &req);
1056}
1057
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001058static void l2cap_move_setup(struct l2cap_chan *chan)
1059{
1060 struct sk_buff *skb;
1061
1062 BT_DBG("chan %p", chan);
1063
1064 if (chan->mode != L2CAP_MODE_ERTM)
1065 return;
1066
1067 __clear_retrans_timer(chan);
1068 __clear_monitor_timer(chan);
1069 __clear_ack_timer(chan);
1070
1071 chan->retry_count = 0;
1072 skb_queue_walk(&chan->tx_q, skb) {
1073 if (bt_cb(skb)->control.retries)
1074 bt_cb(skb)->control.retries = 1;
1075 else
1076 break;
1077 }
1078
1079 chan->expected_tx_seq = chan->buffer_seq;
1080
1081 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1082 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1083 l2cap_seq_list_clear(&chan->retrans_list);
1084 l2cap_seq_list_clear(&chan->srej_list);
1085 skb_queue_purge(&chan->srej_q);
1086
1087 chan->tx_state = L2CAP_TX_STATE_XMIT;
1088 chan->rx_state = L2CAP_RX_STATE_MOVE;
1089
1090 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1091}
1092
Mat Martineau5f3847a2012-10-23 15:24:12 -07001093static void l2cap_move_done(struct l2cap_chan *chan)
1094{
1095 u8 move_role = chan->move_role;
1096 BT_DBG("chan %p", chan);
1097
1098 chan->move_state = L2CAP_MOVE_STABLE;
1099 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1100
1101 if (chan->mode != L2CAP_MODE_ERTM)
1102 return;
1103
1104 switch (move_role) {
1105 case L2CAP_MOVE_ROLE_INITIATOR:
1106 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1107 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1108 break;
1109 case L2CAP_MOVE_ROLE_RESPONDER:
1110 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1111 break;
1112 }
1113}
1114
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001115static void l2cap_chan_ready(struct l2cap_chan *chan)
1116{
Mat Martineau28270112012-05-17 21:14:09 -07001117 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001118 chan->conf_state = 0;
1119 __clear_chan_timer(chan);
1120
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001121 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001122
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001123 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001124}
1125
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001126static void l2cap_start_connection(struct l2cap_chan *chan)
1127{
1128 if (__amp_capable(chan)) {
1129 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1130 a2mp_discover_amp(chan);
1131 } else {
1132 l2cap_send_conn_req(chan);
1133 }
1134}
1135
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001136static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001137{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001138 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001139
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001140 if (conn->hcon->type == LE_LINK) {
1141 l2cap_chan_ready(chan);
1142 return;
1143 }
1144
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001145 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001146 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1147 return;
1148
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001149 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001150 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001151 l2cap_start_connection(chan);
1152 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001153 } else {
1154 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001155 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001156
1157 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1158 conn->info_ident = l2cap_get_ident(conn);
1159
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001160 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001161
Gustavo Padovan2d792812012-10-06 10:07:01 +01001162 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1163 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001164 }
1165}
1166
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001167static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1168{
1169 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001170 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001171 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1172
1173 switch (mode) {
1174 case L2CAP_MODE_ERTM:
1175 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1176 case L2CAP_MODE_STREAMING:
1177 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1178 default:
1179 return 0x00;
1180 }
1181}
1182
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001183static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001184{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001185 struct sock *sk = chan->sk;
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001186 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001187 struct l2cap_disconn_req req;
1188
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001189 if (!conn)
1190 return;
1191
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001192 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001193 __clear_retrans_timer(chan);
1194 __clear_monitor_timer(chan);
1195 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001196 }
1197
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001198 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001199 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001200 return;
1201 }
1202
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001203 req.dcid = cpu_to_le16(chan->dcid);
1204 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001205 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1206 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001207
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001208 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001209 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001210 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001211 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001212}
1213
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001215static void l2cap_conn_start(struct l2cap_conn *conn)
1216{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001217 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001218
1219 BT_DBG("conn %p", conn);
1220
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001221 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001222
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001223 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001224 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001225
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001226 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001227
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001228 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001229 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001230 continue;
1231 }
1232
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001233 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001234 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001235 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001236 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001237 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001238 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001239
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001240 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001241 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001242 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001243 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001244 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001245 continue;
1246 }
1247
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001248 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001249
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001250 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001251 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001252 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001253 rsp.scid = cpu_to_le16(chan->dcid);
1254 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001255
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001256 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001257 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001258 if (test_bit(BT_SK_DEFER_SETUP,
1259 &bt_sk(sk)->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001260 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1261 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001262 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001263
1264 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001265 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001266 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1267 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001268 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001269 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001270 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001271 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1272 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001273 }
1274
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001275 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001276 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001277
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001278 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001279 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001280 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001281 continue;
1282 }
1283
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001284 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001285 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001286 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001287 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001288 }
1289
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001290 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001291 }
1292
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001293 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001294}
1295
Ido Yarivc2287682012-04-20 15:46:07 -03001296/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001297 * Returns closest match, locked.
1298 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001299static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001300 bdaddr_t *src,
1301 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001302{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001303 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001304
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001305 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001306
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001307 list_for_each_entry(c, &chan_list, global_l) {
1308 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001309
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001310 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001311 continue;
1312
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001313 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001314 int src_match, dst_match;
1315 int src_any, dst_any;
1316
Ville Tervob62f3282011-02-10 22:38:50 -03001317 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001318 src_match = !bacmp(&bt_sk(sk)->src, src);
1319 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1320 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001321 read_unlock(&chan_list_lock);
1322 return c;
1323 }
Ville Tervob62f3282011-02-10 22:38:50 -03001324
1325 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001326 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1327 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1328 if ((src_match && dst_any) || (src_any && dst_match) ||
1329 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001330 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001331 }
1332 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001333
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001334 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001335
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001336 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001337}
1338
1339static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1340{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001341 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001342 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001343
1344 BT_DBG("");
1345
1346 /* Check if we have socket listening on cid */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001347 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
Ido Yarivc2287682012-04-20 15:46:07 -03001348 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001349 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001350 return;
1351
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001352 parent = pchan->sk;
1353
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001354 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001355
Gustavo Padovan80b98022012-05-27 22:27:51 -03001356 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001357 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001358 goto clean;
1359
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001360 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001361
Ville Tervob62f3282011-02-10 22:38:50 -03001362 hci_conn_hold(conn->hcon);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001363 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
Ville Tervob62f3282011-02-10 22:38:50 -03001364
Ville Tervob62f3282011-02-10 22:38:50 -03001365 bacpy(&bt_sk(sk)->src, conn->src);
1366 bacpy(&bt_sk(sk)->dst, conn->dst);
1367
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001368 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001369
Gustavo Padovan6754e0d2012-05-25 09:30:56 -03001370 l2cap_chan_ready(chan);
Ville Tervob62f3282011-02-10 22:38:50 -03001371
Ville Tervob62f3282011-02-10 22:38:50 -03001372clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001373 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001374}
1375
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001376static void l2cap_conn_ready(struct l2cap_conn *conn)
1377{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001378 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001379 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001380
1381 BT_DBG("conn %p", conn);
1382
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001383 if (!hcon->out && hcon->type == LE_LINK)
Ville Tervob62f3282011-02-10 22:38:50 -03001384 l2cap_le_conn_ready(conn);
1385
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001386 if (hcon->out && hcon->type == LE_LINK)
1387 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001388
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001389 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001390
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001391 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001392
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001393 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001394
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001395 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1396 l2cap_chan_unlock(chan);
1397 continue;
1398 }
1399
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001400 if (hcon->type == LE_LINK) {
1401 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001402 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001403
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001404 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001405 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001406 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001407 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001408 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001409 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001410 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001411
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001412 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001413 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001414
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001415 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001416 }
1417
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001418 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001419}
1420
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001421/* Notify sockets that we cannot guaranty reliability anymore */
1422static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1423{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001424 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001425
1426 BT_DBG("conn %p", conn);
1427
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001428 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001429
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001430 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001431 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001432 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001433 }
1434
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001435 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001436}
1437
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001438static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001439{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001440 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001441 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001442
Marcel Holtmann984947d2009-02-06 23:35:19 +01001443 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001444 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001445
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001446 l2cap_conn_start(conn);
1447}
1448
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001449static void l2cap_conn_del(struct hci_conn *hcon, int err)
1450{
1451 struct l2cap_conn *conn = hcon->l2cap_data;
1452 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001453
1454 if (!conn)
1455 return;
1456
1457 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1458
1459 kfree_skb(conn->rx_skb);
1460
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001461 mutex_lock(&conn->chan_lock);
1462
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001463 /* Kill channels */
1464 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001465 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001466 l2cap_chan_lock(chan);
1467
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001468 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001469
1470 l2cap_chan_unlock(chan);
1471
Gustavo Padovan80b98022012-05-27 22:27:51 -03001472 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001473 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001474 }
1475
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001476 mutex_unlock(&conn->chan_lock);
1477
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001478 hci_chan_del(conn->hchan);
1479
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001480 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001481 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001482
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001483 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001484 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001485 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001486 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001487
1488 hcon->l2cap_data = NULL;
1489 kfree(conn);
1490}
1491
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001492static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001493{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001494 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001495 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001496
Johan Hedbergd06cc412012-06-06 18:44:11 +08001497 BT_DBG("conn %p", conn);
1498
1499 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1500 smp_chan_destroy(conn);
1501 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1502 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001503}
1504
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1506{
Marcel Holtmann01394182006-07-03 10:02:46 +02001507 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001508 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509
Marcel Holtmann01394182006-07-03 10:02:46 +02001510 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511 return conn;
1512
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001513 hchan = hci_chan_create(hcon);
1514 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001517 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001518 if (!conn) {
1519 hci_chan_del(hchan);
1520 return NULL;
1521 }
1522
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 hcon->l2cap_data = conn;
1524 conn->hcon = hcon;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001525 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001527 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001528
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001529 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001530 case LE_LINK:
1531 if (hcon->hdev->le_mtu) {
1532 conn->mtu = hcon->hdev->le_mtu;
1533 break;
1534 }
1535 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001536 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001537 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001538 break;
1539 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001540
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 conn->src = &hcon->hdev->bdaddr;
1542 conn->dst = &hcon->dst;
1543
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001544 conn->feat_mask = 0;
1545
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001547 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001548
1549 INIT_LIST_HEAD(&conn->chan_l);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001551 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001552 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001553 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001554 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001555
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001556 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001557
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558 return conn;
1559}
1560
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562
Ido Yarivc2287682012-04-20 15:46:07 -03001563/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564 * Returns closest match.
1565 */
Ido Yarivc2287682012-04-20 15:46:07 -03001566static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1567 bdaddr_t *src,
1568 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001570 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001572 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001573
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001574 list_for_each_entry(c, &chan_list, global_l) {
1575 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001576
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001577 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578 continue;
1579
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001580 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001581 int src_match, dst_match;
1582 int src_any, dst_any;
1583
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001585 src_match = !bacmp(&bt_sk(sk)->src, src);
1586 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1587 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001588 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001589 return c;
1590 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591
1592 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001593 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1594 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1595 if ((src_match && dst_any) || (src_any && dst_match) ||
1596 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001597 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 }
1599 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001601 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001602
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001603 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604}
1605
Andre Guedes8e9f9892012-04-24 21:02:55 -03001606int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1607 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001609 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 struct l2cap_conn *conn;
1612 struct hci_conn *hcon;
1613 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001614 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001615 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001617 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301618 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001620 hdev = hci_get_route(dst, src);
1621 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622 return -EHOSTUNREACH;
1623
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001624 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001626 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001627
1628 /* PSM must be odd and lsb of upper byte must be 0 */
1629 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001630 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001631 err = -EINVAL;
1632 goto done;
1633 }
1634
1635 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1636 err = -EINVAL;
1637 goto done;
1638 }
1639
1640 switch (chan->mode) {
1641 case L2CAP_MODE_BASIC:
1642 break;
1643 case L2CAP_MODE_ERTM:
1644 case L2CAP_MODE_STREAMING:
1645 if (!disable_ertm)
1646 break;
1647 /* fall through */
1648 default:
1649 err = -ENOTSUPP;
1650 goto done;
1651 }
1652
Gustavo Padovan0797e012012-05-27 22:27:54 -03001653 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001654 case BT_CONNECT:
1655 case BT_CONNECT2:
1656 case BT_CONFIG:
1657 /* Already connecting */
1658 err = 0;
1659 goto done;
1660
1661 case BT_CONNECTED:
1662 /* Already connected */
1663 err = -EISCONN;
1664 goto done;
1665
1666 case BT_OPEN:
1667 case BT_BOUND:
1668 /* Can connect */
1669 break;
1670
1671 default:
1672 err = -EBADFD;
1673 goto done;
1674 }
1675
1676 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001677 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001678 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001679 release_sock(sk);
1680
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001681 chan->psm = psm;
1682 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001684 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001685
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001686 if (chan->dcid == L2CAP_CID_LE_DATA)
Andre Guedes8e9f9892012-04-24 21:02:55 -03001687 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001688 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001689 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001690 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001691 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001692
Ville Tervo30e76272011-02-22 16:10:53 -03001693 if (IS_ERR(hcon)) {
1694 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001696 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697
1698 conn = l2cap_conn_add(hcon, 0);
1699 if (!conn) {
1700 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001701 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702 goto done;
1703 }
1704
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001705 if (hcon->type == LE_LINK) {
1706 err = 0;
1707
1708 if (!list_empty(&conn->chan_l)) {
1709 err = -EBUSY;
1710 hci_conn_put(hcon);
1711 }
1712
1713 if (err)
1714 goto done;
1715 }
1716
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 /* Update source addr of the socket */
1718 bacpy(src, conn->src);
1719
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001720 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001721 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001722 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001723
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001724 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001725 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726
1727 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001728 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001729 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001730 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001731 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001732 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001733 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734 }
1735
Ville Tervo30e76272011-02-22 16:10:53 -03001736 err = 0;
1737
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001739 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001740 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 hci_dev_put(hdev);
1742 return err;
1743}
1744
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001745int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001746{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001747 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001748 DECLARE_WAITQUEUE(wait, current);
1749 int err = 0;
1750 int timeo = HZ/5;
1751
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001752 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001753 set_current_state(TASK_INTERRUPTIBLE);
1754 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001755 if (!timeo)
1756 timeo = HZ/5;
1757
1758 if (signal_pending(current)) {
1759 err = sock_intr_errno(timeo);
1760 break;
1761 }
1762
1763 release_sock(sk);
1764 timeo = schedule_timeout(timeo);
1765 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001766 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001767
1768 err = sock_error(sk);
1769 if (err)
1770 break;
1771 }
1772 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001773 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001774 return err;
1775}
1776
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001777static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001778{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001779 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001780 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001781
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001782 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001783
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001784 l2cap_chan_lock(chan);
1785
Mat Martineau80909e02012-05-17 20:53:50 -07001786 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001787 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001788 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001789 return;
1790 }
1791
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001792 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001793
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001794 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001795 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001796}
1797
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001798static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001799{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001800 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001801 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001802
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001803 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001804
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001805 l2cap_chan_lock(chan);
1806
Mat Martineau80909e02012-05-17 20:53:50 -07001807 if (!chan->conn) {
1808 l2cap_chan_unlock(chan);
1809 l2cap_chan_put(chan);
1810 return;
1811 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001812
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001813 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001814 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001815 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001816}
1817
Gustavo Padovand6603662012-05-21 13:58:22 -03001818static void l2cap_streaming_send(struct l2cap_chan *chan,
1819 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001820{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001821 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001822 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001823
Mat Martineau37339372012-05-17 20:53:33 -07001824 BT_DBG("chan %p, skbs %p", chan, skbs);
1825
Mat Martineaub99e13a2012-10-23 15:24:19 -07001826 if (__chan_is_moving(chan))
1827 return;
1828
Mat Martineau37339372012-05-17 20:53:33 -07001829 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1830
1831 while (!skb_queue_empty(&chan->tx_q)) {
1832
1833 skb = skb_dequeue(&chan->tx_q);
1834
1835 bt_cb(skb)->control.retries = 1;
1836 control = &bt_cb(skb)->control;
1837
1838 control->reqseq = 0;
1839 control->txseq = chan->next_tx_seq;
1840
1841 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001842
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001843 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001844 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1845 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001846 }
1847
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001848 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001849
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001850 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001851
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001852 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001853 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001854 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001855}
1856
Szymon Janc67c9e842011-07-28 16:24:33 +02001857static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001858{
1859 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001860 struct l2cap_ctrl *control;
1861 int sent = 0;
1862
1863 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001864
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001865 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001866 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001867
Mat Martineau94122bb2012-05-02 09:42:02 -07001868 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1869 return 0;
1870
Mat Martineaub99e13a2012-10-23 15:24:19 -07001871 if (__chan_is_moving(chan))
1872 return 0;
1873
Mat Martineau18a48e72012-05-17 20:53:34 -07001874 while (chan->tx_send_head &&
1875 chan->unacked_frames < chan->remote_tx_win &&
1876 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001877
Mat Martineau18a48e72012-05-17 20:53:34 -07001878 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001879
Mat Martineau18a48e72012-05-17 20:53:34 -07001880 bt_cb(skb)->control.retries = 1;
1881 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001882
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001883 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001884 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001885
Mat Martineau18a48e72012-05-17 20:53:34 -07001886 control->reqseq = chan->buffer_seq;
1887 chan->last_acked_seq = chan->buffer_seq;
1888 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001889
Mat Martineau18a48e72012-05-17 20:53:34 -07001890 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001891
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001892 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001893 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1894 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001895 }
1896
Mat Martineau18a48e72012-05-17 20:53:34 -07001897 /* Clone after data has been modified. Data is assumed to be
1898 read-only (for locking purposes) on cloned sk_buffs.
1899 */
1900 tx_skb = skb_clone(skb, GFP_KERNEL);
1901
1902 if (!tx_skb)
1903 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001904
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001905 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001906
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001907 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001908 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001909 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001910 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001911
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001912 if (skb_queue_is_last(&chan->tx_q, skb))
1913 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001914 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001915 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001916
1917 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001918 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001919 }
1920
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001921 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
1922 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07001923
1924 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001925}
1926
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001927static void l2cap_ertm_resend(struct l2cap_chan *chan)
1928{
1929 struct l2cap_ctrl control;
1930 struct sk_buff *skb;
1931 struct sk_buff *tx_skb;
1932 u16 seq;
1933
1934 BT_DBG("chan %p", chan);
1935
1936 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1937 return;
1938
Mat Martineaub99e13a2012-10-23 15:24:19 -07001939 if (__chan_is_moving(chan))
1940 return;
1941
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001942 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1943 seq = l2cap_seq_list_pop(&chan->retrans_list);
1944
1945 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1946 if (!skb) {
1947 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01001948 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001949 continue;
1950 }
1951
1952 bt_cb(skb)->control.retries++;
1953 control = bt_cb(skb)->control;
1954
1955 if (chan->max_tx != 0 &&
1956 bt_cb(skb)->control.retries > chan->max_tx) {
1957 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001958 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001959 l2cap_seq_list_clear(&chan->retrans_list);
1960 break;
1961 }
1962
1963 control.reqseq = chan->buffer_seq;
1964 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
1965 control.final = 1;
1966 else
1967 control.final = 0;
1968
1969 if (skb_cloned(skb)) {
1970 /* Cloned sk_buffs are read-only, so we need a
1971 * writeable copy
1972 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001973 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001974 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001975 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001976 }
1977
1978 if (!tx_skb) {
1979 l2cap_seq_list_clear(&chan->retrans_list);
1980 break;
1981 }
1982
1983 /* Update skb contents */
1984 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1985 put_unaligned_le32(__pack_extended_control(&control),
1986 tx_skb->data + L2CAP_HDR_SIZE);
1987 } else {
1988 put_unaligned_le16(__pack_enhanced_control(&control),
1989 tx_skb->data + L2CAP_HDR_SIZE);
1990 }
1991
1992 if (chan->fcs == L2CAP_FCS_CRC16) {
1993 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
1994 put_unaligned_le16(fcs, skb_put(tx_skb,
1995 L2CAP_FCS_SIZE));
1996 }
1997
1998 l2cap_do_send(chan, tx_skb);
1999
2000 BT_DBG("Resent txseq %d", control.txseq);
2001
2002 chan->last_acked_seq = chan->buffer_seq;
2003 }
2004}
2005
Mat Martineauf80842a2012-05-17 20:53:46 -07002006static void l2cap_retransmit(struct l2cap_chan *chan,
2007 struct l2cap_ctrl *control)
2008{
2009 BT_DBG("chan %p, control %p", chan, control);
2010
2011 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2012 l2cap_ertm_resend(chan);
2013}
2014
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002015static void l2cap_retransmit_all(struct l2cap_chan *chan,
2016 struct l2cap_ctrl *control)
2017{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002018 struct sk_buff *skb;
2019
2020 BT_DBG("chan %p, control %p", chan, control);
2021
2022 if (control->poll)
2023 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2024
2025 l2cap_seq_list_clear(&chan->retrans_list);
2026
2027 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2028 return;
2029
2030 if (chan->unacked_frames) {
2031 skb_queue_walk(&chan->tx_q, skb) {
2032 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002033 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002034 break;
2035 }
2036
2037 skb_queue_walk_from(&chan->tx_q, skb) {
2038 if (skb == chan->tx_send_head)
2039 break;
2040
2041 l2cap_seq_list_append(&chan->retrans_list,
2042 bt_cb(skb)->control.txseq);
2043 }
2044
2045 l2cap_ertm_resend(chan);
2046 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002047}
2048
Szymon Jancb17e73b2012-01-11 10:59:47 +01002049static void l2cap_send_ack(struct l2cap_chan *chan)
2050{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002051 struct l2cap_ctrl control;
2052 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2053 chan->last_acked_seq);
2054 int threshold;
2055
2056 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2057 chan, chan->last_acked_seq, chan->buffer_seq);
2058
2059 memset(&control, 0, sizeof(control));
2060 control.sframe = 1;
2061
2062 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2063 chan->rx_state == L2CAP_RX_STATE_RECV) {
2064 __clear_ack_timer(chan);
2065 control.super = L2CAP_SUPER_RNR;
2066 control.reqseq = chan->buffer_seq;
2067 l2cap_send_sframe(chan, &control);
2068 } else {
2069 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2070 l2cap_ertm_send(chan);
2071 /* If any i-frames were sent, they included an ack */
2072 if (chan->buffer_seq == chan->last_acked_seq)
2073 frames_to_ack = 0;
2074 }
2075
Mat Martineauc20f8e32012-07-10 05:47:07 -07002076 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002077 * Calculate without mul or div
2078 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002079 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002080 threshold += threshold << 1;
2081 threshold >>= 2;
2082
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002083 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002084 threshold);
2085
2086 if (frames_to_ack >= threshold) {
2087 __clear_ack_timer(chan);
2088 control.super = L2CAP_SUPER_RR;
2089 control.reqseq = chan->buffer_seq;
2090 l2cap_send_sframe(chan, &control);
2091 frames_to_ack = 0;
2092 }
2093
2094 if (frames_to_ack)
2095 __set_ack_timer(chan);
2096 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002097}
2098
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002099static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2100 struct msghdr *msg, int len,
2101 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002102{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002103 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002104 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002105 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002106
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002107 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002108 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002109
2110 sent += count;
2111 len -= count;
2112
2113 /* Continuation fragments (no L2CAP header) */
2114 frag = &skb_shinfo(skb)->frag_list;
2115 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002116 struct sk_buff *tmp;
2117
Linus Torvalds1da177e2005-04-16 15:20:36 -07002118 count = min_t(unsigned int, conn->mtu, len);
2119
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002120 tmp = chan->ops->alloc_skb(chan, count,
2121 msg->msg_flags & MSG_DONTWAIT);
2122 if (IS_ERR(tmp))
2123 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002124
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002125 *frag = tmp;
2126
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002127 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2128 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002129
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002130 (*frag)->priority = skb->priority;
2131
Linus Torvalds1da177e2005-04-16 15:20:36 -07002132 sent += count;
2133 len -= count;
2134
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002135 skb->len += (*frag)->len;
2136 skb->data_len += (*frag)->len;
2137
Linus Torvalds1da177e2005-04-16 15:20:36 -07002138 frag = &(*frag)->next;
2139 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002140
2141 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002142}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002144static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002145 struct msghdr *msg, size_t len,
2146 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002147{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002148 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002149 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002150 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002151 struct l2cap_hdr *lh;
2152
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002153 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002154
2155 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002156
2157 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002158 msg->msg_flags & MSG_DONTWAIT);
2159 if (IS_ERR(skb))
2160 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002161
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002162 skb->priority = priority;
2163
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002164 /* Create L2CAP header */
2165 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002166 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002167 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
2168 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002169
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002170 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002171 if (unlikely(err < 0)) {
2172 kfree_skb(skb);
2173 return ERR_PTR(err);
2174 }
2175 return skb;
2176}
2177
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002178static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002179 struct msghdr *msg, size_t len,
2180 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002181{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002182 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002183 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002184 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002185 struct l2cap_hdr *lh;
2186
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002187 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002188
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002189 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002190
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002191 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002192 msg->msg_flags & MSG_DONTWAIT);
2193 if (IS_ERR(skb))
2194 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002195
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002196 skb->priority = priority;
2197
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002198 /* Create L2CAP header */
2199 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002200 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002201 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002202
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002203 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002204 if (unlikely(err < 0)) {
2205 kfree_skb(skb);
2206 return ERR_PTR(err);
2207 }
2208 return skb;
2209}
2210
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002211static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002212 struct msghdr *msg, size_t len,
2213 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002214{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002215 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002216 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002217 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002218 struct l2cap_hdr *lh;
2219
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002220 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002221
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002222 if (!conn)
2223 return ERR_PTR(-ENOTCONN);
2224
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002225 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002226
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002227 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002228 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002229
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002230 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002231 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002232
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002233 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002234
2235 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002236 msg->msg_flags & MSG_DONTWAIT);
2237 if (IS_ERR(skb))
2238 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002239
2240 /* Create L2CAP header */
2241 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002242 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002243 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002244
Mat Martineau18a48e72012-05-17 20:53:34 -07002245 /* Control header is populated later */
2246 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2247 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2248 else
2249 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002250
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002251 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002252 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002253
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002254 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002255 if (unlikely(err < 0)) {
2256 kfree_skb(skb);
2257 return ERR_PTR(err);
2258 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002259
Mat Martineau18a48e72012-05-17 20:53:34 -07002260 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002261 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002262 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002263}
2264
Mat Martineau94122bb2012-05-02 09:42:02 -07002265static int l2cap_segment_sdu(struct l2cap_chan *chan,
2266 struct sk_buff_head *seg_queue,
2267 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002268{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002269 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002270 u16 sdu_len;
2271 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002272 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002273
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002274 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002275
Mat Martineau94122bb2012-05-02 09:42:02 -07002276 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2277 * so fragmented skbs are not used. The HCI layer's handling
2278 * of fragmented skbs is not compatible with ERTM's queueing.
2279 */
2280
2281 /* PDU size is derived from the HCI MTU */
2282 pdu_len = chan->conn->mtu;
2283
Mat Martineaua5495742012-10-23 15:24:21 -07002284 /* Constrain PDU size for BR/EDR connections */
2285 if (!chan->hs_hcon)
2286 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002287
2288 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002289 if (chan->fcs)
2290 pdu_len -= L2CAP_FCS_SIZE;
2291
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002292 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002293
2294 /* Remote device may have requested smaller PDUs */
2295 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2296
2297 if (len <= pdu_len) {
2298 sar = L2CAP_SAR_UNSEGMENTED;
2299 sdu_len = 0;
2300 pdu_len = len;
2301 } else {
2302 sar = L2CAP_SAR_START;
2303 sdu_len = len;
2304 pdu_len -= L2CAP_SDULEN_SIZE;
2305 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002306
2307 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002308 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002309
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002310 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002311 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002312 return PTR_ERR(skb);
2313 }
2314
Mat Martineau94122bb2012-05-02 09:42:02 -07002315 bt_cb(skb)->control.sar = sar;
2316 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002317
Mat Martineau94122bb2012-05-02 09:42:02 -07002318 len -= pdu_len;
2319 if (sdu_len) {
2320 sdu_len = 0;
2321 pdu_len += L2CAP_SDULEN_SIZE;
2322 }
2323
2324 if (len <= pdu_len) {
2325 sar = L2CAP_SAR_END;
2326 pdu_len = len;
2327 } else {
2328 sar = L2CAP_SAR_CONTINUE;
2329 }
2330 }
2331
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002332 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002333}
2334
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002335int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002336 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002337{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002338 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002339 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002340 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002341
2342 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002343 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002344 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002345 if (IS_ERR(skb))
2346 return PTR_ERR(skb);
2347
2348 l2cap_do_send(chan, skb);
2349 return len;
2350 }
2351
2352 switch (chan->mode) {
2353 case L2CAP_MODE_BASIC:
2354 /* Check outgoing MTU */
2355 if (len > chan->omtu)
2356 return -EMSGSIZE;
2357
2358 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002359 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002360 if (IS_ERR(skb))
2361 return PTR_ERR(skb);
2362
2363 l2cap_do_send(chan, skb);
2364 err = len;
2365 break;
2366
2367 case L2CAP_MODE_ERTM:
2368 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002369 /* Check outgoing MTU */
2370 if (len > chan->omtu) {
2371 err = -EMSGSIZE;
2372 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002373 }
2374
Mat Martineau94122bb2012-05-02 09:42:02 -07002375 __skb_queue_head_init(&seg_queue);
2376
2377 /* Do segmentation before calling in to the state machine,
2378 * since it's possible to block while waiting for memory
2379 * allocation.
2380 */
2381 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2382
2383 /* The channel could have been closed while segmenting,
2384 * check that it is still connected.
2385 */
2386 if (chan->state != BT_CONNECTED) {
2387 __skb_queue_purge(&seg_queue);
2388 err = -ENOTCONN;
2389 }
2390
2391 if (err)
2392 break;
2393
Mat Martineau37339372012-05-17 20:53:33 -07002394 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002395 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002396 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002397 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002398
Gustavo Padovand6603662012-05-21 13:58:22 -03002399 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002400
Mat Martineau94122bb2012-05-02 09:42:02 -07002401 /* If the skbs were not queued for sending, they'll still be in
2402 * seg_queue and need to be purged.
2403 */
2404 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002405 break;
2406
2407 default:
2408 BT_DBG("bad state %1.1x", chan->mode);
2409 err = -EBADFD;
2410 }
2411
2412 return err;
2413}
2414
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002415static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2416{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002417 struct l2cap_ctrl control;
2418 u16 seq;
2419
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002420 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002421
2422 memset(&control, 0, sizeof(control));
2423 control.sframe = 1;
2424 control.super = L2CAP_SUPER_SREJ;
2425
2426 for (seq = chan->expected_tx_seq; seq != txseq;
2427 seq = __next_seq(chan, seq)) {
2428 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2429 control.reqseq = seq;
2430 l2cap_send_sframe(chan, &control);
2431 l2cap_seq_list_append(&chan->srej_list, seq);
2432 }
2433 }
2434
2435 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002436}
2437
2438static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2439{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002440 struct l2cap_ctrl control;
2441
2442 BT_DBG("chan %p", chan);
2443
2444 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2445 return;
2446
2447 memset(&control, 0, sizeof(control));
2448 control.sframe = 1;
2449 control.super = L2CAP_SUPER_SREJ;
2450 control.reqseq = chan->srej_list.tail;
2451 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002452}
2453
2454static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2455{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002456 struct l2cap_ctrl control;
2457 u16 initial_head;
2458 u16 seq;
2459
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002460 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002461
2462 memset(&control, 0, sizeof(control));
2463 control.sframe = 1;
2464 control.super = L2CAP_SUPER_SREJ;
2465
2466 /* Capture initial list head to allow only one pass through the list. */
2467 initial_head = chan->srej_list.head;
2468
2469 do {
2470 seq = l2cap_seq_list_pop(&chan->srej_list);
2471 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2472 break;
2473
2474 control.reqseq = seq;
2475 l2cap_send_sframe(chan, &control);
2476 l2cap_seq_list_append(&chan->srej_list, seq);
2477 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002478}
2479
Mat Martineau608bcc62012-05-17 20:53:32 -07002480static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2481{
2482 struct sk_buff *acked_skb;
2483 u16 ackseq;
2484
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002485 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002486
2487 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2488 return;
2489
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002490 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002491 chan->expected_ack_seq, chan->unacked_frames);
2492
2493 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2494 ackseq = __next_seq(chan, ackseq)) {
2495
2496 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2497 if (acked_skb) {
2498 skb_unlink(acked_skb, &chan->tx_q);
2499 kfree_skb(acked_skb);
2500 chan->unacked_frames--;
2501 }
2502 }
2503
2504 chan->expected_ack_seq = reqseq;
2505
2506 if (chan->unacked_frames == 0)
2507 __clear_retrans_timer(chan);
2508
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002509 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002510}
2511
2512static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2513{
2514 BT_DBG("chan %p", chan);
2515
2516 chan->expected_tx_seq = chan->buffer_seq;
2517 l2cap_seq_list_clear(&chan->srej_list);
2518 skb_queue_purge(&chan->srej_q);
2519 chan->rx_state = L2CAP_RX_STATE_RECV;
2520}
2521
Gustavo Padovand6603662012-05-21 13:58:22 -03002522static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2523 struct l2cap_ctrl *control,
2524 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002525{
Mat Martineau608bcc62012-05-17 20:53:32 -07002526 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2527 event);
2528
2529 switch (event) {
2530 case L2CAP_EV_DATA_REQUEST:
2531 if (chan->tx_send_head == NULL)
2532 chan->tx_send_head = skb_peek(skbs);
2533
2534 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2535 l2cap_ertm_send(chan);
2536 break;
2537 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2538 BT_DBG("Enter LOCAL_BUSY");
2539 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2540
2541 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2542 /* The SREJ_SENT state must be aborted if we are to
2543 * enter the LOCAL_BUSY state.
2544 */
2545 l2cap_abort_rx_srej_sent(chan);
2546 }
2547
2548 l2cap_send_ack(chan);
2549
2550 break;
2551 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2552 BT_DBG("Exit LOCAL_BUSY");
2553 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2554
2555 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2556 struct l2cap_ctrl local_control;
2557
2558 memset(&local_control, 0, sizeof(local_control));
2559 local_control.sframe = 1;
2560 local_control.super = L2CAP_SUPER_RR;
2561 local_control.poll = 1;
2562 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002563 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002564
2565 chan->retry_count = 1;
2566 __set_monitor_timer(chan);
2567 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2568 }
2569 break;
2570 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2571 l2cap_process_reqseq(chan, control->reqseq);
2572 break;
2573 case L2CAP_EV_EXPLICIT_POLL:
2574 l2cap_send_rr_or_rnr(chan, 1);
2575 chan->retry_count = 1;
2576 __set_monitor_timer(chan);
2577 __clear_ack_timer(chan);
2578 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2579 break;
2580 case L2CAP_EV_RETRANS_TO:
2581 l2cap_send_rr_or_rnr(chan, 1);
2582 chan->retry_count = 1;
2583 __set_monitor_timer(chan);
2584 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2585 break;
2586 case L2CAP_EV_RECV_FBIT:
2587 /* Nothing to process */
2588 break;
2589 default:
2590 break;
2591 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002592}
2593
Gustavo Padovand6603662012-05-21 13:58:22 -03002594static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2595 struct l2cap_ctrl *control,
2596 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002597{
Mat Martineau608bcc62012-05-17 20:53:32 -07002598 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2599 event);
2600
2601 switch (event) {
2602 case L2CAP_EV_DATA_REQUEST:
2603 if (chan->tx_send_head == NULL)
2604 chan->tx_send_head = skb_peek(skbs);
2605 /* Queue data, but don't send. */
2606 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2607 break;
2608 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2609 BT_DBG("Enter LOCAL_BUSY");
2610 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2611
2612 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2613 /* The SREJ_SENT state must be aborted if we are to
2614 * enter the LOCAL_BUSY state.
2615 */
2616 l2cap_abort_rx_srej_sent(chan);
2617 }
2618
2619 l2cap_send_ack(chan);
2620
2621 break;
2622 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2623 BT_DBG("Exit LOCAL_BUSY");
2624 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2625
2626 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2627 struct l2cap_ctrl local_control;
2628 memset(&local_control, 0, sizeof(local_control));
2629 local_control.sframe = 1;
2630 local_control.super = L2CAP_SUPER_RR;
2631 local_control.poll = 1;
2632 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002633 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002634
2635 chan->retry_count = 1;
2636 __set_monitor_timer(chan);
2637 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2638 }
2639 break;
2640 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2641 l2cap_process_reqseq(chan, control->reqseq);
2642
2643 /* Fall through */
2644
2645 case L2CAP_EV_RECV_FBIT:
2646 if (control && control->final) {
2647 __clear_monitor_timer(chan);
2648 if (chan->unacked_frames > 0)
2649 __set_retrans_timer(chan);
2650 chan->retry_count = 0;
2651 chan->tx_state = L2CAP_TX_STATE_XMIT;
2652 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2653 }
2654 break;
2655 case L2CAP_EV_EXPLICIT_POLL:
2656 /* Ignore */
2657 break;
2658 case L2CAP_EV_MONITOR_TO:
2659 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2660 l2cap_send_rr_or_rnr(chan, 1);
2661 __set_monitor_timer(chan);
2662 chan->retry_count++;
2663 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002664 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002665 }
2666 break;
2667 default:
2668 break;
2669 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002670}
2671
Gustavo Padovand6603662012-05-21 13:58:22 -03002672static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2673 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002674{
Mat Martineau608bcc62012-05-17 20:53:32 -07002675 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2676 chan, control, skbs, event, chan->tx_state);
2677
2678 switch (chan->tx_state) {
2679 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002680 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002681 break;
2682 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002683 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002684 break;
2685 default:
2686 /* Ignore event */
2687 break;
2688 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002689}
2690
Mat Martineau4b51dae92012-05-17 20:53:37 -07002691static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2692 struct l2cap_ctrl *control)
2693{
2694 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002695 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002696}
2697
Mat Martineauf80842a2012-05-17 20:53:46 -07002698static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2699 struct l2cap_ctrl *control)
2700{
2701 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002702 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002703}
2704
Linus Torvalds1da177e2005-04-16 15:20:36 -07002705/* Copy frame to all raw sockets on that connection */
2706static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2707{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002708 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002709 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710
2711 BT_DBG("conn %p", conn);
2712
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002713 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002714
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002715 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002716 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002717 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002718 continue;
2719
2720 /* Don't send frame to the socket it came from */
2721 if (skb->sk == sk)
2722 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002723 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002724 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002725 continue;
2726
Gustavo Padovan80b98022012-05-27 22:27:51 -03002727 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728 kfree_skb(nskb);
2729 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002730
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002731 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002732}
2733
2734/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002735static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2736 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002737{
2738 struct sk_buff *skb, **frag;
2739 struct l2cap_cmd_hdr *cmd;
2740 struct l2cap_hdr *lh;
2741 int len, count;
2742
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002743 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2744 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002745
2746 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2747 count = min_t(unsigned int, conn->mtu, len);
2748
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002749 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750 if (!skb)
2751 return NULL;
2752
2753 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002754 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002755
2756 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002757 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002758 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002759 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002760
2761 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2762 cmd->code = code;
2763 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002764 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002765
2766 if (dlen) {
2767 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2768 memcpy(skb_put(skb, count), data, count);
2769 data += count;
2770 }
2771
2772 len -= skb->len;
2773
2774 /* Continuation fragments (no L2CAP header) */
2775 frag = &skb_shinfo(skb)->frag_list;
2776 while (len) {
2777 count = min_t(unsigned int, conn->mtu, len);
2778
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002779 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002780 if (!*frag)
2781 goto fail;
2782
2783 memcpy(skb_put(*frag, count), data, count);
2784
2785 len -= count;
2786 data += count;
2787
2788 frag = &(*frag)->next;
2789 }
2790
2791 return skb;
2792
2793fail:
2794 kfree_skb(skb);
2795 return NULL;
2796}
2797
Gustavo Padovan2d792812012-10-06 10:07:01 +01002798static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2799 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002800{
2801 struct l2cap_conf_opt *opt = *ptr;
2802 int len;
2803
2804 len = L2CAP_CONF_OPT_SIZE + opt->len;
2805 *ptr += len;
2806
2807 *type = opt->type;
2808 *olen = opt->len;
2809
2810 switch (opt->len) {
2811 case 1:
2812 *val = *((u8 *) opt->val);
2813 break;
2814
2815 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002816 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817 break;
2818
2819 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002820 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821 break;
2822
2823 default:
2824 *val = (unsigned long) opt->val;
2825 break;
2826 }
2827
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002828 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829 return len;
2830}
2831
Linus Torvalds1da177e2005-04-16 15:20:36 -07002832static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2833{
2834 struct l2cap_conf_opt *opt = *ptr;
2835
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002836 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002837
2838 opt->type = type;
2839 opt->len = len;
2840
2841 switch (len) {
2842 case 1:
2843 *((u8 *) opt->val) = val;
2844 break;
2845
2846 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002847 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002848 break;
2849
2850 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002851 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002852 break;
2853
2854 default:
2855 memcpy(opt->val, (void *) val, len);
2856 break;
2857 }
2858
2859 *ptr += L2CAP_CONF_OPT_SIZE + len;
2860}
2861
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002862static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2863{
2864 struct l2cap_conf_efs efs;
2865
Szymon Janc1ec918c2011-11-16 09:32:21 +01002866 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002867 case L2CAP_MODE_ERTM:
2868 efs.id = chan->local_id;
2869 efs.stype = chan->local_stype;
2870 efs.msdu = cpu_to_le16(chan->local_msdu);
2871 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002872 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002873 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002874 break;
2875
2876 case L2CAP_MODE_STREAMING:
2877 efs.id = 1;
2878 efs.stype = L2CAP_SERV_BESTEFFORT;
2879 efs.msdu = cpu_to_le16(chan->local_msdu);
2880 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2881 efs.acc_lat = 0;
2882 efs.flush_to = 0;
2883 break;
2884
2885 default:
2886 return;
2887 }
2888
2889 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002890 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002891}
2892
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002893static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002894{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002895 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07002896 ack_timer.work);
2897 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002898
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02002899 BT_DBG("chan %p", chan);
2900
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002901 l2cap_chan_lock(chan);
2902
Mat Martineau03625202012-05-17 20:53:51 -07002903 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2904 chan->last_acked_seq);
2905
2906 if (frames_to_ack)
2907 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002908
2909 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01002910 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002911}
2912
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03002913int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002914{
Mat Martineau3c588192012-04-11 10:48:42 -07002915 int err;
2916
Mat Martineau105bdf92012-04-27 16:50:48 -07002917 chan->next_tx_seq = 0;
2918 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002919 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002920 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002921 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002922 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07002923 chan->last_acked_seq = 0;
2924 chan->sdu = NULL;
2925 chan->sdu_last_frag = NULL;
2926 chan->sdu_len = 0;
2927
Mat Martineaud34c34f2012-05-14 14:49:27 -07002928 skb_queue_head_init(&chan->tx_q);
2929
Mat Martineau08333282012-10-23 15:24:06 -07002930 chan->local_amp_id = 0;
2931 chan->move_id = 0;
2932 chan->move_state = L2CAP_MOVE_STABLE;
2933 chan->move_role = L2CAP_MOVE_ROLE_NONE;
2934
Mat Martineau105bdf92012-04-27 16:50:48 -07002935 if (chan->mode != L2CAP_MODE_ERTM)
2936 return 0;
2937
2938 chan->rx_state = L2CAP_RX_STATE_RECV;
2939 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002940
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002941 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
2942 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
2943 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002944
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03002945 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002946
Mat Martineau3c588192012-04-11 10:48:42 -07002947 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
2948 if (err < 0)
2949 return err;
2950
Mat Martineau9dc9aff2012-05-17 16:20:14 -07002951 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
2952 if (err < 0)
2953 l2cap_seq_list_free(&chan->srej_list);
2954
2955 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002956}
2957
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002958static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2959{
2960 switch (mode) {
2961 case L2CAP_MODE_STREAMING:
2962 case L2CAP_MODE_ERTM:
2963 if (l2cap_mode_supported(mode, remote_feat_mask))
2964 return mode;
2965 /* fall through */
2966 default:
2967 return L2CAP_MODE_BASIC;
2968 }
2969}
2970
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002971static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
2972{
2973 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
2974}
2975
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002976static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
2977{
2978 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
2979}
2980
Mat Martineau36c86c82012-10-23 15:24:20 -07002981static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
2982 struct l2cap_conf_rfc *rfc)
2983{
2984 if (chan->local_amp_id && chan->hs_hcon) {
2985 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
2986
2987 /* Class 1 devices have must have ERTM timeouts
2988 * exceeding the Link Supervision Timeout. The
2989 * default Link Supervision Timeout for AMP
2990 * controllers is 10 seconds.
2991 *
2992 * Class 1 devices use 0xffffffff for their
2993 * best-effort flush timeout, so the clamping logic
2994 * will result in a timeout that meets the above
2995 * requirement. ERTM timeouts are 16-bit values, so
2996 * the maximum timeout is 65.535 seconds.
2997 */
2998
2999 /* Convert timeout to milliseconds and round */
3000 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3001
3002 /* This is the recommended formula for class 2 devices
3003 * that start ERTM timers when packets are sent to the
3004 * controller.
3005 */
3006 ertm_to = 3 * ertm_to + 500;
3007
3008 if (ertm_to > 0xffff)
3009 ertm_to = 0xffff;
3010
3011 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3012 rfc->monitor_timeout = rfc->retrans_timeout;
3013 } else {
3014 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3015 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3016 }
3017}
3018
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003019static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3020{
3021 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003022 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003023 /* use extended control field */
3024 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003025 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3026 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003027 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003028 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003029 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3030 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003031 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003032}
3033
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003034static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003035{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003036 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003037 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003038 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003039 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003040
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003041 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003042
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003043 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003044 goto done;
3045
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003046 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003047 case L2CAP_MODE_STREAMING:
3048 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003049 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003050 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003051
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003052 if (__l2cap_efs_supported(chan))
3053 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3054
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003055 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003056 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003057 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003058 break;
3059 }
3060
3061done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003062 if (chan->imtu != L2CAP_DEFAULT_MTU)
3063 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003064
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003065 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003066 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003067 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003068 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003069 break;
3070
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003071 rfc.mode = L2CAP_MODE_BASIC;
3072 rfc.txwin_size = 0;
3073 rfc.max_transmit = 0;
3074 rfc.retrans_timeout = 0;
3075 rfc.monitor_timeout = 0;
3076 rfc.max_pdu_size = 0;
3077
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003078 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003079 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003080 break;
3081
3082 case L2CAP_MODE_ERTM:
3083 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003084 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003085
3086 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003087
3088 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003089 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3090 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003091 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003092
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003093 l2cap_txwin_setup(chan);
3094
3095 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003096 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003097
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003098 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003099 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003100
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003101 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3102 l2cap_add_opt_efs(&ptr, chan);
3103
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003104 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);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003107
3108 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3109 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003110 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003111 chan->fcs = L2CAP_FCS_NONE;
3112 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3113 chan->fcs);
3114 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003115 break;
3116
3117 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003118 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003119 rfc.mode = L2CAP_MODE_STREAMING;
3120 rfc.txwin_size = 0;
3121 rfc.max_transmit = 0;
3122 rfc.retrans_timeout = 0;
3123 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003124
3125 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003126 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3127 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003128 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003129
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003130 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003131 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003132
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003133 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3134 l2cap_add_opt_efs(&ptr, chan);
3135
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003136 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3137 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003138 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003139 chan->fcs = L2CAP_FCS_NONE;
3140 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3141 chan->fcs);
3142 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003143 break;
3144 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003145
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003146 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003147 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003148
3149 return ptr - data;
3150}
3151
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003152static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003153{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003154 struct l2cap_conf_rsp *rsp = data;
3155 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003156 void *req = chan->conf_req;
3157 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003158 int type, hint, olen;
3159 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003160 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003161 struct l2cap_conf_efs efs;
3162 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003163 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003164 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003165 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003166
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003167 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003168
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003169 while (len >= L2CAP_CONF_OPT_SIZE) {
3170 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003171
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003172 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003173 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003174
3175 switch (type) {
3176 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003177 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003178 break;
3179
3180 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003181 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003182 break;
3183
3184 case L2CAP_CONF_QOS:
3185 break;
3186
Marcel Holtmann6464f352007-10-20 13:39:51 +02003187 case L2CAP_CONF_RFC:
3188 if (olen == sizeof(rfc))
3189 memcpy(&rfc, (void *) val, olen);
3190 break;
3191
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003192 case L2CAP_CONF_FCS:
3193 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003194 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003195 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003196
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003197 case L2CAP_CONF_EFS:
3198 remote_efs = 1;
3199 if (olen == sizeof(efs))
3200 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003201 break;
3202
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003203 case L2CAP_CONF_EWS:
3204 if (!enable_hs)
3205 return -ECONNREFUSED;
3206
3207 set_bit(FLAG_EXT_CTRL, &chan->flags);
3208 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003209 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003210 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003211 break;
3212
3213 default:
3214 if (hint)
3215 break;
3216
3217 result = L2CAP_CONF_UNKNOWN;
3218 *((u8 *) ptr++) = type;
3219 break;
3220 }
3221 }
3222
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003223 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003224 goto done;
3225
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003226 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003227 case L2CAP_MODE_STREAMING:
3228 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003229 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003230 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003231 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003232 break;
3233 }
3234
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003235 if (remote_efs) {
3236 if (__l2cap_efs_supported(chan))
3237 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3238 else
3239 return -ECONNREFUSED;
3240 }
3241
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003242 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003243 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003244
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003245 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003246 }
3247
3248done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003249 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003250 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003251 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003252
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003253 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003254 return -ECONNREFUSED;
3255
Gustavo Padovan2d792812012-10-06 10:07:01 +01003256 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3257 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003258 }
3259
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003260 if (result == L2CAP_CONF_SUCCESS) {
3261 /* Configure output options and let the other side know
3262 * which ones we don't like. */
3263
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003264 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3265 result = L2CAP_CONF_UNACCEPT;
3266 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003267 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003268 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003269 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003270 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003271
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003272 if (remote_efs) {
3273 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003274 efs.stype != L2CAP_SERV_NOTRAFIC &&
3275 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003276
3277 result = L2CAP_CONF_UNACCEPT;
3278
3279 if (chan->num_conf_req >= 1)
3280 return -ECONNREFUSED;
3281
3282 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003283 sizeof(efs),
3284 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003285 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003286 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003287 result = L2CAP_CONF_PENDING;
3288 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003289 }
3290 }
3291
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003292 switch (rfc.mode) {
3293 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003294 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003295 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003296 break;
3297
3298 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003299 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3300 chan->remote_tx_win = rfc.txwin_size;
3301 else
3302 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3303
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003304 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003305
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003306 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003307 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3308 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003309 rfc.max_pdu_size = cpu_to_le16(size);
3310 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003311
Mat Martineau36c86c82012-10-23 15:24:20 -07003312 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003313
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003314 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003315
3316 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003317 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003318
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003319 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3320 chan->remote_id = efs.id;
3321 chan->remote_stype = efs.stype;
3322 chan->remote_msdu = le16_to_cpu(efs.msdu);
3323 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003324 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003325 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003326 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003327 chan->remote_sdu_itime =
3328 le32_to_cpu(efs.sdu_itime);
3329 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003330 sizeof(efs),
3331 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003332 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003333 break;
3334
3335 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003336 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003337 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3338 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003339 rfc.max_pdu_size = cpu_to_le16(size);
3340 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003341
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003342 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003343
Gustavo Padovan2d792812012-10-06 10:07:01 +01003344 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3345 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003346
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003347 break;
3348
3349 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003350 result = L2CAP_CONF_UNACCEPT;
3351
3352 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003353 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003354 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003355
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003356 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003357 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003358 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003359 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003360 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003361 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003362
3363 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003364}
3365
Gustavo Padovan2d792812012-10-06 10:07:01 +01003366static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3367 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003368{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003369 struct l2cap_conf_req *req = data;
3370 void *ptr = req->data;
3371 int type, olen;
3372 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003373 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003374 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003375
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003376 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003377
3378 while (len >= L2CAP_CONF_OPT_SIZE) {
3379 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3380
3381 switch (type) {
3382 case L2CAP_CONF_MTU:
3383 if (val < L2CAP_DEFAULT_MIN_MTU) {
3384 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003385 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003386 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003387 chan->imtu = val;
3388 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003389 break;
3390
3391 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003392 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003393 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003394 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003395 break;
3396
3397 case L2CAP_CONF_RFC:
3398 if (olen == sizeof(rfc))
3399 memcpy(&rfc, (void *)val, olen);
3400
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003401 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003402 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003403 return -ECONNREFUSED;
3404
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003405 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003406
3407 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003408 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003409 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003410
3411 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003412 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003413 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003414 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003415 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003416
3417 case L2CAP_CONF_EFS:
3418 if (olen == sizeof(efs))
3419 memcpy(&efs, (void *)val, olen);
3420
3421 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003422 efs.stype != L2CAP_SERV_NOTRAFIC &&
3423 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003424 return -ECONNREFUSED;
3425
Gustavo Padovan2d792812012-10-06 10:07:01 +01003426 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3427 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003428 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003429
3430 case L2CAP_CONF_FCS:
3431 if (*result == L2CAP_CONF_PENDING)
3432 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003433 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003434 &chan->conf_state);
3435 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003436 }
3437 }
3438
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003439 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003440 return -ECONNREFUSED;
3441
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003442 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003443
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003444 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003445 switch (rfc.mode) {
3446 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003447 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3448 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3449 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003450 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3451 chan->ack_win = min_t(u16, chan->ack_win,
3452 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003453
3454 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3455 chan->local_msdu = le16_to_cpu(efs.msdu);
3456 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003457 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003458 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3459 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003460 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003461 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003462 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003463
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003464 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003465 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003466 }
3467 }
3468
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003469 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003470 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003471
3472 return ptr - data;
3473}
3474
Gustavo Padovan2d792812012-10-06 10:07:01 +01003475static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3476 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003477{
3478 struct l2cap_conf_rsp *rsp = data;
3479 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003480
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003481 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003482
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003483 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003484 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003485 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003486
3487 return ptr - data;
3488}
3489
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003490void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003491{
3492 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003493 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003494 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003495 u8 rsp_code;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003496
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003497 rsp.scid = cpu_to_le16(chan->dcid);
3498 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003499 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3500 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003501
3502 if (chan->hs_hcon)
3503 rsp_code = L2CAP_CREATE_CHAN_RSP;
3504 else
3505 rsp_code = L2CAP_CONN_RSP;
3506
3507 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3508
3509 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003510
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003511 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003512 return;
3513
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003514 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003515 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003516 chan->num_conf_req++;
3517}
3518
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003519static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003520{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003521 int type, olen;
3522 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003523 /* Use sane default values in case a misbehaving remote device
3524 * did not send an RFC or extended window size option.
3525 */
3526 u16 txwin_ext = chan->ack_win;
3527 struct l2cap_conf_rfc rfc = {
3528 .mode = chan->mode,
3529 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3530 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3531 .max_pdu_size = cpu_to_le16(chan->imtu),
3532 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3533 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003534
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003535 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003536
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003537 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003538 return;
3539
3540 while (len >= L2CAP_CONF_OPT_SIZE) {
3541 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3542
Mat Martineauc20f8e32012-07-10 05:47:07 -07003543 switch (type) {
3544 case L2CAP_CONF_RFC:
3545 if (olen == sizeof(rfc))
3546 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003547 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003548 case L2CAP_CONF_EWS:
3549 txwin_ext = val;
3550 break;
3551 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003552 }
3553
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003554 switch (rfc.mode) {
3555 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003556 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3557 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003558 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3559 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3560 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3561 else
3562 chan->ack_win = min_t(u16, chan->ack_win,
3563 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003564 break;
3565 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003566 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003567 }
3568}
3569
Gustavo Padovan2d792812012-10-06 10:07:01 +01003570static inline int l2cap_command_rej(struct l2cap_conn *conn,
3571 struct l2cap_cmd_hdr *cmd, u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003572{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003573 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003574
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003575 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003576 return 0;
3577
3578 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003579 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003580 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003581
3582 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003583 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003584
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003585 l2cap_conn_start(conn);
3586 }
3587
3588 return 0;
3589}
3590
Mat Martineau17009152012-10-23 15:24:07 -07003591static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3592 struct l2cap_cmd_hdr *cmd,
3593 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003594{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003595 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3596 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003597 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003598 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003599 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003600
3601 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003602 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003603
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003604 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003605
3606 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003607 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003608 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003609 result = L2CAP_CR_BAD_PSM;
3610 goto sendresp;
3611 }
3612
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003613 parent = pchan->sk;
3614
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003615 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003616 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003617
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003618 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003619 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003620 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003621 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003622 result = L2CAP_CR_SEC_BLOCK;
3623 goto response;
3624 }
3625
Linus Torvalds1da177e2005-04-16 15:20:36 -07003626 result = L2CAP_CR_NO_MEM;
3627
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003628 /* Check if we already have channel with that dcid */
3629 if (__l2cap_get_chan_by_dcid(conn, scid))
3630 goto response;
3631
Gustavo Padovan80b98022012-05-27 22:27:51 -03003632 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003633 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003634 goto response;
3635
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003636 sk = chan->sk;
3637
Linus Torvalds1da177e2005-04-16 15:20:36 -07003638 hci_conn_hold(conn->hcon);
3639
Linus Torvalds1da177e2005-04-16 15:20:36 -07003640 bacpy(&bt_sk(sk)->src, conn->src);
3641 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003642 chan->psm = psm;
3643 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003644 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003645
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003646 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003647
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003648 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003649
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003650 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003651
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003652 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003653
Marcel Holtmann984947d2009-02-06 23:35:19 +01003654 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003655 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003656 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003657 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003658 result = L2CAP_CR_PEND;
3659 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003660 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003661 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003662 /* Force pending result for AMP controllers.
3663 * The connection will succeed after the
3664 * physical link is up.
3665 */
3666 if (amp_id) {
3667 __l2cap_state_change(chan, BT_CONNECT2);
3668 result = L2CAP_CR_PEND;
3669 } else {
3670 __l2cap_state_change(chan, BT_CONFIG);
3671 result = L2CAP_CR_SUCCESS;
3672 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003673 status = L2CAP_CS_NO_INFO;
3674 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003675 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003676 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003677 result = L2CAP_CR_PEND;
3678 status = L2CAP_CS_AUTHEN_PEND;
3679 }
3680 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003681 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003682 result = L2CAP_CR_PEND;
3683 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003684 }
3685
Linus Torvalds1da177e2005-04-16 15:20:36 -07003686response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003687 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003688 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003689
3690sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003691 rsp.scid = cpu_to_le16(scid);
3692 rsp.dcid = cpu_to_le16(dcid);
3693 rsp.result = cpu_to_le16(result);
3694 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003695 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003696
3697 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3698 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003699 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003700
3701 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3702 conn->info_ident = l2cap_get_ident(conn);
3703
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003704 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003705
Gustavo Padovan2d792812012-10-06 10:07:01 +01003706 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3707 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003708 }
3709
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003710 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003711 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003712 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003713 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003714 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003715 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003716 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003717 }
Mat Martineau17009152012-10-23 15:24:07 -07003718
3719 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003720}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003721
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003722static int l2cap_connect_req(struct l2cap_conn *conn,
3723 struct l2cap_cmd_hdr *cmd, u8 *data)
3724{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303725 struct hci_dev *hdev = conn->hcon->hdev;
3726 struct hci_conn *hcon = conn->hcon;
3727
3728 hci_dev_lock(hdev);
3729 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3730 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3731 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3732 hcon->dst_type, 0, NULL, 0,
3733 hcon->dev_class);
3734 hci_dev_unlock(hdev);
3735
Gustavo Padovan300229f2012-10-12 19:40:40 +08003736 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003737 return 0;
3738}
3739
Mat Martineau5909cf32012-10-23 15:24:08 -07003740static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003741 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003742{
3743 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3744 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003745 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003746 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003747 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003748
3749 scid = __le16_to_cpu(rsp->scid);
3750 dcid = __le16_to_cpu(rsp->dcid);
3751 result = __le16_to_cpu(rsp->result);
3752 status = __le16_to_cpu(rsp->status);
3753
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003754 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 +01003755 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003756
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003757 mutex_lock(&conn->chan_lock);
3758
Linus Torvalds1da177e2005-04-16 15:20:36 -07003759 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003760 chan = __l2cap_get_chan_by_scid(conn, scid);
3761 if (!chan) {
3762 err = -EFAULT;
3763 goto unlock;
3764 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003765 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003766 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3767 if (!chan) {
3768 err = -EFAULT;
3769 goto unlock;
3770 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003771 }
3772
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003773 err = 0;
3774
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003775 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003776
Linus Torvalds1da177e2005-04-16 15:20:36 -07003777 switch (result) {
3778 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003779 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003780 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003781 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003782 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003783
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003784 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003785 break;
3786
Linus Torvalds1da177e2005-04-16 15:20:36 -07003787 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003788 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003789 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003790 break;
3791
3792 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003793 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003794 break;
3795
3796 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003797 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003798 break;
3799 }
3800
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003801 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003802
3803unlock:
3804 mutex_unlock(&conn->chan_lock);
3805
3806 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003807}
3808
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003809static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003810{
3811 /* FCS is enabled only in ERTM or streaming mode, if one or both
3812 * sides request it.
3813 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003814 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003815 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003816 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003817 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003818}
3819
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003820static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3821 u8 ident, u16 flags)
3822{
3823 struct l2cap_conn *conn = chan->conn;
3824
3825 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3826 flags);
3827
3828 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3829 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3830
3831 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3832 l2cap_build_conf_rsp(chan, data,
3833 L2CAP_CONF_SUCCESS, flags), data);
3834}
3835
Gustavo Padovan2d792812012-10-06 10:07:01 +01003836static inline int l2cap_config_req(struct l2cap_conn *conn,
3837 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3838 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003839{
3840 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3841 u16 dcid, flags;
3842 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003843 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003844 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003845
3846 dcid = __le16_to_cpu(req->dcid);
3847 flags = __le16_to_cpu(req->flags);
3848
3849 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3850
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003851 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003852 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003853 return -ENOENT;
3854
David S. Miller033b1142011-07-21 13:38:42 -07003855 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003856 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003857
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003858 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003859 rej.scid = cpu_to_le16(chan->scid);
3860 rej.dcid = cpu_to_le16(chan->dcid);
3861
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003862 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003863 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003864 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003865 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003866
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003867 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003868 len = cmd_len - sizeof(*req);
Dan Rosenberg7ac28812011-06-24 08:38:05 -04003869 if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003870 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003871 l2cap_build_conf_rsp(chan, rsp,
3872 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003873 goto unlock;
3874 }
3875
3876 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003877 memcpy(chan->conf_req + chan->conf_len, req->data, len);
3878 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003879
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003880 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003881 /* Incomplete config. Send empty response. */
3882 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003883 l2cap_build_conf_rsp(chan, rsp,
3884 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003885 goto unlock;
3886 }
3887
3888 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003889 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003890 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02003891 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003892 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003893 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003894
Mat Martineau1500109b2012-10-23 15:24:15 -07003895 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003896 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003897 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003898
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003899 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003900 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003901
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003902 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02003903 goto unlock;
3904
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003905 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003906 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003907
Mat Martineau105bdf92012-04-27 16:50:48 -07003908 if (chan->mode == L2CAP_MODE_ERTM ||
3909 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003910 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003911
Mat Martineau3c588192012-04-11 10:48:42 -07003912 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02003913 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07003914 else
3915 l2cap_chan_ready(chan);
3916
Marcel Holtmann876d9482007-10-20 13:35:42 +02003917 goto unlock;
3918 }
3919
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003920 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003921 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003922 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003923 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003924 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003925 }
3926
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003927 /* Got Conf Rsp PENDING from remote side and asume we sent
3928 Conf Rsp PENDING in the code above */
3929 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003930 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003931
3932 /* check compatibility */
3933
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03003934 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02003935 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03003936 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
3937 else
3938 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003939 }
3940
Linus Torvalds1da177e2005-04-16 15:20:36 -07003941unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003942 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003943 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003944}
3945
Gustavo Padovan2d792812012-10-06 10:07:01 +01003946static inline int l2cap_config_rsp(struct l2cap_conn *conn,
3947 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003948{
3949 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3950 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003951 struct l2cap_chan *chan;
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003952 int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07003953 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003954
3955 scid = __le16_to_cpu(rsp->scid);
3956 flags = __le16_to_cpu(rsp->flags);
3957 result = __le16_to_cpu(rsp->result);
3958
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003959 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
3960 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003961
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003962 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003963 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003964 return 0;
3965
3966 switch (result) {
3967 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003968 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003969 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003970 break;
3971
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003972 case L2CAP_CONF_PENDING:
3973 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
3974
3975 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3976 char buf[64];
3977
3978 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003979 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003980 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02003981 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003982 goto done;
3983 }
3984
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02003985 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03003986 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
3987 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02003988 } else {
3989 if (l2cap_check_efs(chan)) {
3990 amp_create_logical_link(chan);
3991 chan->ident = cmd->ident;
3992 }
3993 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003994 }
3995 goto done;
3996
Linus Torvalds1da177e2005-04-16 15:20:36 -07003997 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003998 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003999 char req[64];
4000
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004001 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004002 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004003 goto done;
4004 }
4005
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004006 /* throw out any old stored conf requests */
4007 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004008 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004009 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004010 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004011 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004012 goto done;
4013 }
4014
4015 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004016 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004017 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004018 if (result != L2CAP_CONF_SUCCESS)
4019 goto done;
4020 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004021 }
4022
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004023 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004024 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004025
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004026 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004027 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004028 goto done;
4029 }
4030
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004031 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004032 goto done;
4033
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004034 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004035
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004036 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004037 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004038
Mat Martineau105bdf92012-04-27 16:50:48 -07004039 if (chan->mode == L2CAP_MODE_ERTM ||
4040 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004041 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004042
Mat Martineau3c588192012-04-11 10:48:42 -07004043 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004044 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004045 else
4046 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004047 }
4048
4049done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004050 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004051 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004052}
4053
Gustavo Padovan2d792812012-10-06 10:07:01 +01004054static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
4055 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004056{
4057 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4058 struct l2cap_disconn_rsp rsp;
4059 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004060 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004061 struct sock *sk;
4062
4063 scid = __le16_to_cpu(req->scid);
4064 dcid = __le16_to_cpu(req->dcid);
4065
4066 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4067
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004068 mutex_lock(&conn->chan_lock);
4069
4070 chan = __l2cap_get_chan_by_scid(conn, dcid);
4071 if (!chan) {
4072 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004073 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004074 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004075
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004076 l2cap_chan_lock(chan);
4077
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004078 sk = chan->sk;
4079
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004080 rsp.dcid = cpu_to_le16(chan->scid);
4081 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004082 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4083
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004084 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004085 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004086 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004087
Mat Martineau61d6ef32012-04-27 16:50:50 -07004088 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004089 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004090
4091 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004092
Gustavo Padovan80b98022012-05-27 22:27:51 -03004093 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004094 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004095
4096 mutex_unlock(&conn->chan_lock);
4097
Linus Torvalds1da177e2005-04-16 15:20:36 -07004098 return 0;
4099}
4100
Gustavo Padovan2d792812012-10-06 10:07:01 +01004101static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
4102 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004103{
4104 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4105 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004106 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004107
4108 scid = __le16_to_cpu(rsp->scid);
4109 dcid = __le16_to_cpu(rsp->dcid);
4110
4111 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4112
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004113 mutex_lock(&conn->chan_lock);
4114
4115 chan = __l2cap_get_chan_by_scid(conn, scid);
4116 if (!chan) {
4117 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004118 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004119 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004120
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004121 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004122
Mat Martineau61d6ef32012-04-27 16:50:50 -07004123 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004124 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004125
4126 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004127
Gustavo Padovan80b98022012-05-27 22:27:51 -03004128 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004129 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004130
4131 mutex_unlock(&conn->chan_lock);
4132
Linus Torvalds1da177e2005-04-16 15:20:36 -07004133 return 0;
4134}
4135
Gustavo Padovan2d792812012-10-06 10:07:01 +01004136static inline int l2cap_information_req(struct l2cap_conn *conn,
4137 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004138{
4139 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004140 u16 type;
4141
4142 type = __le16_to_cpu(req->type);
4143
4144 BT_DBG("type 0x%4.4x", type);
4145
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004146 if (type == L2CAP_IT_FEAT_MASK) {
4147 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004148 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004149 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004150 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4151 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004152 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004153 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004154 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004155 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004156 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004157 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004158
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004159 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004160 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4161 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004162 } else if (type == L2CAP_IT_FIXED_CHAN) {
4163 u8 buf[12];
4164 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004165
4166 if (enable_hs)
4167 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4168 else
4169 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4170
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004171 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4172 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004173 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004174 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4175 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004176 } else {
4177 struct l2cap_info_rsp rsp;
4178 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004179 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004180 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4181 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004182 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004183
4184 return 0;
4185}
4186
Gustavo Padovan2d792812012-10-06 10:07:01 +01004187static inline int l2cap_information_rsp(struct l2cap_conn *conn,
4188 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004189{
4190 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4191 u16 type, result;
4192
4193 type = __le16_to_cpu(rsp->type);
4194 result = __le16_to_cpu(rsp->result);
4195
4196 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4197
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004198 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4199 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004200 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004201 return 0;
4202
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004203 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004204
Ville Tervoadb08ed2010-08-04 09:43:33 +03004205 if (result != L2CAP_IR_SUCCESS) {
4206 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4207 conn->info_ident = 0;
4208
4209 l2cap_conn_start(conn);
4210
4211 return 0;
4212 }
4213
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004214 switch (type) {
4215 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004216 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004217
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004218 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004219 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004220 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004221
4222 conn->info_ident = l2cap_get_ident(conn);
4223
4224 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004225 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004226 } else {
4227 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4228 conn->info_ident = 0;
4229
4230 l2cap_conn_start(conn);
4231 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004232 break;
4233
4234 case L2CAP_IT_FIXED_CHAN:
4235 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004236 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004237 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004238
4239 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004240 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004241 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004242
Linus Torvalds1da177e2005-04-16 15:20:36 -07004243 return 0;
4244}
4245
Mat Martineau17009152012-10-23 15:24:07 -07004246static int l2cap_create_channel_req(struct l2cap_conn *conn,
4247 struct l2cap_cmd_hdr *cmd,
4248 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004249{
4250 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004251 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004252 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004253 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004254 u16 psm, scid;
4255
4256 if (cmd_len != sizeof(*req))
4257 return -EPROTO;
4258
4259 if (!enable_hs)
4260 return -EINVAL;
4261
4262 psm = le16_to_cpu(req->psm);
4263 scid = le16_to_cpu(req->scid);
4264
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004265 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 -07004266
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004267 /* For controller id 0 make BR/EDR connection */
4268 if (req->amp_id == HCI_BREDR_ID) {
4269 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4270 req->amp_id);
4271 return 0;
4272 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004273
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004274 /* Validate AMP controller id */
4275 hdev = hci_dev_get(req->amp_id);
4276 if (!hdev)
4277 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004278
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004279 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004280 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004281 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004282 }
4283
4284 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4285 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004286 if (chan) {
4287 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4288 struct hci_conn *hs_hcon;
4289
4290 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, conn->dst);
4291 if (!hs_hcon) {
4292 hci_dev_put(hdev);
4293 return -EFAULT;
4294 }
4295
4296 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4297
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004298 mgr->bredr_chan = chan;
4299 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004300 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004301 conn->mtu = hdev->block_mtu;
4302 }
4303
4304 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004305
4306 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004307
4308error:
4309 rsp.dcid = 0;
4310 rsp.scid = cpu_to_le16(scid);
4311 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4312 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4313
4314 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4315 sizeof(rsp), &rsp);
4316
4317 return -EFAULT;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004318}
4319
Mat Martineau8eb200b2012-10-23 15:24:17 -07004320static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4321{
4322 struct l2cap_move_chan_req req;
4323 u8 ident;
4324
4325 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4326
4327 ident = l2cap_get_ident(chan->conn);
4328 chan->ident = ident;
4329
4330 req.icid = cpu_to_le16(chan->scid);
4331 req.dest_amp_id = dest_amp_id;
4332
4333 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4334 &req);
4335
4336 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4337}
4338
Mat Martineau1500109b2012-10-23 15:24:15 -07004339static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004340{
4341 struct l2cap_move_chan_rsp rsp;
4342
Mat Martineau1500109b2012-10-23 15:24:15 -07004343 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004344
Mat Martineau1500109b2012-10-23 15:24:15 -07004345 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004346 rsp.result = cpu_to_le16(result);
4347
Mat Martineau1500109b2012-10-23 15:24:15 -07004348 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4349 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004350}
4351
Mat Martineau5b155ef2012-10-23 15:24:14 -07004352static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004353{
4354 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004355
Mat Martineau5b155ef2012-10-23 15:24:14 -07004356 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004357
Mat Martineau5b155ef2012-10-23 15:24:14 -07004358 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004359
Mat Martineau5b155ef2012-10-23 15:24:14 -07004360 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004361 cfm.result = cpu_to_le16(result);
4362
Mat Martineau5b155ef2012-10-23 15:24:14 -07004363 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4364 sizeof(cfm), &cfm);
4365
4366 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4367}
4368
4369static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4370{
4371 struct l2cap_move_chan_cfm cfm;
4372
4373 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4374
4375 cfm.icid = cpu_to_le16(icid);
4376 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4377
4378 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4379 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004380}
4381
4382static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004383 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004384{
4385 struct l2cap_move_chan_cfm_rsp rsp;
4386
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004387 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004388
4389 rsp.icid = cpu_to_le16(icid);
4390 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4391}
4392
Mat Martineau5f3847a2012-10-23 15:24:12 -07004393static void __release_logical_link(struct l2cap_chan *chan)
4394{
4395 chan->hs_hchan = NULL;
4396 chan->hs_hcon = NULL;
4397
4398 /* Placeholder - release the logical link */
4399}
4400
Mat Martineau1500109b2012-10-23 15:24:15 -07004401static void l2cap_logical_fail(struct l2cap_chan *chan)
4402{
4403 /* Logical link setup failed */
4404 if (chan->state != BT_CONNECTED) {
4405 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004406 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004407 return;
4408 }
4409
4410 switch (chan->move_role) {
4411 case L2CAP_MOVE_ROLE_RESPONDER:
4412 l2cap_move_done(chan);
4413 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4414 break;
4415 case L2CAP_MOVE_ROLE_INITIATOR:
4416 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4417 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4418 /* Remote has only sent pending or
4419 * success responses, clean up
4420 */
4421 l2cap_move_done(chan);
4422 }
4423
4424 /* Other amp move states imply that the move
4425 * has already aborted
4426 */
4427 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4428 break;
4429 }
4430}
4431
4432static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4433 struct hci_chan *hchan)
4434{
4435 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004436
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004437 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004438 chan->hs_hcon->l2cap_data = chan->conn;
4439
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004440 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004441
4442 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004443 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004444
4445 set_default_fcs(chan);
4446
4447 err = l2cap_ertm_init(chan);
4448 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004449 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004450 else
4451 l2cap_chan_ready(chan);
4452 }
4453}
4454
4455static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4456 struct hci_chan *hchan)
4457{
4458 chan->hs_hcon = hchan->conn;
4459 chan->hs_hcon->l2cap_data = chan->conn;
4460
4461 BT_DBG("move_state %d", chan->move_state);
4462
4463 switch (chan->move_state) {
4464 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4465 /* Move confirm will be sent after a success
4466 * response is received
4467 */
4468 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4469 break;
4470 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4471 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4472 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4473 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4474 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4475 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4476 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4477 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4478 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4479 }
4480 break;
4481 default:
4482 /* Move was not in expected state, free the channel */
4483 __release_logical_link(chan);
4484
4485 chan->move_state = L2CAP_MOVE_STABLE;
4486 }
4487}
4488
4489/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004490void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4491 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004492{
Mat Martineau1500109b2012-10-23 15:24:15 -07004493 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4494
4495 if (status) {
4496 l2cap_logical_fail(chan);
4497 __release_logical_link(chan);
4498 return;
4499 }
4500
4501 if (chan->state != BT_CONNECTED) {
4502 /* Ignore logical link if channel is on BR/EDR */
4503 if (chan->local_amp_id)
4504 l2cap_logical_finish_create(chan, hchan);
4505 } else {
4506 l2cap_logical_finish_move(chan, hchan);
4507 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004508}
4509
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004510void l2cap_move_start(struct l2cap_chan *chan)
4511{
4512 BT_DBG("chan %p", chan);
4513
4514 if (chan->local_amp_id == HCI_BREDR_ID) {
4515 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4516 return;
4517 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4518 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4519 /* Placeholder - start physical link setup */
4520 } else {
4521 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4522 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4523 chan->move_id = 0;
4524 l2cap_move_setup(chan);
4525 l2cap_send_move_chan_req(chan, 0);
4526 }
4527}
4528
Mat Martineau8eb200b2012-10-23 15:24:17 -07004529static void l2cap_do_create(struct l2cap_chan *chan, int result,
4530 u8 local_amp_id, u8 remote_amp_id)
4531{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004532 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4533 local_amp_id, remote_amp_id);
4534
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004535 chan->fcs = L2CAP_FCS_NONE;
4536
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004537 /* Outgoing channel on AMP */
4538 if (chan->state == BT_CONNECT) {
4539 if (result == L2CAP_CR_SUCCESS) {
4540 chan->local_amp_id = local_amp_id;
4541 l2cap_send_create_chan_req(chan, remote_amp_id);
4542 } else {
4543 /* Revert to BR/EDR connect */
4544 l2cap_send_conn_req(chan);
4545 }
4546
4547 return;
4548 }
4549
4550 /* Incoming channel on AMP */
4551 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004552 struct l2cap_conn_rsp rsp;
4553 char buf[128];
4554 rsp.scid = cpu_to_le16(chan->dcid);
4555 rsp.dcid = cpu_to_le16(chan->scid);
4556
Mat Martineau8eb200b2012-10-23 15:24:17 -07004557 if (result == L2CAP_CR_SUCCESS) {
4558 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004559 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4560 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004561 } else {
4562 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004563 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4564 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004565 }
4566
4567 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4568 sizeof(rsp), &rsp);
4569
4570 if (result == L2CAP_CR_SUCCESS) {
4571 __l2cap_state_change(chan, BT_CONFIG);
4572 set_bit(CONF_REQ_SENT, &chan->conf_state);
4573 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4574 L2CAP_CONF_REQ,
4575 l2cap_build_conf_req(chan, buf), buf);
4576 chan->num_conf_req++;
4577 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004578 }
4579}
4580
4581static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4582 u8 remote_amp_id)
4583{
4584 l2cap_move_setup(chan);
4585 chan->move_id = local_amp_id;
4586 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4587
4588 l2cap_send_move_chan_req(chan, remote_amp_id);
4589}
4590
4591static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4592{
4593 struct hci_chan *hchan = NULL;
4594
4595 /* Placeholder - get hci_chan for logical link */
4596
4597 if (hchan) {
4598 if (hchan->state == BT_CONNECTED) {
4599 /* Logical link is ready to go */
4600 chan->hs_hcon = hchan->conn;
4601 chan->hs_hcon->l2cap_data = chan->conn;
4602 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4603 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4604
4605 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4606 } else {
4607 /* Wait for logical link to be ready */
4608 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4609 }
4610 } else {
4611 /* Logical link not available */
4612 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4613 }
4614}
4615
4616static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4617{
4618 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4619 u8 rsp_result;
4620 if (result == -EINVAL)
4621 rsp_result = L2CAP_MR_BAD_ID;
4622 else
4623 rsp_result = L2CAP_MR_NOT_ALLOWED;
4624
4625 l2cap_send_move_chan_rsp(chan, rsp_result);
4626 }
4627
4628 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4629 chan->move_state = L2CAP_MOVE_STABLE;
4630
4631 /* Restart data transmission */
4632 l2cap_ertm_send(chan);
4633}
4634
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004635/* Invoke with locked chan */
4636void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004637{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004638 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004639 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004640
Mat Martineau8eb200b2012-10-23 15:24:17 -07004641 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4642 chan, result, local_amp_id, remote_amp_id);
4643
Mat Martineau8eb200b2012-10-23 15:24:17 -07004644 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4645 l2cap_chan_unlock(chan);
4646 return;
4647 }
4648
4649 if (chan->state != BT_CONNECTED) {
4650 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4651 } else if (result != L2CAP_MR_SUCCESS) {
4652 l2cap_do_move_cancel(chan, result);
4653 } else {
4654 switch (chan->move_role) {
4655 case L2CAP_MOVE_ROLE_INITIATOR:
4656 l2cap_do_move_initiate(chan, local_amp_id,
4657 remote_amp_id);
4658 break;
4659 case L2CAP_MOVE_ROLE_RESPONDER:
4660 l2cap_do_move_respond(chan, result);
4661 break;
4662 default:
4663 l2cap_do_move_cancel(chan, result);
4664 break;
4665 }
4666 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004667}
4668
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004669static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004670 struct l2cap_cmd_hdr *cmd,
4671 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004672{
4673 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004674 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004675 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004676 u16 icid = 0;
4677 u16 result = L2CAP_MR_NOT_ALLOWED;
4678
4679 if (cmd_len != sizeof(*req))
4680 return -EPROTO;
4681
4682 icid = le16_to_cpu(req->icid);
4683
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004684 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004685
4686 if (!enable_hs)
4687 return -EINVAL;
4688
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004689 chan = l2cap_get_chan_by_dcid(conn, icid);
4690 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004691 rsp.icid = cpu_to_le16(icid);
4692 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4693 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4694 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004695 return 0;
4696 }
4697
Mat Martineau1500109b2012-10-23 15:24:15 -07004698 chan->ident = cmd->ident;
4699
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004700 if (chan->scid < L2CAP_CID_DYN_START ||
4701 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4702 (chan->mode != L2CAP_MODE_ERTM &&
4703 chan->mode != L2CAP_MODE_STREAMING)) {
4704 result = L2CAP_MR_NOT_ALLOWED;
4705 goto send_move_response;
4706 }
4707
4708 if (chan->local_amp_id == req->dest_amp_id) {
4709 result = L2CAP_MR_SAME_ID;
4710 goto send_move_response;
4711 }
4712
4713 if (req->dest_amp_id) {
4714 struct hci_dev *hdev;
4715 hdev = hci_dev_get(req->dest_amp_id);
4716 if (!hdev || hdev->dev_type != HCI_AMP ||
4717 !test_bit(HCI_UP, &hdev->flags)) {
4718 if (hdev)
4719 hci_dev_put(hdev);
4720
4721 result = L2CAP_MR_BAD_ID;
4722 goto send_move_response;
4723 }
4724 hci_dev_put(hdev);
4725 }
4726
4727 /* Detect a move collision. Only send a collision response
4728 * if this side has "lost", otherwise proceed with the move.
4729 * The winner has the larger bd_addr.
4730 */
4731 if ((__chan_is_moving(chan) ||
4732 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
4733 bacmp(conn->src, conn->dst) > 0) {
4734 result = L2CAP_MR_COLLISION;
4735 goto send_move_response;
4736 }
4737
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004738 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4739 l2cap_move_setup(chan);
4740 chan->move_id = req->dest_amp_id;
4741 icid = chan->dcid;
4742
4743 if (!req->dest_amp_id) {
4744 /* Moving to BR/EDR */
4745 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4746 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4747 result = L2CAP_MR_PEND;
4748 } else {
4749 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4750 result = L2CAP_MR_SUCCESS;
4751 }
4752 } else {
4753 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4754 /* Placeholder - uncomment when amp functions are available */
4755 /*amp_accept_physical(chan, req->dest_amp_id);*/
4756 result = L2CAP_MR_PEND;
4757 }
4758
4759send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004760 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004761
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004762 l2cap_chan_unlock(chan);
4763
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004764 return 0;
4765}
4766
Mat Martineau5b155ef2012-10-23 15:24:14 -07004767static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4768{
4769 struct l2cap_chan *chan;
4770 struct hci_chan *hchan = NULL;
4771
4772 chan = l2cap_get_chan_by_scid(conn, icid);
4773 if (!chan) {
4774 l2cap_send_move_chan_cfm_icid(conn, icid);
4775 return;
4776 }
4777
4778 __clear_chan_timer(chan);
4779 if (result == L2CAP_MR_PEND)
4780 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4781
4782 switch (chan->move_state) {
4783 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4784 /* Move confirm will be sent when logical link
4785 * is complete.
4786 */
4787 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4788 break;
4789 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4790 if (result == L2CAP_MR_PEND) {
4791 break;
4792 } else if (test_bit(CONN_LOCAL_BUSY,
4793 &chan->conn_state)) {
4794 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4795 } else {
4796 /* Logical link is up or moving to BR/EDR,
4797 * proceed with move
4798 */
4799 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4800 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4801 }
4802 break;
4803 case L2CAP_MOVE_WAIT_RSP:
4804 /* Moving to AMP */
4805 if (result == L2CAP_MR_SUCCESS) {
4806 /* Remote is ready, send confirm immediately
4807 * after logical link is ready
4808 */
4809 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4810 } else {
4811 /* Both logical link and move success
4812 * are required to confirm
4813 */
4814 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4815 }
4816
4817 /* Placeholder - get hci_chan for logical link */
4818 if (!hchan) {
4819 /* Logical link not available */
4820 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4821 break;
4822 }
4823
4824 /* If the logical link is not yet connected, do not
4825 * send confirmation.
4826 */
4827 if (hchan->state != BT_CONNECTED)
4828 break;
4829
4830 /* Logical link is already ready to go */
4831
4832 chan->hs_hcon = hchan->conn;
4833 chan->hs_hcon->l2cap_data = chan->conn;
4834
4835 if (result == L2CAP_MR_SUCCESS) {
4836 /* Can confirm now */
4837 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4838 } else {
4839 /* Now only need move success
4840 * to confirm
4841 */
4842 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4843 }
4844
4845 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4846 break;
4847 default:
4848 /* Any other amp move state means the move failed. */
4849 chan->move_id = chan->local_amp_id;
4850 l2cap_move_done(chan);
4851 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4852 }
4853
4854 l2cap_chan_unlock(chan);
4855}
4856
4857static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
4858 u16 result)
4859{
4860 struct l2cap_chan *chan;
4861
4862 chan = l2cap_get_chan_by_ident(conn, ident);
4863 if (!chan) {
4864 /* Could not locate channel, icid is best guess */
4865 l2cap_send_move_chan_cfm_icid(conn, icid);
4866 return;
4867 }
4868
4869 __clear_chan_timer(chan);
4870
4871 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4872 if (result == L2CAP_MR_COLLISION) {
4873 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4874 } else {
4875 /* Cleanup - cancel move */
4876 chan->move_id = chan->local_amp_id;
4877 l2cap_move_done(chan);
4878 }
4879 }
4880
4881 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4882
4883 l2cap_chan_unlock(chan);
4884}
4885
4886static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
4887 struct l2cap_cmd_hdr *cmd,
4888 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004889{
4890 struct l2cap_move_chan_rsp *rsp = data;
4891 u16 icid, result;
4892
4893 if (cmd_len != sizeof(*rsp))
4894 return -EPROTO;
4895
4896 icid = le16_to_cpu(rsp->icid);
4897 result = le16_to_cpu(rsp->result);
4898
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004899 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004900
Mat Martineau5b155ef2012-10-23 15:24:14 -07004901 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
4902 l2cap_move_continue(conn, icid, result);
4903 else
4904 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004905
4906 return 0;
4907}
4908
Mat Martineau5f3847a2012-10-23 15:24:12 -07004909static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
4910 struct l2cap_cmd_hdr *cmd,
4911 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004912{
4913 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07004914 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004915 u16 icid, result;
4916
4917 if (cmd_len != sizeof(*cfm))
4918 return -EPROTO;
4919
4920 icid = le16_to_cpu(cfm->icid);
4921 result = le16_to_cpu(cfm->result);
4922
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004923 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004924
Mat Martineau5f3847a2012-10-23 15:24:12 -07004925 chan = l2cap_get_chan_by_dcid(conn, icid);
4926 if (!chan) {
4927 /* Spec requires a response even if the icid was not found */
4928 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4929 return 0;
4930 }
4931
4932 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
4933 if (result == L2CAP_MC_CONFIRMED) {
4934 chan->local_amp_id = chan->move_id;
4935 if (!chan->local_amp_id)
4936 __release_logical_link(chan);
4937 } else {
4938 chan->move_id = chan->local_amp_id;
4939 }
4940
4941 l2cap_move_done(chan);
4942 }
4943
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004944 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4945
Mat Martineau5f3847a2012-10-23 15:24:12 -07004946 l2cap_chan_unlock(chan);
4947
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004948 return 0;
4949}
4950
4951static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004952 struct l2cap_cmd_hdr *cmd,
4953 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004954{
4955 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07004956 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004957 u16 icid;
4958
4959 if (cmd_len != sizeof(*rsp))
4960 return -EPROTO;
4961
4962 icid = le16_to_cpu(rsp->icid);
4963
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004964 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004965
Mat Martineau3fd71a02012-10-23 15:24:16 -07004966 chan = l2cap_get_chan_by_scid(conn, icid);
4967 if (!chan)
4968 return 0;
4969
4970 __clear_chan_timer(chan);
4971
4972 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
4973 chan->local_amp_id = chan->move_id;
4974
4975 if (!chan->local_amp_id && chan->hs_hchan)
4976 __release_logical_link(chan);
4977
4978 l2cap_move_done(chan);
4979 }
4980
4981 l2cap_chan_unlock(chan);
4982
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004983 return 0;
4984}
4985
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004986static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004987 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02004988{
4989 u16 max_latency;
4990
4991 if (min > max || min < 6 || max > 3200)
4992 return -EINVAL;
4993
4994 if (to_multiplier < 10 || to_multiplier > 3200)
4995 return -EINVAL;
4996
4997 if (max >= to_multiplier * 8)
4998 return -EINVAL;
4999
5000 max_latency = (to_multiplier * 8 / max) - 1;
5001 if (latency > 499 || latency > max_latency)
5002 return -EINVAL;
5003
5004 return 0;
5005}
5006
5007static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005008 struct l2cap_cmd_hdr *cmd,
5009 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005010{
5011 struct hci_conn *hcon = conn->hcon;
5012 struct l2cap_conn_param_update_req *req;
5013 struct l2cap_conn_param_update_rsp rsp;
5014 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005015 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005016
5017 if (!(hcon->link_mode & HCI_LM_MASTER))
5018 return -EINVAL;
5019
5020 cmd_len = __le16_to_cpu(cmd->len);
5021 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5022 return -EPROTO;
5023
5024 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005025 min = __le16_to_cpu(req->min);
5026 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005027 latency = __le16_to_cpu(req->latency);
5028 to_multiplier = __le16_to_cpu(req->to_multiplier);
5029
5030 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 +01005031 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005032
5033 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005034
5035 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5036 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005037 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005038 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005039 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005040
5041 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005042 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005043
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005044 if (!err)
5045 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5046
Claudio Takahaside731152011-02-11 19:28:55 -02005047 return 0;
5048}
5049
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005050static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005051 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5052 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005053{
5054 int err = 0;
5055
5056 switch (cmd->code) {
5057 case L2CAP_COMMAND_REJ:
5058 l2cap_command_rej(conn, cmd, data);
5059 break;
5060
5061 case L2CAP_CONN_REQ:
5062 err = l2cap_connect_req(conn, cmd, data);
5063 break;
5064
5065 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005066 case L2CAP_CREATE_CHAN_RSP:
Mat Martineau5909cf32012-10-23 15:24:08 -07005067 err = l2cap_connect_create_rsp(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005068 break;
5069
5070 case L2CAP_CONF_REQ:
5071 err = l2cap_config_req(conn, cmd, cmd_len, data);
5072 break;
5073
5074 case L2CAP_CONF_RSP:
5075 err = l2cap_config_rsp(conn, cmd, data);
5076 break;
5077
5078 case L2CAP_DISCONN_REQ:
5079 err = l2cap_disconnect_req(conn, cmd, data);
5080 break;
5081
5082 case L2CAP_DISCONN_RSP:
5083 err = l2cap_disconnect_rsp(conn, cmd, data);
5084 break;
5085
5086 case L2CAP_ECHO_REQ:
5087 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5088 break;
5089
5090 case L2CAP_ECHO_RSP:
5091 break;
5092
5093 case L2CAP_INFO_REQ:
5094 err = l2cap_information_req(conn, cmd, data);
5095 break;
5096
5097 case L2CAP_INFO_RSP:
5098 err = l2cap_information_rsp(conn, cmd, data);
5099 break;
5100
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005101 case L2CAP_CREATE_CHAN_REQ:
5102 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5103 break;
5104
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005105 case L2CAP_MOVE_CHAN_REQ:
5106 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5107 break;
5108
5109 case L2CAP_MOVE_CHAN_RSP:
5110 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
5111 break;
5112
5113 case L2CAP_MOVE_CHAN_CFM:
5114 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5115 break;
5116
5117 case L2CAP_MOVE_CHAN_CFM_RSP:
5118 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
5119 break;
5120
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005121 default:
5122 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5123 err = -EINVAL;
5124 break;
5125 }
5126
5127 return err;
5128}
5129
5130static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005131 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005132{
5133 switch (cmd->code) {
5134 case L2CAP_COMMAND_REJ:
5135 return 0;
5136
5137 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005138 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005139
5140 case L2CAP_CONN_PARAM_UPDATE_RSP:
5141 return 0;
5142
5143 default:
5144 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5145 return -EINVAL;
5146 }
5147}
5148
5149static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005150 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005151{
5152 u8 *data = skb->data;
5153 int len = skb->len;
5154 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005155 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005156
5157 l2cap_raw_recv(conn, skb);
5158
5159 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005160 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005161 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5162 data += L2CAP_CMD_HDR_SIZE;
5163 len -= L2CAP_CMD_HDR_SIZE;
5164
Al Viro88219a02007-07-29 00:17:25 -07005165 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005166
Gustavo Padovan2d792812012-10-06 10:07:01 +01005167 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5168 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005169
Al Viro88219a02007-07-29 00:17:25 -07005170 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005171 BT_DBG("corrupted command");
5172 break;
5173 }
5174
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005175 if (conn->hcon->type == LE_LINK)
5176 err = l2cap_le_sig_cmd(conn, &cmd, data);
5177 else
5178 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005179
5180 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005181 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005182
5183 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005184
5185 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005186 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005187 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5188 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005189 }
5190
Al Viro88219a02007-07-29 00:17:25 -07005191 data += cmd_len;
5192 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005193 }
5194
5195 kfree_skb(skb);
5196}
5197
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005198static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005199{
5200 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005201 int hdr_size;
5202
5203 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5204 hdr_size = L2CAP_EXT_HDR_SIZE;
5205 else
5206 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005207
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005208 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005209 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005210 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5211 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5212
5213 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005214 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005215 }
5216 return 0;
5217}
5218
Mat Martineau6ea00482012-05-17 20:53:52 -07005219static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005220{
Mat Martineaue31f7632012-05-17 20:53:41 -07005221 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005222
Mat Martineaue31f7632012-05-17 20:53:41 -07005223 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005224
Mat Martineaue31f7632012-05-17 20:53:41 -07005225 memset(&control, 0, sizeof(control));
5226 control.sframe = 1;
5227 control.final = 1;
5228 control.reqseq = chan->buffer_seq;
5229 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005230
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005231 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005232 control.super = L2CAP_SUPER_RNR;
5233 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005234 }
5235
Mat Martineaue31f7632012-05-17 20:53:41 -07005236 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5237 chan->unacked_frames > 0)
5238 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005239
Mat Martineaue31f7632012-05-17 20:53:41 -07005240 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005241 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005242
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005243 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005244 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5245 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5246 * send it now.
5247 */
5248 control.super = L2CAP_SUPER_RR;
5249 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005250 }
5251}
5252
Gustavo Padovan2d792812012-10-06 10:07:01 +01005253static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5254 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005255{
Mat Martineau84084a32011-07-22 14:54:00 -07005256 /* skb->len reflects data in skb as well as all fragments
5257 * skb->data_len reflects only data in fragments
5258 */
5259 if (!skb_has_frag_list(skb))
5260 skb_shinfo(skb)->frag_list = new_frag;
5261
5262 new_frag->next = NULL;
5263
5264 (*last_frag)->next = new_frag;
5265 *last_frag = new_frag;
5266
5267 skb->len += new_frag->len;
5268 skb->data_len += new_frag->len;
5269 skb->truesize += new_frag->truesize;
5270}
5271
Mat Martineau4b51dae92012-05-17 20:53:37 -07005272static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5273 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005274{
5275 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005276
Mat Martineau4b51dae92012-05-17 20:53:37 -07005277 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005278 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005279 if (chan->sdu)
5280 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005281
Gustavo Padovan80b98022012-05-27 22:27:51 -03005282 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005283 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005284
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005285 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005286 if (chan->sdu)
5287 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005288
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005289 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005290 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005291
Mat Martineau84084a32011-07-22 14:54:00 -07005292 if (chan->sdu_len > chan->imtu) {
5293 err = -EMSGSIZE;
5294 break;
5295 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005296
Mat Martineau84084a32011-07-22 14:54:00 -07005297 if (skb->len >= chan->sdu_len)
5298 break;
5299
5300 chan->sdu = skb;
5301 chan->sdu_last_frag = skb;
5302
5303 skb = NULL;
5304 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005305 break;
5306
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005307 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005308 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005309 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005310
Mat Martineau84084a32011-07-22 14:54:00 -07005311 append_skb_frag(chan->sdu, skb,
5312 &chan->sdu_last_frag);
5313 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005314
Mat Martineau84084a32011-07-22 14:54:00 -07005315 if (chan->sdu->len >= chan->sdu_len)
5316 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005317
Mat Martineau84084a32011-07-22 14:54:00 -07005318 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005319 break;
5320
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005321 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005322 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005323 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005324
Mat Martineau84084a32011-07-22 14:54:00 -07005325 append_skb_frag(chan->sdu, skb,
5326 &chan->sdu_last_frag);
5327 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005328
Mat Martineau84084a32011-07-22 14:54:00 -07005329 if (chan->sdu->len != chan->sdu_len)
5330 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005331
Gustavo Padovan80b98022012-05-27 22:27:51 -03005332 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005333
Mat Martineau84084a32011-07-22 14:54:00 -07005334 if (!err) {
5335 /* Reassembly complete */
5336 chan->sdu = NULL;
5337 chan->sdu_last_frag = NULL;
5338 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005339 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005340 break;
5341 }
5342
Mat Martineau84084a32011-07-22 14:54:00 -07005343 if (err) {
5344 kfree_skb(skb);
5345 kfree_skb(chan->sdu);
5346 chan->sdu = NULL;
5347 chan->sdu_last_frag = NULL;
5348 chan->sdu_len = 0;
5349 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005350
Mat Martineau84084a32011-07-22 14:54:00 -07005351 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005352}
5353
Mat Martineau32b32732012-10-23 15:24:11 -07005354static int l2cap_resegment(struct l2cap_chan *chan)
5355{
5356 /* Placeholder */
5357 return 0;
5358}
5359
Mat Martineaue3281402011-07-07 09:39:02 -07005360void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005361{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005362 u8 event;
5363
5364 if (chan->mode != L2CAP_MODE_ERTM)
5365 return;
5366
5367 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005368 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005369}
5370
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005371static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5372{
Mat Martineau63838722012-05-17 20:53:45 -07005373 int err = 0;
5374 /* Pass sequential frames to l2cap_reassemble_sdu()
5375 * until a gap is encountered.
5376 */
5377
5378 BT_DBG("chan %p", chan);
5379
5380 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5381 struct sk_buff *skb;
5382 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5383 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5384
5385 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5386
5387 if (!skb)
5388 break;
5389
5390 skb_unlink(skb, &chan->srej_q);
5391 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5392 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5393 if (err)
5394 break;
5395 }
5396
5397 if (skb_queue_empty(&chan->srej_q)) {
5398 chan->rx_state = L2CAP_RX_STATE_RECV;
5399 l2cap_send_ack(chan);
5400 }
5401
5402 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005403}
5404
5405static void l2cap_handle_srej(struct l2cap_chan *chan,
5406 struct l2cap_ctrl *control)
5407{
Mat Martineauf80842a2012-05-17 20:53:46 -07005408 struct sk_buff *skb;
5409
5410 BT_DBG("chan %p, control %p", chan, control);
5411
5412 if (control->reqseq == chan->next_tx_seq) {
5413 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005414 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005415 return;
5416 }
5417
5418 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5419
5420 if (skb == NULL) {
5421 BT_DBG("Seq %d not available for retransmission",
5422 control->reqseq);
5423 return;
5424 }
5425
5426 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5427 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005428 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005429 return;
5430 }
5431
5432 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5433
5434 if (control->poll) {
5435 l2cap_pass_to_tx(chan, control);
5436
5437 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5438 l2cap_retransmit(chan, control);
5439 l2cap_ertm_send(chan);
5440
5441 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5442 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5443 chan->srej_save_reqseq = control->reqseq;
5444 }
5445 } else {
5446 l2cap_pass_to_tx_fbit(chan, control);
5447
5448 if (control->final) {
5449 if (chan->srej_save_reqseq != control->reqseq ||
5450 !test_and_clear_bit(CONN_SREJ_ACT,
5451 &chan->conn_state))
5452 l2cap_retransmit(chan, control);
5453 } else {
5454 l2cap_retransmit(chan, control);
5455 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5456 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5457 chan->srej_save_reqseq = control->reqseq;
5458 }
5459 }
5460 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005461}
5462
5463static void l2cap_handle_rej(struct l2cap_chan *chan,
5464 struct l2cap_ctrl *control)
5465{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005466 struct sk_buff *skb;
5467
5468 BT_DBG("chan %p, control %p", chan, control);
5469
5470 if (control->reqseq == chan->next_tx_seq) {
5471 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005472 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005473 return;
5474 }
5475
5476 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5477
5478 if (chan->max_tx && skb &&
5479 bt_cb(skb)->control.retries >= chan->max_tx) {
5480 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005481 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005482 return;
5483 }
5484
5485 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5486
5487 l2cap_pass_to_tx(chan, control);
5488
5489 if (control->final) {
5490 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5491 l2cap_retransmit_all(chan, control);
5492 } else {
5493 l2cap_retransmit_all(chan, control);
5494 l2cap_ertm_send(chan);
5495 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5496 set_bit(CONN_REJ_ACT, &chan->conn_state);
5497 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005498}
5499
Mat Martineau4b51dae92012-05-17 20:53:37 -07005500static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5501{
5502 BT_DBG("chan %p, txseq %d", chan, txseq);
5503
5504 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5505 chan->expected_tx_seq);
5506
5507 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5508 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005509 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005510 /* See notes below regarding "double poll" and
5511 * invalid packets.
5512 */
5513 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5514 BT_DBG("Invalid/Ignore - after SREJ");
5515 return L2CAP_TXSEQ_INVALID_IGNORE;
5516 } else {
5517 BT_DBG("Invalid - in window after SREJ sent");
5518 return L2CAP_TXSEQ_INVALID;
5519 }
5520 }
5521
5522 if (chan->srej_list.head == txseq) {
5523 BT_DBG("Expected SREJ");
5524 return L2CAP_TXSEQ_EXPECTED_SREJ;
5525 }
5526
5527 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5528 BT_DBG("Duplicate SREJ - txseq already stored");
5529 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5530 }
5531
5532 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5533 BT_DBG("Unexpected SREJ - not requested");
5534 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5535 }
5536 }
5537
5538 if (chan->expected_tx_seq == txseq) {
5539 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5540 chan->tx_win) {
5541 BT_DBG("Invalid - txseq outside tx window");
5542 return L2CAP_TXSEQ_INVALID;
5543 } else {
5544 BT_DBG("Expected");
5545 return L2CAP_TXSEQ_EXPECTED;
5546 }
5547 }
5548
5549 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005550 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005551 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5552 return L2CAP_TXSEQ_DUPLICATE;
5553 }
5554
5555 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5556 /* A source of invalid packets is a "double poll" condition,
5557 * where delays cause us to send multiple poll packets. If
5558 * the remote stack receives and processes both polls,
5559 * sequence numbers can wrap around in such a way that a
5560 * resent frame has a sequence number that looks like new data
5561 * with a sequence gap. This would trigger an erroneous SREJ
5562 * request.
5563 *
5564 * Fortunately, this is impossible with a tx window that's
5565 * less than half of the maximum sequence number, which allows
5566 * invalid frames to be safely ignored.
5567 *
5568 * With tx window sizes greater than half of the tx window
5569 * maximum, the frame is invalid and cannot be ignored. This
5570 * causes a disconnect.
5571 */
5572
5573 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5574 BT_DBG("Invalid/Ignore - txseq outside tx window");
5575 return L2CAP_TXSEQ_INVALID_IGNORE;
5576 } else {
5577 BT_DBG("Invalid - txseq outside tx window");
5578 return L2CAP_TXSEQ_INVALID;
5579 }
5580 } else {
5581 BT_DBG("Unexpected - txseq indicates missing frames");
5582 return L2CAP_TXSEQ_UNEXPECTED;
5583 }
5584}
5585
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005586static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5587 struct l2cap_ctrl *control,
5588 struct sk_buff *skb, u8 event)
5589{
5590 int err = 0;
5591 bool skb_in_use = 0;
5592
5593 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5594 event);
5595
5596 switch (event) {
5597 case L2CAP_EV_RECV_IFRAME:
5598 switch (l2cap_classify_txseq(chan, control->txseq)) {
5599 case L2CAP_TXSEQ_EXPECTED:
5600 l2cap_pass_to_tx(chan, control);
5601
5602 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5603 BT_DBG("Busy, discarding expected seq %d",
5604 control->txseq);
5605 break;
5606 }
5607
5608 chan->expected_tx_seq = __next_seq(chan,
5609 control->txseq);
5610
5611 chan->buffer_seq = chan->expected_tx_seq;
5612 skb_in_use = 1;
5613
5614 err = l2cap_reassemble_sdu(chan, skb, control);
5615 if (err)
5616 break;
5617
5618 if (control->final) {
5619 if (!test_and_clear_bit(CONN_REJ_ACT,
5620 &chan->conn_state)) {
5621 control->final = 0;
5622 l2cap_retransmit_all(chan, control);
5623 l2cap_ertm_send(chan);
5624 }
5625 }
5626
5627 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5628 l2cap_send_ack(chan);
5629 break;
5630 case L2CAP_TXSEQ_UNEXPECTED:
5631 l2cap_pass_to_tx(chan, control);
5632
5633 /* Can't issue SREJ frames in the local busy state.
5634 * Drop this frame, it will be seen as missing
5635 * when local busy is exited.
5636 */
5637 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5638 BT_DBG("Busy, discarding unexpected seq %d",
5639 control->txseq);
5640 break;
5641 }
5642
5643 /* There was a gap in the sequence, so an SREJ
5644 * must be sent for each missing frame. The
5645 * current frame is stored for later use.
5646 */
5647 skb_queue_tail(&chan->srej_q, skb);
5648 skb_in_use = 1;
5649 BT_DBG("Queued %p (queue len %d)", skb,
5650 skb_queue_len(&chan->srej_q));
5651
5652 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5653 l2cap_seq_list_clear(&chan->srej_list);
5654 l2cap_send_srej(chan, control->txseq);
5655
5656 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5657 break;
5658 case L2CAP_TXSEQ_DUPLICATE:
5659 l2cap_pass_to_tx(chan, control);
5660 break;
5661 case L2CAP_TXSEQ_INVALID_IGNORE:
5662 break;
5663 case L2CAP_TXSEQ_INVALID:
5664 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005665 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005666 break;
5667 }
5668 break;
5669 case L2CAP_EV_RECV_RR:
5670 l2cap_pass_to_tx(chan, control);
5671 if (control->final) {
5672 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5673
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005674 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5675 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005676 control->final = 0;
5677 l2cap_retransmit_all(chan, control);
5678 }
5679
5680 l2cap_ertm_send(chan);
5681 } else if (control->poll) {
5682 l2cap_send_i_or_rr_or_rnr(chan);
5683 } else {
5684 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5685 &chan->conn_state) &&
5686 chan->unacked_frames)
5687 __set_retrans_timer(chan);
5688
5689 l2cap_ertm_send(chan);
5690 }
5691 break;
5692 case L2CAP_EV_RECV_RNR:
5693 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5694 l2cap_pass_to_tx(chan, control);
5695 if (control && control->poll) {
5696 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5697 l2cap_send_rr_or_rnr(chan, 0);
5698 }
5699 __clear_retrans_timer(chan);
5700 l2cap_seq_list_clear(&chan->retrans_list);
5701 break;
5702 case L2CAP_EV_RECV_REJ:
5703 l2cap_handle_rej(chan, control);
5704 break;
5705 case L2CAP_EV_RECV_SREJ:
5706 l2cap_handle_srej(chan, control);
5707 break;
5708 default:
5709 break;
5710 }
5711
5712 if (skb && !skb_in_use) {
5713 BT_DBG("Freeing %p", skb);
5714 kfree_skb(skb);
5715 }
5716
5717 return err;
5718}
5719
5720static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5721 struct l2cap_ctrl *control,
5722 struct sk_buff *skb, u8 event)
5723{
5724 int err = 0;
5725 u16 txseq = control->txseq;
5726 bool skb_in_use = 0;
5727
5728 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5729 event);
5730
5731 switch (event) {
5732 case L2CAP_EV_RECV_IFRAME:
5733 switch (l2cap_classify_txseq(chan, txseq)) {
5734 case L2CAP_TXSEQ_EXPECTED:
5735 /* Keep frame for reassembly later */
5736 l2cap_pass_to_tx(chan, control);
5737 skb_queue_tail(&chan->srej_q, skb);
5738 skb_in_use = 1;
5739 BT_DBG("Queued %p (queue len %d)", skb,
5740 skb_queue_len(&chan->srej_q));
5741
5742 chan->expected_tx_seq = __next_seq(chan, txseq);
5743 break;
5744 case L2CAP_TXSEQ_EXPECTED_SREJ:
5745 l2cap_seq_list_pop(&chan->srej_list);
5746
5747 l2cap_pass_to_tx(chan, control);
5748 skb_queue_tail(&chan->srej_q, skb);
5749 skb_in_use = 1;
5750 BT_DBG("Queued %p (queue len %d)", skb,
5751 skb_queue_len(&chan->srej_q));
5752
5753 err = l2cap_rx_queued_iframes(chan);
5754 if (err)
5755 break;
5756
5757 break;
5758 case L2CAP_TXSEQ_UNEXPECTED:
5759 /* Got a frame that can't be reassembled yet.
5760 * Save it for later, and send SREJs to cover
5761 * the missing frames.
5762 */
5763 skb_queue_tail(&chan->srej_q, skb);
5764 skb_in_use = 1;
5765 BT_DBG("Queued %p (queue len %d)", skb,
5766 skb_queue_len(&chan->srej_q));
5767
5768 l2cap_pass_to_tx(chan, control);
5769 l2cap_send_srej(chan, control->txseq);
5770 break;
5771 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
5772 /* This frame was requested with an SREJ, but
5773 * some expected retransmitted frames are
5774 * missing. Request retransmission of missing
5775 * SREJ'd frames.
5776 */
5777 skb_queue_tail(&chan->srej_q, skb);
5778 skb_in_use = 1;
5779 BT_DBG("Queued %p (queue len %d)", skb,
5780 skb_queue_len(&chan->srej_q));
5781
5782 l2cap_pass_to_tx(chan, control);
5783 l2cap_send_srej_list(chan, control->txseq);
5784 break;
5785 case L2CAP_TXSEQ_DUPLICATE_SREJ:
5786 /* We've already queued this frame. Drop this copy. */
5787 l2cap_pass_to_tx(chan, control);
5788 break;
5789 case L2CAP_TXSEQ_DUPLICATE:
5790 /* Expecting a later sequence number, so this frame
5791 * was already received. Ignore it completely.
5792 */
5793 break;
5794 case L2CAP_TXSEQ_INVALID_IGNORE:
5795 break;
5796 case L2CAP_TXSEQ_INVALID:
5797 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005798 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005799 break;
5800 }
5801 break;
5802 case L2CAP_EV_RECV_RR:
5803 l2cap_pass_to_tx(chan, control);
5804 if (control->final) {
5805 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5806
5807 if (!test_and_clear_bit(CONN_REJ_ACT,
5808 &chan->conn_state)) {
5809 control->final = 0;
5810 l2cap_retransmit_all(chan, control);
5811 }
5812
5813 l2cap_ertm_send(chan);
5814 } else if (control->poll) {
5815 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5816 &chan->conn_state) &&
5817 chan->unacked_frames) {
5818 __set_retrans_timer(chan);
5819 }
5820
5821 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5822 l2cap_send_srej_tail(chan);
5823 } else {
5824 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5825 &chan->conn_state) &&
5826 chan->unacked_frames)
5827 __set_retrans_timer(chan);
5828
5829 l2cap_send_ack(chan);
5830 }
5831 break;
5832 case L2CAP_EV_RECV_RNR:
5833 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5834 l2cap_pass_to_tx(chan, control);
5835 if (control->poll) {
5836 l2cap_send_srej_tail(chan);
5837 } else {
5838 struct l2cap_ctrl rr_control;
5839 memset(&rr_control, 0, sizeof(rr_control));
5840 rr_control.sframe = 1;
5841 rr_control.super = L2CAP_SUPER_RR;
5842 rr_control.reqseq = chan->buffer_seq;
5843 l2cap_send_sframe(chan, &rr_control);
5844 }
5845
5846 break;
5847 case L2CAP_EV_RECV_REJ:
5848 l2cap_handle_rej(chan, control);
5849 break;
5850 case L2CAP_EV_RECV_SREJ:
5851 l2cap_handle_srej(chan, control);
5852 break;
5853 }
5854
5855 if (skb && !skb_in_use) {
5856 BT_DBG("Freeing %p", skb);
5857 kfree_skb(skb);
5858 }
5859
5860 return err;
5861}
5862
Mat Martineau32b32732012-10-23 15:24:11 -07005863static int l2cap_finish_move(struct l2cap_chan *chan)
5864{
5865 BT_DBG("chan %p", chan);
5866
5867 chan->rx_state = L2CAP_RX_STATE_RECV;
5868
5869 if (chan->hs_hcon)
5870 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
5871 else
5872 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
5873
5874 return l2cap_resegment(chan);
5875}
5876
5877static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
5878 struct l2cap_ctrl *control,
5879 struct sk_buff *skb, u8 event)
5880{
5881 int err;
5882
5883 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5884 event);
5885
5886 if (!control->poll)
5887 return -EPROTO;
5888
5889 l2cap_process_reqseq(chan, control->reqseq);
5890
5891 if (!skb_queue_empty(&chan->tx_q))
5892 chan->tx_send_head = skb_peek(&chan->tx_q);
5893 else
5894 chan->tx_send_head = NULL;
5895
5896 /* Rewind next_tx_seq to the point expected
5897 * by the receiver.
5898 */
5899 chan->next_tx_seq = control->reqseq;
5900 chan->unacked_frames = 0;
5901
5902 err = l2cap_finish_move(chan);
5903 if (err)
5904 return err;
5905
5906 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5907 l2cap_send_i_or_rr_or_rnr(chan);
5908
5909 if (event == L2CAP_EV_RECV_IFRAME)
5910 return -EPROTO;
5911
5912 return l2cap_rx_state_recv(chan, control, NULL, event);
5913}
5914
5915static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
5916 struct l2cap_ctrl *control,
5917 struct sk_buff *skb, u8 event)
5918{
5919 int err;
5920
5921 if (!control->final)
5922 return -EPROTO;
5923
5924 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5925
5926 chan->rx_state = L2CAP_RX_STATE_RECV;
5927 l2cap_process_reqseq(chan, control->reqseq);
5928
5929 if (!skb_queue_empty(&chan->tx_q))
5930 chan->tx_send_head = skb_peek(&chan->tx_q);
5931 else
5932 chan->tx_send_head = NULL;
5933
5934 /* Rewind next_tx_seq to the point expected
5935 * by the receiver.
5936 */
5937 chan->next_tx_seq = control->reqseq;
5938 chan->unacked_frames = 0;
5939
5940 if (chan->hs_hcon)
5941 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
5942 else
5943 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
5944
5945 err = l2cap_resegment(chan);
5946
5947 if (!err)
5948 err = l2cap_rx_state_recv(chan, control, skb, event);
5949
5950 return err;
5951}
5952
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005953static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
5954{
5955 /* Make sure reqseq is for a packet that has been sent but not acked */
5956 u16 unacked;
5957
5958 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
5959 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
5960}
5961
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005962static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5963 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005964{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005965 int err = 0;
5966
5967 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
5968 control, skb, event, chan->rx_state);
5969
5970 if (__valid_reqseq(chan, control->reqseq)) {
5971 switch (chan->rx_state) {
5972 case L2CAP_RX_STATE_RECV:
5973 err = l2cap_rx_state_recv(chan, control, skb, event);
5974 break;
5975 case L2CAP_RX_STATE_SREJ_SENT:
5976 err = l2cap_rx_state_srej_sent(chan, control, skb,
5977 event);
5978 break;
Mat Martineau32b32732012-10-23 15:24:11 -07005979 case L2CAP_RX_STATE_WAIT_P:
5980 err = l2cap_rx_state_wait_p(chan, control, skb, event);
5981 break;
5982 case L2CAP_RX_STATE_WAIT_F:
5983 err = l2cap_rx_state_wait_f(chan, control, skb, event);
5984 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005985 default:
5986 /* shut it down */
5987 break;
5988 }
5989 } else {
5990 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
5991 control->reqseq, chan->next_tx_seq,
5992 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005993 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005994 }
5995
5996 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005997}
5998
5999static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6000 struct sk_buff *skb)
6001{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006002 int err = 0;
6003
6004 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6005 chan->rx_state);
6006
6007 if (l2cap_classify_txseq(chan, control->txseq) ==
6008 L2CAP_TXSEQ_EXPECTED) {
6009 l2cap_pass_to_tx(chan, control);
6010
6011 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6012 __next_seq(chan, chan->buffer_seq));
6013
6014 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6015
6016 l2cap_reassemble_sdu(chan, skb, control);
6017 } else {
6018 if (chan->sdu) {
6019 kfree_skb(chan->sdu);
6020 chan->sdu = NULL;
6021 }
6022 chan->sdu_last_frag = NULL;
6023 chan->sdu_len = 0;
6024
6025 if (skb) {
6026 BT_DBG("Freeing %p", skb);
6027 kfree_skb(skb);
6028 }
6029 }
6030
6031 chan->last_acked_seq = control->txseq;
6032 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6033
6034 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006035}
6036
6037static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6038{
6039 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6040 u16 len;
6041 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006042
Mat Martineaub76bbd62012-04-11 10:48:43 -07006043 __unpack_control(chan, skb);
6044
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006045 len = skb->len;
6046
6047 /*
6048 * We can just drop the corrupted I-frame here.
6049 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006050 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006051 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006052 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006053 goto drop;
6054
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006055 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006056 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006057
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006058 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006059 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006060
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006061 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006062 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006063 goto drop;
6064 }
6065
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006066 if (!control->sframe) {
6067 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006068
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006069 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6070 control->sar, control->reqseq, control->final,
6071 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006072
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006073 /* Validate F-bit - F=0 always valid, F=1 only
6074 * valid in TX WAIT_F
6075 */
6076 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006077 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006078
6079 if (chan->mode != L2CAP_MODE_STREAMING) {
6080 event = L2CAP_EV_RECV_IFRAME;
6081 err = l2cap_rx(chan, control, skb, event);
6082 } else {
6083 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006084 }
6085
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006086 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006087 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006088 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006089 const u8 rx_func_to_event[4] = {
6090 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6091 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6092 };
6093
6094 /* Only I-frames are expected in streaming mode */
6095 if (chan->mode == L2CAP_MODE_STREAMING)
6096 goto drop;
6097
6098 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6099 control->reqseq, control->final, control->poll,
6100 control->super);
6101
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006102 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006103 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006104 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006105 goto drop;
6106 }
6107
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006108 /* Validate F and P bits */
6109 if (control->final && (control->poll ||
6110 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6111 goto drop;
6112
6113 event = rx_func_to_event[control->super];
6114 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006115 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006116 }
6117
6118 return 0;
6119
6120drop:
6121 kfree_skb(skb);
6122 return 0;
6123}
6124
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006125static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6126 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006127{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006128 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006129
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006130 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006131 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006132 if (cid == L2CAP_CID_A2MP) {
6133 chan = a2mp_channel_create(conn, skb);
6134 if (!chan) {
6135 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006136 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006137 }
6138
6139 l2cap_chan_lock(chan);
6140 } else {
6141 BT_DBG("unknown cid 0x%4.4x", cid);
6142 /* Drop packet and return */
6143 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006144 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006145 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006146 }
6147
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006148 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006149
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006150 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006151 goto drop;
6152
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006153 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006154 case L2CAP_MODE_BASIC:
6155 /* If socket recv buffers overflows we drop data here
6156 * which is *bad* because L2CAP has to be reliable.
6157 * But we don't have any other choice. L2CAP doesn't
6158 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006159
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006160 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006161 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006162
Gustavo Padovan80b98022012-05-27 22:27:51 -03006163 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006164 goto done;
6165 break;
6166
6167 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006168 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006169 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006170 goto done;
6171
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006172 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006173 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006174 break;
6175 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006176
6177drop:
6178 kfree_skb(skb);
6179
6180done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006181 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006182}
6183
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006184static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6185 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006186{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006187 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006188
Ido Yarivc2287682012-04-20 15:46:07 -03006189 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006190 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006191 goto drop;
6192
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006193 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006194
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006195 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006196 goto drop;
6197
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006198 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006199 goto drop;
6200
Gustavo Padovan80b98022012-05-27 22:27:51 -03006201 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006202 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006203
6204drop:
6205 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006206}
6207
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006208static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
6209 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006210{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006211 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006212
Ido Yarivc2287682012-04-20 15:46:07 -03006213 chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006214 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006215 goto drop;
6216
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006217 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006218
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006219 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006220 goto drop;
6221
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006222 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006223 goto drop;
6224
Gustavo Padovan80b98022012-05-27 22:27:51 -03006225 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006226 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006227
6228drop:
6229 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006230}
6231
Linus Torvalds1da177e2005-04-16 15:20:36 -07006232static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6233{
6234 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006235 u16 cid, len;
6236 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006237
6238 skb_pull(skb, L2CAP_HDR_SIZE);
6239 cid = __le16_to_cpu(lh->cid);
6240 len = __le16_to_cpu(lh->len);
6241
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006242 if (len != skb->len) {
6243 kfree_skb(skb);
6244 return;
6245 }
6246
Linus Torvalds1da177e2005-04-16 15:20:36 -07006247 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6248
6249 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02006250 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006251 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006252 l2cap_sig_channel(conn, skb);
6253 break;
6254
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006255 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006256 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006257 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006258 l2cap_conless_channel(conn, psm, skb);
6259 break;
6260
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006261 case L2CAP_CID_LE_DATA:
6262 l2cap_att_channel(conn, cid, skb);
6263 break;
6264
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006265 case L2CAP_CID_SMP:
6266 if (smp_sig_channel(conn, skb))
6267 l2cap_conn_del(conn->hcon, EACCES);
6268 break;
6269
Linus Torvalds1da177e2005-04-16 15:20:36 -07006270 default:
6271 l2cap_data_channel(conn, cid, skb);
6272 break;
6273 }
6274}
6275
6276/* ---- L2CAP interface with lower layer (HCI) ---- */
6277
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006278int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006279{
6280 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006281 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006282
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006283 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006284
6285 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006286 read_lock(&chan_list_lock);
6287 list_for_each_entry(c, &chan_list, global_l) {
6288 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006289
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006290 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006291 continue;
6292
6293 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006294 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006295 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006296 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006297 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006298 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
6299 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006300 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006301 lm2 |= HCI_LM_MASTER;
6302 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006303 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006304 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006305
6306 return exact ? lm1 : lm2;
6307}
6308
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006309void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006310{
Marcel Holtmann01394182006-07-03 10:02:46 +02006311 struct l2cap_conn *conn;
6312
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006313 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006314
Linus Torvalds1da177e2005-04-16 15:20:36 -07006315 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006316 conn = l2cap_conn_add(hcon, status);
6317 if (conn)
6318 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006319 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006320 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006321 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006322}
6323
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006324int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006325{
6326 struct l2cap_conn *conn = hcon->l2cap_data;
6327
6328 BT_DBG("hcon %p", hcon);
6329
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006330 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006331 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006332 return conn->disc_reason;
6333}
6334
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006335void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006336{
6337 BT_DBG("hcon %p reason %d", hcon, reason);
6338
Joe Perchese1750722011-06-29 18:18:29 -07006339 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006340}
6341
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006342static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006343{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006344 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006345 return;
6346
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006347 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006348 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006349 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006350 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006351 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006352 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006353 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006354 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006355 }
6356}
6357
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006358int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006359{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006360 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006361 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006362
Marcel Holtmann01394182006-07-03 10:02:46 +02006363 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006364 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006365
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006366 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006367
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006368 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306369 if (!status && encrypt)
6370 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006371 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006372 }
6373
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006374 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006375
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006376 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006377 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006378
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006379 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6380 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006381
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006382 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6383 l2cap_chan_unlock(chan);
6384 continue;
6385 }
6386
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006387 if (chan->scid == L2CAP_CID_LE_DATA) {
6388 if (!status && encrypt) {
6389 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006390 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006391 }
6392
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006393 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006394 continue;
6395 }
6396
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006397 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006398 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006399 continue;
6400 }
6401
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006402 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006403 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03006404 struct sock *sk = chan->sk;
6405
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006406 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03006407 sk->sk_state_change(sk);
6408
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006409 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006410 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006411 continue;
6412 }
6413
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006414 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006415 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006416 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006417 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006418 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006419 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006420 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006421 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006422 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006423 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006424
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006425 lock_sock(sk);
6426
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006427 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006428 if (test_bit(BT_SK_DEFER_SETUP,
6429 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006430 res = L2CAP_CR_PEND;
6431 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006432 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006433 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006434 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006435 res = L2CAP_CR_SUCCESS;
6436 stat = L2CAP_CS_NO_INFO;
6437 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006438 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006439 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006440 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006441 res = L2CAP_CR_SEC_BLOCK;
6442 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006443 }
6444
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006445 release_sock(sk);
6446
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006447 rsp.scid = cpu_to_le16(chan->dcid);
6448 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006449 rsp.result = cpu_to_le16(res);
6450 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006451 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006452 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006453
6454 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6455 res == L2CAP_CR_SUCCESS) {
6456 char buf[128];
6457 set_bit(CONF_REQ_SENT, &chan->conf_state);
6458 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6459 L2CAP_CONF_REQ,
6460 l2cap_build_conf_req(chan, buf),
6461 buf);
6462 chan->num_conf_req++;
6463 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006464 }
6465
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006466 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006467 }
6468
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006469 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006470
Linus Torvalds1da177e2005-04-16 15:20:36 -07006471 return 0;
6472}
6473
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006474int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006475{
6476 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006477 struct l2cap_hdr *hdr;
6478 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006479
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006480 /* For AMP controller do not create l2cap conn */
6481 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6482 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006483
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006484 if (!conn)
6485 conn = l2cap_conn_add(hcon, 0);
6486
6487 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006488 goto drop;
6489
6490 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6491
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006492 switch (flags) {
6493 case ACL_START:
6494 case ACL_START_NO_FLUSH:
6495 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006496 if (conn->rx_len) {
6497 BT_ERR("Unexpected start frame (len %d)", skb->len);
6498 kfree_skb(conn->rx_skb);
6499 conn->rx_skb = NULL;
6500 conn->rx_len = 0;
6501 l2cap_conn_unreliable(conn, ECOMM);
6502 }
6503
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006504 /* Start fragment always begin with Basic L2CAP header */
6505 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006506 BT_ERR("Frame is too short (len %d)", skb->len);
6507 l2cap_conn_unreliable(conn, ECOMM);
6508 goto drop;
6509 }
6510
6511 hdr = (struct l2cap_hdr *) skb->data;
6512 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6513
6514 if (len == skb->len) {
6515 /* Complete frame received */
6516 l2cap_recv_frame(conn, skb);
6517 return 0;
6518 }
6519
6520 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6521
6522 if (skb->len > len) {
6523 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006524 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006525 l2cap_conn_unreliable(conn, ECOMM);
6526 goto drop;
6527 }
6528
6529 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006530 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006531 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006532 goto drop;
6533
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006534 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006535 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006536 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006537 break;
6538
6539 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006540 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6541
6542 if (!conn->rx_len) {
6543 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6544 l2cap_conn_unreliable(conn, ECOMM);
6545 goto drop;
6546 }
6547
6548 if (skb->len > conn->rx_len) {
6549 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006550 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006551 kfree_skb(conn->rx_skb);
6552 conn->rx_skb = NULL;
6553 conn->rx_len = 0;
6554 l2cap_conn_unreliable(conn, ECOMM);
6555 goto drop;
6556 }
6557
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006558 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006559 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006560 conn->rx_len -= skb->len;
6561
6562 if (!conn->rx_len) {
6563 /* Complete frame received */
6564 l2cap_recv_frame(conn, conn->rx_skb);
6565 conn->rx_skb = NULL;
6566 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006567 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006568 }
6569
6570drop:
6571 kfree_skb(skb);
6572 return 0;
6573}
6574
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006575static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006576{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006577 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006578
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006579 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006580
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006581 list_for_each_entry(c, &chan_list, global_l) {
6582 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006583
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006584 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
6585 &bt_sk(sk)->src, &bt_sk(sk)->dst,
6586 c->state, __le16_to_cpu(c->psm),
6587 c->scid, c->dcid, c->imtu, c->omtu,
6588 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006589 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006590
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006591 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006592
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006593 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006594}
6595
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006596static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6597{
6598 return single_open(file, l2cap_debugfs_show, inode->i_private);
6599}
6600
6601static const struct file_operations l2cap_debugfs_fops = {
6602 .open = l2cap_debugfs_open,
6603 .read = seq_read,
6604 .llseek = seq_lseek,
6605 .release = single_release,
6606};
6607
6608static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006609
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006610int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006611{
6612 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006613
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006614 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006615 if (err < 0)
6616 return err;
6617
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006618 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006619 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6620 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006621 if (!l2cap_debugfs)
6622 BT_ERR("Failed to create L2CAP debug file");
6623 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006624
Linus Torvalds1da177e2005-04-16 15:20:36 -07006625 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006626}
6627
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006628void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006629{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006630 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006631 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006632}
6633
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006634module_param(disable_ertm, bool, 0644);
6635MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");