blob: df5670d8e11d8b4234b33bf9867deb1186b95573 [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>
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070039
Marcel Holtmannac4b7232013-10-10 14:54:16 -070040#include "smp.h"
Marcel Holtmann70247282013-10-10 14:54:15 -070041#include "a2mp.h"
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070042#include "amp.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
Mat Martineaud1de6d42012-05-17 20:53:55 -070044bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020045
Marcel Holtmann547d1032013-10-12 08:18:19 -070046static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN | L2CAP_FEAT_UCD;
Marcel Holtmannd40bffb2013-10-12 08:18:18 -070047static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP | L2CAP_FC_CONNLESS, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Johannes Bergb5ad8b72011-06-01 08:54:45 +020049static LIST_HEAD(chan_list);
50static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Linus Torvalds1da177e2005-04-16 15:20:36 -070052static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010053 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030054static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010055 void *data);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -030056static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +020057static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
Gustavo Padovand6603662012-05-21 13:58:22 -030059static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010060 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070061
Marcel Holtmann4f1654e2013-10-13 08:50:41 -070062static inline __u8 bdaddr_type(struct hci_conn *hcon, __u8 type)
63{
64 if (hcon->type == LE_LINK) {
65 if (type == ADDR_LE_DEV_PUBLIC)
66 return BDADDR_LE_PUBLIC;
67 else
68 return BDADDR_LE_RANDOM;
69 }
70
71 return BDADDR_BREDR;
72}
73
Marcel Holtmann01394182006-07-03 10:02:46 +020074/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030075
Gustavo Padovan2d792812012-10-06 10:07:01 +010076static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
77 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020078{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020079 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030080
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020081 list_for_each_entry(c, &conn->chan_l, list) {
82 if (c->dcid == cid)
83 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020084 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020085 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020086}
87
Gustavo Padovan2d792812012-10-06 10:07:01 +010088static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
89 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020090{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020091 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030092
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020093 list_for_each_entry(c, &conn->chan_l, list) {
94 if (c->scid == cid)
95 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020096 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020097 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020098}
99
100/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -0700101 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +0100102static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
103 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +0200104{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300105 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300106
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200107 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300108 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -0700109 if (c)
110 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200111 mutex_unlock(&conn->chan_lock);
112
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300113 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200114}
115
Mat Martineaub1a130b2012-10-23 15:24:09 -0700116/* Find channel with given DCID.
117 * Returns locked channel.
118 */
119static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
120 u16 cid)
121{
122 struct l2cap_chan *c;
123
124 mutex_lock(&conn->chan_lock);
125 c = __l2cap_get_chan_by_dcid(conn, cid);
126 if (c)
127 l2cap_chan_lock(c);
128 mutex_unlock(&conn->chan_lock);
129
130 return c;
131}
132
Gustavo Padovan2d792812012-10-06 10:07:01 +0100133static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
134 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200135{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200136 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300137
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200138 list_for_each_entry(c, &conn->chan_l, list) {
139 if (c->ident == ident)
140 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200141 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200142 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200143}
144
Mat Martineau5b155ef2012-10-23 15:24:14 -0700145static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
146 u8 ident)
147{
148 struct l2cap_chan *c;
149
150 mutex_lock(&conn->chan_lock);
151 c = __l2cap_get_chan_by_ident(conn, ident);
152 if (c)
153 l2cap_chan_lock(c);
154 mutex_unlock(&conn->chan_lock);
155
156 return c;
157}
158
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300159static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300160{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300161 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300162
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300163 list_for_each_entry(c, &chan_list, global_l) {
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700164 if (c->sport == psm && !bacmp(&c->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100165 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300166 }
Szymon Janc250938c2011-11-16 09:32:22 +0100167 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300168}
169
170int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
171{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300172 int err;
173
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200174 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300175
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300176 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300177 err = -EADDRINUSE;
178 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300179 }
180
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300181 if (psm) {
182 chan->psm = psm;
183 chan->sport = psm;
184 err = 0;
185 } else {
186 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300187
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300188 err = -EINVAL;
189 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300190 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300191 chan->psm = cpu_to_le16(p);
192 chan->sport = cpu_to_le16(p);
193 err = 0;
194 break;
195 }
196 }
197
198done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200199 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300200 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300201}
202
203int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
204{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200205 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300206
207 chan->scid = scid;
208
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200209 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300210
211 return 0;
212}
213
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300214static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200215{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300216 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200217
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300218 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300219 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200220 return cid;
221 }
222
223 return 0;
224}
225
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200226static void __l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300227{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200228 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100229 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200230
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300231 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300232 chan->ops->state_change(chan, state, 0);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300233}
234
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200235static void l2cap_state_change(struct l2cap_chan *chan, int state)
236{
237 struct sock *sk = chan->sk;
238
239 lock_sock(sk);
240 __l2cap_state_change(chan, state);
241 release_sock(sk);
242}
243
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200244static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
245{
Gustavo Padovan53f52122013-10-15 19:24:45 -0300246 chan->ops->state_change(chan, chan->state, err);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200247}
248
249static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
250{
251 struct sock *sk = chan->sk;
252
253 lock_sock(sk);
254 __l2cap_chan_set_err(chan, err);
255 release_sock(sk);
256}
257
Mat Martineau4239d162012-05-17 20:53:49 -0700258static void __set_retrans_timer(struct l2cap_chan *chan)
259{
260 if (!delayed_work_pending(&chan->monitor_timer) &&
261 chan->retrans_timeout) {
262 l2cap_set_timer(chan, &chan->retrans_timer,
263 msecs_to_jiffies(chan->retrans_timeout));
264 }
265}
266
267static void __set_monitor_timer(struct l2cap_chan *chan)
268{
269 __clear_retrans_timer(chan);
270 if (chan->monitor_timeout) {
271 l2cap_set_timer(chan, &chan->monitor_timer,
272 msecs_to_jiffies(chan->monitor_timeout));
273 }
274}
275
Mat Martineau608bcc62012-05-17 20:53:32 -0700276static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
277 u16 seq)
278{
279 struct sk_buff *skb;
280
281 skb_queue_walk(head, skb) {
282 if (bt_cb(skb)->control.txseq == seq)
283 return skb;
284 }
285
286 return NULL;
287}
288
Mat Martineau3c588192012-04-11 10:48:42 -0700289/* ---- L2CAP sequence number lists ---- */
290
291/* For ERTM, ordered lists of sequence numbers must be tracked for
292 * SREJ requests that are received and for frames that are to be
293 * retransmitted. These seq_list functions implement a singly-linked
294 * list in an array, where membership in the list can also be checked
295 * in constant time. Items can also be added to the tail of the list
296 * and removed from the head in constant time, without further memory
297 * allocs or frees.
298 */
299
300static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
301{
302 size_t alloc_size, i;
303
304 /* Allocated size is a power of 2 to map sequence numbers
305 * (which may be up to 14 bits) in to a smaller array that is
306 * sized for the negotiated ERTM transmit windows.
307 */
308 alloc_size = roundup_pow_of_two(size);
309
310 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
311 if (!seq_list->list)
312 return -ENOMEM;
313
314 seq_list->mask = alloc_size - 1;
315 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
316 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
317 for (i = 0; i < alloc_size; i++)
318 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
319
320 return 0;
321}
322
323static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
324{
325 kfree(seq_list->list);
326}
327
328static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
329 u16 seq)
330{
331 /* Constant-time check for list membership */
332 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
333}
334
335static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
336{
337 u16 mask = seq_list->mask;
338
339 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
340 /* In case someone tries to pop the head of an empty list */
341 return L2CAP_SEQ_LIST_CLEAR;
342 } else if (seq_list->head == seq) {
343 /* Head can be removed in constant time */
344 seq_list->head = seq_list->list[seq & mask];
345 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
346
347 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
348 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
349 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
350 }
351 } else {
352 /* Walk the list to find the sequence number */
353 u16 prev = seq_list->head;
354 while (seq_list->list[prev & mask] != seq) {
355 prev = seq_list->list[prev & mask];
356 if (prev == L2CAP_SEQ_LIST_TAIL)
357 return L2CAP_SEQ_LIST_CLEAR;
358 }
359
360 /* Unlink the number from the list and clear it */
361 seq_list->list[prev & mask] = seq_list->list[seq & mask];
362 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
363 if (seq_list->tail == seq)
364 seq_list->tail = prev;
365 }
366 return seq;
367}
368
369static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
370{
371 /* Remove the head in constant time */
372 return l2cap_seq_list_remove(seq_list, seq_list->head);
373}
374
375static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
376{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300377 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700378
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300379 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
380 return;
381
382 for (i = 0; i <= seq_list->mask; i++)
383 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
384
385 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
386 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700387}
388
389static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
390{
391 u16 mask = seq_list->mask;
392
393 /* All appends happen in constant time */
394
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300395 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
396 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700397
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300398 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
399 seq_list->head = seq;
400 else
401 seq_list->list[seq_list->tail & mask] = seq;
402
403 seq_list->tail = seq;
404 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700405}
406
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300407static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300408{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300409 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100410 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200411 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300412 int reason;
413
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200414 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300415
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200416 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200417 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300418
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300419 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300420 reason = ECONNREFUSED;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300421 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100422 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300423 reason = ECONNREFUSED;
424 else
425 reason = ETIMEDOUT;
426
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300427 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300428
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200429 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300430
Gustavo Padovan80b98022012-05-27 22:27:51 -0300431 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200432 mutex_unlock(&conn->chan_lock);
433
Ulisses Furquim371fd832011-12-21 20:02:36 -0200434 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300435}
436
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300437struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200438{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300439 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200440
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300441 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
442 if (!chan)
443 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200444
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200445 mutex_init(&chan->lock);
446
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200447 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300448 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200449 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300450
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300451 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300452
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300453 chan->state = BT_OPEN;
454
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530455 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300456
Mat Martineau28270112012-05-17 21:14:09 -0700457 /* This flag is cleared in l2cap_chan_ready() */
458 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
459
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300460 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100461
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300462 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200463}
464
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530465static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300466{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530467 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
468
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530469 BT_DBG("chan %p", chan);
470
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200471 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300472 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200473 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300474
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530475 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300476}
477
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530478void l2cap_chan_hold(struct l2cap_chan *c)
479{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530480 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530481
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530482 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530483}
484
485void l2cap_chan_put(struct l2cap_chan *c)
486{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530487 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530488
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530489 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530490}
491
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300492void l2cap_chan_set_defaults(struct l2cap_chan *chan)
493{
494 chan->fcs = L2CAP_FCS_CRC16;
495 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
496 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
497 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700498 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300499 chan->sec_level = BT_SECURITY_LOW;
500
501 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
502}
503
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300504void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200505{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300506 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200507 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200508
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200509 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100510
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300511 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200512
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200513 switch (chan->chan_type) {
514 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300515 if (conn->hcon->type == LE_LINK) {
516 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300517 chan->omtu = L2CAP_DEFAULT_MTU;
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300518 if (chan->dcid == L2CAP_CID_ATT)
519 chan->scid = L2CAP_CID_ATT;
520 else
521 chan->scid = l2cap_alloc_cid(conn);
Ville Tervob62f3282011-02-10 22:38:50 -0300522 } else {
523 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300524 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300525 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300526 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200527 break;
528
529 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200530 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300531 chan->scid = L2CAP_CID_CONN_LESS;
532 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300533 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200534 break;
535
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300536 case L2CAP_CHAN_CONN_FIX_A2MP:
537 chan->scid = L2CAP_CID_A2MP;
538 chan->dcid = L2CAP_CID_A2MP;
539 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
540 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
541 break;
542
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200543 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200544 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300545 chan->scid = L2CAP_CID_SIGNALING;
546 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300547 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200548 }
549
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300550 chan->local_id = L2CAP_BESTEFFORT_ID;
551 chan->local_stype = L2CAP_SERV_BESTEFFORT;
552 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
553 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
554 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300555 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300556
Ulisses Furquim371fd832011-12-21 20:02:36 -0200557 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300558
Johan Hedberg5ee98912013-04-29 19:35:43 +0300559 hci_conn_hold(conn->hcon);
560
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200561 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200562}
563
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300564void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200565{
566 mutex_lock(&conn->chan_lock);
567 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200568 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200569}
570
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300571void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200572{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300573 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200574
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300575 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200576
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300577 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200578
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900579 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300580 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300581 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200582 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200583
Ulisses Furquim371fd832011-12-21 20:02:36 -0200584 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300585
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300586 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300587
588 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200589 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300590
591 if (mgr && mgr->bredr_chan == chan)
592 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200593 }
594
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200595 if (chan->hs_hchan) {
596 struct hci_chan *hs_hchan = chan->hs_hchan;
597
598 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
599 amp_disconnect_logical_link(hs_hchan);
600 }
601
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100602 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200603
Mat Martineau28270112012-05-17 21:14:09 -0700604 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300605 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300606
Gustavo Padovanee556f62012-05-18 20:22:38 -0300607 switch(chan->mode) {
608 case L2CAP_MODE_BASIC:
609 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300610
Gustavo Padovanee556f62012-05-18 20:22:38 -0300611 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300612 __clear_retrans_timer(chan);
613 __clear_monitor_timer(chan);
614 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300615
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300616 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300617
Mat Martineau3c588192012-04-11 10:48:42 -0700618 l2cap_seq_list_free(&chan->srej_list);
619 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300620
621 /* fall through */
622
623 case L2CAP_MODE_STREAMING:
624 skb_queue_purge(&chan->tx_q);
625 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300626 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300627
628 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200629}
630
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300631void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300632{
633 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300634
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700635 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300636
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300637 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300638 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100639 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300640 break;
641
642 case BT_CONNECTED:
643 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300644 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100645 conn->hcon->type == ACL_LINK) {
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700646 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300647 __set_chan_timer(chan, sk->sk_sndtimeo);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200648 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300649 } else
650 l2cap_chan_del(chan, reason);
651 break;
652
653 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300654 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100655 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300656 struct l2cap_conn_rsp rsp;
657 __u16 result;
658
Marcel Holtmannbdc25782013-10-14 02:45:34 -0700659 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300660 result = L2CAP_CR_SEC_BLOCK;
661 else
662 result = L2CAP_CR_BAD_PSM;
Marcel Holtmannbdc25782013-10-14 02:45:34 -0700663
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300664 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300665
666 rsp.scid = cpu_to_le16(chan->dcid);
667 rsp.dcid = cpu_to_le16(chan->scid);
668 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300669 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300670 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100671 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300672 }
673
674 l2cap_chan_del(chan, reason);
675 break;
676
677 case BT_CONNECT:
678 case BT_DISCONN:
679 l2cap_chan_del(chan, reason);
680 break;
681
682 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100683 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300684 break;
685 }
686}
687
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300688static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530689{
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700690 switch (chan->chan_type) {
691 case L2CAP_CHAN_RAW:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300692 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530693 case BT_SECURITY_HIGH:
694 return HCI_AT_DEDICATED_BONDING_MITM;
695 case BT_SECURITY_MEDIUM:
696 return HCI_AT_DEDICATED_BONDING;
697 default:
698 return HCI_AT_NO_BONDING;
699 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700700 break;
Marcel Holtmann3124b842013-10-12 07:19:32 -0700701 case L2CAP_CHAN_CONN_LESS:
702 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_3DSP)) {
703 if (chan->sec_level == BT_SECURITY_LOW)
704 chan->sec_level = BT_SECURITY_SDP;
705 }
706 if (chan->sec_level == BT_SECURITY_HIGH)
707 return HCI_AT_NO_BONDING_MITM;
708 else
709 return HCI_AT_NO_BONDING;
710 break;
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700711 case L2CAP_CHAN_CONN_ORIENTED:
712 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
713 if (chan->sec_level == BT_SECURITY_LOW)
714 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530715
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700716 if (chan->sec_level == BT_SECURITY_HIGH)
717 return HCI_AT_NO_BONDING_MITM;
718 else
719 return HCI_AT_NO_BONDING;
720 }
721 /* fall through */
722 default:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300723 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530724 case BT_SECURITY_HIGH:
725 return HCI_AT_GENERAL_BONDING_MITM;
726 case BT_SECURITY_MEDIUM:
727 return HCI_AT_GENERAL_BONDING;
728 default:
729 return HCI_AT_NO_BONDING;
730 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700731 break;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530732 }
733}
734
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200735/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200736int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200737{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300738 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100739 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200740
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300741 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100742
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300743 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200744}
745
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200746static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200747{
748 u8 id;
749
750 /* Get next available identificator.
751 * 1 - 128 are used by kernel.
752 * 129 - 199 are reserved.
753 * 200 - 254 are used by utilities like l2ping, etc.
754 */
755
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200756 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200757
758 if (++conn->tx_ident > 128)
759 conn->tx_ident = 1;
760
761 id = conn->tx_ident;
762
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200763 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200764
765 return id;
766}
767
Gustavo Padovan2d792812012-10-06 10:07:01 +0100768static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
769 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200770{
771 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200772 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200773
774 BT_DBG("code 0x%2.2x", code);
775
776 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300777 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200778
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200779 if (lmp_no_flush_capable(conn->hcon->hdev))
780 flags = ACL_START_NO_FLUSH;
781 else
782 flags = ACL_START;
783
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700784 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200785 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700786
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200787 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200788}
789
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700790static bool __chan_is_moving(struct l2cap_chan *chan)
791{
792 return chan->move_state != L2CAP_MOVE_STABLE &&
793 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
794}
795
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200796static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
797{
798 struct hci_conn *hcon = chan->conn->hcon;
799 u16 flags;
800
801 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100802 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200803
Mat Martineaud5f8a752012-10-23 15:24:18 -0700804 if (chan->hs_hcon && !__chan_is_moving(chan)) {
805 if (chan->hs_hchan)
806 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
807 else
808 kfree_skb(skb);
809
810 return;
811 }
812
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200813 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100814 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200815 flags = ACL_START_NO_FLUSH;
816 else
817 flags = ACL_START;
818
819 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
820 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821}
822
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700823static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
824{
825 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
826 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
827
828 if (enh & L2CAP_CTRL_FRAME_TYPE) {
829 /* S-Frame */
830 control->sframe = 1;
831 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
832 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
833
834 control->sar = 0;
835 control->txseq = 0;
836 } else {
837 /* I-Frame */
838 control->sframe = 0;
839 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
840 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
841
842 control->poll = 0;
843 control->super = 0;
844 }
845}
846
847static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
848{
849 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
850 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
851
852 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
853 /* S-Frame */
854 control->sframe = 1;
855 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
856 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
857
858 control->sar = 0;
859 control->txseq = 0;
860 } else {
861 /* I-Frame */
862 control->sframe = 0;
863 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
864 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
865
866 control->poll = 0;
867 control->super = 0;
868 }
869}
870
871static inline void __unpack_control(struct l2cap_chan *chan,
872 struct sk_buff *skb)
873{
874 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
875 __unpack_extended_control(get_unaligned_le32(skb->data),
876 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700877 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700878 } else {
879 __unpack_enhanced_control(get_unaligned_le16(skb->data),
880 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700881 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700882 }
883}
884
885static u32 __pack_extended_control(struct l2cap_ctrl *control)
886{
887 u32 packed;
888
889 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
890 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
891
892 if (control->sframe) {
893 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
894 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
895 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
896 } else {
897 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
898 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
899 }
900
901 return packed;
902}
903
904static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
905{
906 u16 packed;
907
908 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
909 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
910
911 if (control->sframe) {
912 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
913 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
914 packed |= L2CAP_CTRL_FRAME_TYPE;
915 } else {
916 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
917 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
918 }
919
920 return packed;
921}
922
923static inline void __pack_control(struct l2cap_chan *chan,
924 struct l2cap_ctrl *control,
925 struct sk_buff *skb)
926{
927 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
928 put_unaligned_le32(__pack_extended_control(control),
929 skb->data + L2CAP_HDR_SIZE);
930 } else {
931 put_unaligned_le16(__pack_enhanced_control(control),
932 skb->data + L2CAP_HDR_SIZE);
933 }
934}
935
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300936static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
937{
938 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
939 return L2CAP_EXT_HDR_SIZE;
940 else
941 return L2CAP_ENH_HDR_SIZE;
942}
943
Mat Martineaua67d7f62012-05-17 20:53:35 -0700944static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
945 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300946{
947 struct sk_buff *skb;
948 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300949 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300950
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300951 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300952 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300953
Mat Martineaua67d7f62012-05-17 20:53:35 -0700954 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300955
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300956 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700957 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300958
959 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300960 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300961 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300962
Mat Martineaua67d7f62012-05-17 20:53:35 -0700963 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
964 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
965 else
966 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300967
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300968 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700969 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300970 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300971 }
972
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200973 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700974 return skb;
975}
976
977static void l2cap_send_sframe(struct l2cap_chan *chan,
978 struct l2cap_ctrl *control)
979{
980 struct sk_buff *skb;
981 u32 control_field;
982
983 BT_DBG("chan %p, control %p", chan, control);
984
985 if (!control->sframe)
986 return;
987
Mat Martineaub99e13a2012-10-23 15:24:19 -0700988 if (__chan_is_moving(chan))
989 return;
990
Mat Martineaua67d7f62012-05-17 20:53:35 -0700991 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
992 !control->poll)
993 control->final = 1;
994
995 if (control->super == L2CAP_SUPER_RR)
996 clear_bit(CONN_RNR_SENT, &chan->conn_state);
997 else if (control->super == L2CAP_SUPER_RNR)
998 set_bit(CONN_RNR_SENT, &chan->conn_state);
999
1000 if (control->super != L2CAP_SUPER_SREJ) {
1001 chan->last_acked_seq = control->reqseq;
1002 __clear_ack_timer(chan);
1003 }
1004
1005 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
1006 control->final, control->poll, control->super);
1007
1008 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1009 control_field = __pack_extended_control(control);
1010 else
1011 control_field = __pack_enhanced_control(control);
1012
1013 skb = l2cap_create_sframe_pdu(chan, control_field);
1014 if (!IS_ERR(skb))
1015 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001016}
1017
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001018static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001019{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001020 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001021
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001022 BT_DBG("chan %p, poll %d", chan, poll);
1023
1024 memset(&control, 0, sizeof(control));
1025 control.sframe = 1;
1026 control.poll = poll;
1027
1028 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1029 control.super = L2CAP_SUPER_RNR;
1030 else
1031 control.super = L2CAP_SUPER_RR;
1032
1033 control.reqseq = chan->buffer_seq;
1034 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001035}
1036
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001037static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001038{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001039 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001040}
1041
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001042static bool __amp_capable(struct l2cap_chan *chan)
1043{
1044 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001045 struct hci_dev *hdev;
1046 bool amp_available = false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001047
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001048 if (!conn->hs_enabled)
1049 return false;
1050
1051 if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
1052 return false;
1053
1054 read_lock(&hci_dev_list_lock);
1055 list_for_each_entry(hdev, &hci_dev_list, list) {
1056 if (hdev->amp_type != AMP_TYPE_BREDR &&
1057 test_bit(HCI_UP, &hdev->flags)) {
1058 amp_available = true;
1059 break;
1060 }
1061 }
1062 read_unlock(&hci_dev_list_lock);
1063
1064 if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED)
1065 return amp_available;
Marcel Holtmann848566b2013-10-01 22:59:22 -07001066
1067 return false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001068}
1069
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001070static bool l2cap_check_efs(struct l2cap_chan *chan)
1071{
1072 /* Check EFS parameters */
1073 return true;
1074}
1075
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001076void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001077{
1078 struct l2cap_conn *conn = chan->conn;
1079 struct l2cap_conn_req req;
1080
1081 req.scid = cpu_to_le16(chan->scid);
1082 req.psm = chan->psm;
1083
1084 chan->ident = l2cap_get_ident(conn);
1085
1086 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1087
1088 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1089}
1090
Mat Martineau8eb200b2012-10-23 15:24:17 -07001091static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1092{
1093 struct l2cap_create_chan_req req;
1094 req.scid = cpu_to_le16(chan->scid);
1095 req.psm = chan->psm;
1096 req.amp_id = amp_id;
1097
1098 chan->ident = l2cap_get_ident(chan->conn);
1099
1100 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1101 sizeof(req), &req);
1102}
1103
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001104static void l2cap_move_setup(struct l2cap_chan *chan)
1105{
1106 struct sk_buff *skb;
1107
1108 BT_DBG("chan %p", chan);
1109
1110 if (chan->mode != L2CAP_MODE_ERTM)
1111 return;
1112
1113 __clear_retrans_timer(chan);
1114 __clear_monitor_timer(chan);
1115 __clear_ack_timer(chan);
1116
1117 chan->retry_count = 0;
1118 skb_queue_walk(&chan->tx_q, skb) {
1119 if (bt_cb(skb)->control.retries)
1120 bt_cb(skb)->control.retries = 1;
1121 else
1122 break;
1123 }
1124
1125 chan->expected_tx_seq = chan->buffer_seq;
1126
1127 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1128 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1129 l2cap_seq_list_clear(&chan->retrans_list);
1130 l2cap_seq_list_clear(&chan->srej_list);
1131 skb_queue_purge(&chan->srej_q);
1132
1133 chan->tx_state = L2CAP_TX_STATE_XMIT;
1134 chan->rx_state = L2CAP_RX_STATE_MOVE;
1135
1136 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1137}
1138
Mat Martineau5f3847a2012-10-23 15:24:12 -07001139static void l2cap_move_done(struct l2cap_chan *chan)
1140{
1141 u8 move_role = chan->move_role;
1142 BT_DBG("chan %p", chan);
1143
1144 chan->move_state = L2CAP_MOVE_STABLE;
1145 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1146
1147 if (chan->mode != L2CAP_MODE_ERTM)
1148 return;
1149
1150 switch (move_role) {
1151 case L2CAP_MOVE_ROLE_INITIATOR:
1152 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1153 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1154 break;
1155 case L2CAP_MOVE_ROLE_RESPONDER:
1156 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1157 break;
1158 }
1159}
1160
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001161static void l2cap_chan_ready(struct l2cap_chan *chan)
1162{
Mat Martineau28270112012-05-17 21:14:09 -07001163 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001164 chan->conf_state = 0;
1165 __clear_chan_timer(chan);
1166
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001167 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001168
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001169 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001170}
1171
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001172static void l2cap_start_connection(struct l2cap_chan *chan)
1173{
1174 if (__amp_capable(chan)) {
1175 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1176 a2mp_discover_amp(chan);
1177 } else {
1178 l2cap_send_conn_req(chan);
1179 }
1180}
1181
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001182static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001183{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001184 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001185
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001186 if (conn->hcon->type == LE_LINK) {
1187 l2cap_chan_ready(chan);
1188 return;
1189 }
1190
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001191 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001192 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1193 return;
1194
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001195 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001196 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001197 l2cap_start_connection(chan);
1198 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001199 } else {
1200 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001201 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001202
1203 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1204 conn->info_ident = l2cap_get_ident(conn);
1205
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001206 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001207
Gustavo Padovan2d792812012-10-06 10:07:01 +01001208 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1209 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001210 }
1211}
1212
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001213static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1214{
1215 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001216 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001217 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1218
1219 switch (mode) {
1220 case L2CAP_MODE_ERTM:
1221 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1222 case L2CAP_MODE_STREAMING:
1223 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1224 default:
1225 return 0x00;
1226 }
1227}
1228
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001229static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001230{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001231 struct sock *sk = chan->sk;
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001232 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001233 struct l2cap_disconn_req req;
1234
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001235 if (!conn)
1236 return;
1237
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001238 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001239 __clear_retrans_timer(chan);
1240 __clear_monitor_timer(chan);
1241 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001242 }
1243
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001244 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001245 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001246 return;
1247 }
1248
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001249 req.dcid = cpu_to_le16(chan->dcid);
1250 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001251 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1252 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001253
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001254 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001255 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001256 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001257 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001258}
1259
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001261static void l2cap_conn_start(struct l2cap_conn *conn)
1262{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001263 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001264
1265 BT_DBG("conn %p", conn);
1266
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001267 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001268
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001269 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001270 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001271
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001272 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001273 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001274 continue;
1275 }
1276
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001277 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001278 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001279 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001280 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001281 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001282 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001283
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001284 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001285 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001286 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001287 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001288 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001289 continue;
1290 }
1291
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001292 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001293
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001294 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001295 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001296 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001297 rsp.scid = cpu_to_le16(chan->dcid);
1298 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001299
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001300 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07001301 struct sock *sk = chan->sk;
1302
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001303 lock_sock(sk);
Marcel Holtmannbdc25782013-10-14 02:45:34 -07001304 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001305 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1306 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001307 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001308
1309 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001310 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001311 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1312 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001313 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001314 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001315 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001316 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1317 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001318 }
1319
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001320 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001321 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001322
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001323 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001324 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001325 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001326 continue;
1327 }
1328
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001329 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001330 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001331 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001332 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001333 }
1334
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001335 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001336 }
1337
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001338 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001339}
1340
Ido Yarivc2287682012-04-20 15:46:07 -03001341/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001342 * Returns closest match, locked.
1343 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001344static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001345 bdaddr_t *src,
1346 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001347{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001348 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001349
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001350 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001351
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001352 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001353 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001354 continue;
1355
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001356 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001357 int src_match, dst_match;
1358 int src_any, dst_any;
1359
Ville Tervob62f3282011-02-10 22:38:50 -03001360 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001361 src_match = !bacmp(&c->src, src);
1362 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001363 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001364 read_unlock(&chan_list_lock);
1365 return c;
1366 }
Ville Tervob62f3282011-02-10 22:38:50 -03001367
1368 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001369 src_any = !bacmp(&c->src, BDADDR_ANY);
1370 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001371 if ((src_match && dst_any) || (src_any && dst_match) ||
1372 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001373 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001374 }
1375 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001376
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001377 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001378
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001379 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001380}
1381
1382static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1383{
Johan Hedberg60bac182013-04-29 19:35:41 +03001384 struct sock *parent;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001385 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001386
1387 BT_DBG("");
1388
1389 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001390 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Marcel Holtmann6f59b902013-10-13 05:24:01 -07001391 &conn->hcon->src, &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001392 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001393 return;
1394
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001395 /* Client ATT sockets should override the server one */
1396 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1397 return;
1398
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001399 parent = pchan->sk;
1400
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001401 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001402
Gustavo Padovan80b98022012-05-27 22:27:51 -03001403 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001404 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001405 goto clean;
1406
Johan Hedberg9f22398c2013-04-29 19:35:38 +03001407 chan->dcid = L2CAP_CID_ATT;
1408
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001409 bacpy(&chan->src, &conn->hcon->src);
1410 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001411 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
1412 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Ville Tervob62f3282011-02-10 22:38:50 -03001413
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001414 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001415
Ville Tervob62f3282011-02-10 22:38:50 -03001416clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001417 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001418}
1419
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001420static void l2cap_conn_ready(struct l2cap_conn *conn)
1421{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001422 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001423 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001424
1425 BT_DBG("conn %p", conn);
1426
Johan Hedbergd8729922013-04-29 19:35:39 +03001427 /* For outgoing pairing which doesn't necessarily have an
1428 * associated socket (e.g. mgmt_pair_device).
1429 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001430 if (hcon->out && hcon->type == LE_LINK)
1431 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001432
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001433 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001434
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001435 if (hcon->type == LE_LINK)
1436 l2cap_le_conn_ready(conn);
1437
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001438 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001439
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001440 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001441
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001442 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1443 l2cap_chan_unlock(chan);
1444 continue;
1445 }
1446
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001447 if (hcon->type == LE_LINK) {
1448 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001449 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001450
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001451 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001452 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001453 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001454 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001455 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001456 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001457 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001458
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001459 } else if (chan->state == BT_CONNECT) {
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001460 l2cap_do_start(chan);
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001461 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001462
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001463 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001464 }
1465
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001466 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001467}
1468
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001469/* Notify sockets that we cannot guaranty reliability anymore */
1470static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1471{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001472 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001473
1474 BT_DBG("conn %p", conn);
1475
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001476 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001477
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001478 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001479 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001480 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001481 }
1482
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001483 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001484}
1485
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001486static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001487{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001488 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001489 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001490
Marcel Holtmann984947d2009-02-06 23:35:19 +01001491 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001492 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001493
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001494 l2cap_conn_start(conn);
1495}
1496
David Herrmann2c8e1412013-04-06 20:28:45 +02001497/*
1498 * l2cap_user
1499 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1500 * callback is called during registration. The ->remove callback is called
1501 * during unregistration.
1502 * An l2cap_user object can either be explicitly unregistered or when the
1503 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1504 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1505 * External modules must own a reference to the l2cap_conn object if they intend
1506 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1507 * any time if they don't.
1508 */
1509
1510int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1511{
1512 struct hci_dev *hdev = conn->hcon->hdev;
1513 int ret;
1514
1515 /* We need to check whether l2cap_conn is registered. If it is not, we
1516 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1517 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1518 * relies on the parent hci_conn object to be locked. This itself relies
1519 * on the hci_dev object to be locked. So we must lock the hci device
1520 * here, too. */
1521
1522 hci_dev_lock(hdev);
1523
1524 if (user->list.next || user->list.prev) {
1525 ret = -EINVAL;
1526 goto out_unlock;
1527 }
1528
1529 /* conn->hchan is NULL after l2cap_conn_del() was called */
1530 if (!conn->hchan) {
1531 ret = -ENODEV;
1532 goto out_unlock;
1533 }
1534
1535 ret = user->probe(conn, user);
1536 if (ret)
1537 goto out_unlock;
1538
1539 list_add(&user->list, &conn->users);
1540 ret = 0;
1541
1542out_unlock:
1543 hci_dev_unlock(hdev);
1544 return ret;
1545}
1546EXPORT_SYMBOL(l2cap_register_user);
1547
1548void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1549{
1550 struct hci_dev *hdev = conn->hcon->hdev;
1551
1552 hci_dev_lock(hdev);
1553
1554 if (!user->list.next || !user->list.prev)
1555 goto out_unlock;
1556
1557 list_del(&user->list);
1558 user->list.next = NULL;
1559 user->list.prev = NULL;
1560 user->remove(conn, user);
1561
1562out_unlock:
1563 hci_dev_unlock(hdev);
1564}
1565EXPORT_SYMBOL(l2cap_unregister_user);
1566
1567static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1568{
1569 struct l2cap_user *user;
1570
1571 while (!list_empty(&conn->users)) {
1572 user = list_first_entry(&conn->users, struct l2cap_user, list);
1573 list_del(&user->list);
1574 user->list.next = NULL;
1575 user->list.prev = NULL;
1576 user->remove(conn, user);
1577 }
1578}
1579
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001580static void l2cap_conn_del(struct hci_conn *hcon, int err)
1581{
1582 struct l2cap_conn *conn = hcon->l2cap_data;
1583 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001584
1585 if (!conn)
1586 return;
1587
1588 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1589
1590 kfree_skb(conn->rx_skb);
1591
David Herrmann2c8e1412013-04-06 20:28:45 +02001592 l2cap_unregister_all_users(conn);
1593
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001594 mutex_lock(&conn->chan_lock);
1595
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001596 /* Kill channels */
1597 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001598 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001599 l2cap_chan_lock(chan);
1600
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001601 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001602
1603 l2cap_chan_unlock(chan);
1604
Gustavo Padovan80b98022012-05-27 22:27:51 -03001605 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001606 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001607 }
1608
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001609 mutex_unlock(&conn->chan_lock);
1610
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001611 hci_chan_del(conn->hchan);
1612
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001613 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001614 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001615
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001616 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001617 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001618 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001619 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001620
1621 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001622 conn->hchan = NULL;
1623 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001624}
1625
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001626static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001627{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001628 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001629 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001630
Johan Hedbergd06cc412012-06-06 18:44:11 +08001631 BT_DBG("conn %p", conn);
1632
1633 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1634 smp_chan_destroy(conn);
1635 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1636 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001637}
1638
Claudio Takahasibaf43252013-04-11 13:55:50 -03001639static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640{
Marcel Holtmann01394182006-07-03 10:02:46 +02001641 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001642 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643
Claudio Takahasibaf43252013-04-11 13:55:50 -03001644 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645 return conn;
1646
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001647 hchan = hci_chan_create(hcon);
1648 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001651 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001652 if (!conn) {
1653 hci_chan_del(hchan);
1654 return NULL;
1655 }
1656
David Herrmann9c903e32013-04-06 20:28:44 +02001657 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658 hcon->l2cap_data = conn;
1659 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001660 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001661 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001663 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001664
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001665 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001666 case LE_LINK:
1667 if (hcon->hdev->le_mtu) {
1668 conn->mtu = hcon->hdev->le_mtu;
1669 break;
1670 }
1671 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001672 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001673 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001674 break;
1675 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001676
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001677 conn->feat_mask = 0;
1678
Marcel Holtmann848566b2013-10-01 22:59:22 -07001679 if (hcon->type == ACL_LINK)
1680 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
1681 &hcon->hdev->dev_flags);
1682
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001684 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001685
1686 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001687 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001689 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001690 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001691 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001692 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001693
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001694 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001695
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 return conn;
1697}
1698
David Herrmann9c903e32013-04-06 20:28:44 +02001699static void l2cap_conn_free(struct kref *ref)
1700{
1701 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1702
1703 hci_conn_put(conn->hcon);
1704 kfree(conn);
1705}
1706
1707void l2cap_conn_get(struct l2cap_conn *conn)
1708{
1709 kref_get(&conn->ref);
1710}
1711EXPORT_SYMBOL(l2cap_conn_get);
1712
1713void l2cap_conn_put(struct l2cap_conn *conn)
1714{
1715 kref_put(&conn->ref, l2cap_conn_free);
1716}
1717EXPORT_SYMBOL(l2cap_conn_put);
1718
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720
Ido Yarivc2287682012-04-20 15:46:07 -03001721/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 * Returns closest match.
1723 */
Ido Yarivc2287682012-04-20 15:46:07 -03001724static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1725 bdaddr_t *src,
1726 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001728 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001730 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001731
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001732 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001733 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734 continue;
1735
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001736 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001737 int src_match, dst_match;
1738 int src_any, dst_any;
1739
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001741 src_match = !bacmp(&c->src, src);
1742 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001743 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001744 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001745 return c;
1746 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747
1748 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001749 src_any = !bacmp(&c->src, BDADDR_ANY);
1750 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001751 if ((src_match && dst_any) || (src_any && dst_match) ||
1752 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001753 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 }
1755 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001757 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001758
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001759 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760}
1761
Andre Guedes8e9f9892012-04-24 21:02:55 -03001762int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1763 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001765 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766 struct l2cap_conn *conn;
1767 struct hci_conn *hcon;
1768 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001769 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001770 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001772 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301773 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001775 hdev = hci_get_route(dst, &chan->src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001776 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 return -EHOSTUNREACH;
1778
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001779 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001781 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001782
1783 /* PSM must be odd and lsb of upper byte must be 0 */
1784 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001785 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001786 err = -EINVAL;
1787 goto done;
1788 }
1789
1790 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1791 err = -EINVAL;
1792 goto done;
1793 }
1794
1795 switch (chan->mode) {
1796 case L2CAP_MODE_BASIC:
1797 break;
1798 case L2CAP_MODE_ERTM:
1799 case L2CAP_MODE_STREAMING:
1800 if (!disable_ertm)
1801 break;
1802 /* fall through */
1803 default:
1804 err = -ENOTSUPP;
1805 goto done;
1806 }
1807
Gustavo Padovan0797e012012-05-27 22:27:54 -03001808 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001809 case BT_CONNECT:
1810 case BT_CONNECT2:
1811 case BT_CONFIG:
1812 /* Already connecting */
1813 err = 0;
1814 goto done;
1815
1816 case BT_CONNECTED:
1817 /* Already connected */
1818 err = -EISCONN;
1819 goto done;
1820
1821 case BT_OPEN:
1822 case BT_BOUND:
1823 /* Can connect */
1824 break;
1825
1826 default:
1827 err = -EBADFD;
1828 goto done;
1829 }
1830
1831 /* Set destination address and psm */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001832 bacpy(&chan->dst, dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001833 chan->dst_type = dst_type;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001834
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001835 chan->psm = psm;
1836 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001838 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001839
Johan Hedbergf224ca52013-04-29 19:35:36 +03001840 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001841 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001842 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001843 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001844 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001845 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001846
Ville Tervo30e76272011-02-22 16:10:53 -03001847 if (IS_ERR(hcon)) {
1848 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001850 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851
Claudio Takahasibaf43252013-04-11 13:55:50 -03001852 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001854 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001855 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856 goto done;
1857 }
1858
Johan Hedberg141d5702013-04-29 19:35:37 +03001859 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1860 hci_conn_drop(hcon);
1861 err = -EBUSY;
1862 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001863 }
1864
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 /* Update source addr of the socket */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001866 bacpy(&chan->src, &hcon->src);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001867 chan->src_type = bdaddr_type(hcon, hcon->src_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001869 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001870 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001871 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001872
Johan Hedberg5ee98912013-04-29 19:35:43 +03001873 /* l2cap_chan_add takes its own ref so we can drop this one */
1874 hci_conn_drop(hcon);
1875
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001876 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001877 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878
1879 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001880 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001881 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001882 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001883 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001884 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001885 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886 }
1887
Ville Tervo30e76272011-02-22 16:10:53 -03001888 err = 0;
1889
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001891 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001892 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893 hci_dev_put(hdev);
1894 return err;
1895}
1896
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001897int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001898{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001899 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001900 DECLARE_WAITQUEUE(wait, current);
1901 int err = 0;
1902 int timeo = HZ/5;
1903
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001904 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001905 set_current_state(TASK_INTERRUPTIBLE);
1906 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001907 if (!timeo)
1908 timeo = HZ/5;
1909
1910 if (signal_pending(current)) {
1911 err = sock_intr_errno(timeo);
1912 break;
1913 }
1914
1915 release_sock(sk);
1916 timeo = schedule_timeout(timeo);
1917 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001918 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001919
1920 err = sock_error(sk);
1921 if (err)
1922 break;
1923 }
1924 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001925 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001926 return err;
1927}
1928
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001929static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001930{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001931 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001932 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001933
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001934 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001935
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001936 l2cap_chan_lock(chan);
1937
Mat Martineau80909e02012-05-17 20:53:50 -07001938 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001939 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001940 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001941 return;
1942 }
1943
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001944 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001945
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001946 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001947 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001948}
1949
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001950static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001951{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001952 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001953 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001954
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001955 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001956
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001957 l2cap_chan_lock(chan);
1958
Mat Martineau80909e02012-05-17 20:53:50 -07001959 if (!chan->conn) {
1960 l2cap_chan_unlock(chan);
1961 l2cap_chan_put(chan);
1962 return;
1963 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001964
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001965 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001966 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001967 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001968}
1969
Gustavo Padovand6603662012-05-21 13:58:22 -03001970static void l2cap_streaming_send(struct l2cap_chan *chan,
1971 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001972{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001973 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001974 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001975
Mat Martineau37339372012-05-17 20:53:33 -07001976 BT_DBG("chan %p, skbs %p", chan, skbs);
1977
Mat Martineaub99e13a2012-10-23 15:24:19 -07001978 if (__chan_is_moving(chan))
1979 return;
1980
Mat Martineau37339372012-05-17 20:53:33 -07001981 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1982
1983 while (!skb_queue_empty(&chan->tx_q)) {
1984
1985 skb = skb_dequeue(&chan->tx_q);
1986
1987 bt_cb(skb)->control.retries = 1;
1988 control = &bt_cb(skb)->control;
1989
1990 control->reqseq = 0;
1991 control->txseq = chan->next_tx_seq;
1992
1993 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001994
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001995 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001996 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1997 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001998 }
1999
Gustavo F. Padovan43434782011-04-12 18:31:57 -03002000 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002001
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002002 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07002003
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002004 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07002005 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002006 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002007}
2008
Szymon Janc67c9e842011-07-28 16:24:33 +02002009static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002010{
2011 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07002012 struct l2cap_ctrl *control;
2013 int sent = 0;
2014
2015 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002016
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03002017 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03002018 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002019
Mat Martineau94122bb2012-05-02 09:42:02 -07002020 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2021 return 0;
2022
Mat Martineaub99e13a2012-10-23 15:24:19 -07002023 if (__chan_is_moving(chan))
2024 return 0;
2025
Mat Martineau18a48e72012-05-17 20:53:34 -07002026 while (chan->tx_send_head &&
2027 chan->unacked_frames < chan->remote_tx_win &&
2028 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002029
Mat Martineau18a48e72012-05-17 20:53:34 -07002030 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002031
Mat Martineau18a48e72012-05-17 20:53:34 -07002032 bt_cb(skb)->control.retries = 1;
2033 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03002034
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002035 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07002036 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002037
Mat Martineau18a48e72012-05-17 20:53:34 -07002038 control->reqseq = chan->buffer_seq;
2039 chan->last_acked_seq = chan->buffer_seq;
2040 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002041
Mat Martineau18a48e72012-05-17 20:53:34 -07002042 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002043
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002044 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002045 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2046 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002047 }
2048
Mat Martineau18a48e72012-05-17 20:53:34 -07002049 /* Clone after data has been modified. Data is assumed to be
2050 read-only (for locking purposes) on cloned sk_buffs.
2051 */
2052 tx_skb = skb_clone(skb, GFP_KERNEL);
2053
2054 if (!tx_skb)
2055 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002056
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002057 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002058
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002059 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002060 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002061 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002062 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002063
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002064 if (skb_queue_is_last(&chan->tx_q, skb))
2065 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002066 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002067 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002068
2069 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002070 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002071 }
2072
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002073 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2074 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002075
2076 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002077}
2078
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002079static void l2cap_ertm_resend(struct l2cap_chan *chan)
2080{
2081 struct l2cap_ctrl control;
2082 struct sk_buff *skb;
2083 struct sk_buff *tx_skb;
2084 u16 seq;
2085
2086 BT_DBG("chan %p", chan);
2087
2088 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2089 return;
2090
Mat Martineaub99e13a2012-10-23 15:24:19 -07002091 if (__chan_is_moving(chan))
2092 return;
2093
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002094 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2095 seq = l2cap_seq_list_pop(&chan->retrans_list);
2096
2097 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2098 if (!skb) {
2099 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002100 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002101 continue;
2102 }
2103
2104 bt_cb(skb)->control.retries++;
2105 control = bt_cb(skb)->control;
2106
2107 if (chan->max_tx != 0 &&
2108 bt_cb(skb)->control.retries > chan->max_tx) {
2109 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002110 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002111 l2cap_seq_list_clear(&chan->retrans_list);
2112 break;
2113 }
2114
2115 control.reqseq = chan->buffer_seq;
2116 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2117 control.final = 1;
2118 else
2119 control.final = 0;
2120
2121 if (skb_cloned(skb)) {
2122 /* Cloned sk_buffs are read-only, so we need a
2123 * writeable copy
2124 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002125 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002126 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002127 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002128 }
2129
2130 if (!tx_skb) {
2131 l2cap_seq_list_clear(&chan->retrans_list);
2132 break;
2133 }
2134
2135 /* Update skb contents */
2136 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2137 put_unaligned_le32(__pack_extended_control(&control),
2138 tx_skb->data + L2CAP_HDR_SIZE);
2139 } else {
2140 put_unaligned_le16(__pack_enhanced_control(&control),
2141 tx_skb->data + L2CAP_HDR_SIZE);
2142 }
2143
2144 if (chan->fcs == L2CAP_FCS_CRC16) {
2145 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2146 put_unaligned_le16(fcs, skb_put(tx_skb,
2147 L2CAP_FCS_SIZE));
2148 }
2149
2150 l2cap_do_send(chan, tx_skb);
2151
2152 BT_DBG("Resent txseq %d", control.txseq);
2153
2154 chan->last_acked_seq = chan->buffer_seq;
2155 }
2156}
2157
Mat Martineauf80842a2012-05-17 20:53:46 -07002158static void l2cap_retransmit(struct l2cap_chan *chan,
2159 struct l2cap_ctrl *control)
2160{
2161 BT_DBG("chan %p, control %p", chan, control);
2162
2163 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2164 l2cap_ertm_resend(chan);
2165}
2166
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002167static void l2cap_retransmit_all(struct l2cap_chan *chan,
2168 struct l2cap_ctrl *control)
2169{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002170 struct sk_buff *skb;
2171
2172 BT_DBG("chan %p, control %p", chan, control);
2173
2174 if (control->poll)
2175 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2176
2177 l2cap_seq_list_clear(&chan->retrans_list);
2178
2179 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2180 return;
2181
2182 if (chan->unacked_frames) {
2183 skb_queue_walk(&chan->tx_q, skb) {
2184 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002185 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002186 break;
2187 }
2188
2189 skb_queue_walk_from(&chan->tx_q, skb) {
2190 if (skb == chan->tx_send_head)
2191 break;
2192
2193 l2cap_seq_list_append(&chan->retrans_list,
2194 bt_cb(skb)->control.txseq);
2195 }
2196
2197 l2cap_ertm_resend(chan);
2198 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002199}
2200
Szymon Jancb17e73b2012-01-11 10:59:47 +01002201static void l2cap_send_ack(struct l2cap_chan *chan)
2202{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002203 struct l2cap_ctrl control;
2204 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2205 chan->last_acked_seq);
2206 int threshold;
2207
2208 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2209 chan, chan->last_acked_seq, chan->buffer_seq);
2210
2211 memset(&control, 0, sizeof(control));
2212 control.sframe = 1;
2213
2214 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2215 chan->rx_state == L2CAP_RX_STATE_RECV) {
2216 __clear_ack_timer(chan);
2217 control.super = L2CAP_SUPER_RNR;
2218 control.reqseq = chan->buffer_seq;
2219 l2cap_send_sframe(chan, &control);
2220 } else {
2221 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2222 l2cap_ertm_send(chan);
2223 /* If any i-frames were sent, they included an ack */
2224 if (chan->buffer_seq == chan->last_acked_seq)
2225 frames_to_ack = 0;
2226 }
2227
Mat Martineauc20f8e32012-07-10 05:47:07 -07002228 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002229 * Calculate without mul or div
2230 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002231 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002232 threshold += threshold << 1;
2233 threshold >>= 2;
2234
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002235 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002236 threshold);
2237
2238 if (frames_to_ack >= threshold) {
2239 __clear_ack_timer(chan);
2240 control.super = L2CAP_SUPER_RR;
2241 control.reqseq = chan->buffer_seq;
2242 l2cap_send_sframe(chan, &control);
2243 frames_to_ack = 0;
2244 }
2245
2246 if (frames_to_ack)
2247 __set_ack_timer(chan);
2248 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002249}
2250
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002251static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2252 struct msghdr *msg, int len,
2253 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002254{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002255 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002256 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002257 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002258
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002259 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002260 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002261
2262 sent += count;
2263 len -= count;
2264
2265 /* Continuation fragments (no L2CAP header) */
2266 frag = &skb_shinfo(skb)->frag_list;
2267 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002268 struct sk_buff *tmp;
2269
Linus Torvalds1da177e2005-04-16 15:20:36 -07002270 count = min_t(unsigned int, conn->mtu, len);
2271
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002272 tmp = chan->ops->alloc_skb(chan, count,
2273 msg->msg_flags & MSG_DONTWAIT);
2274 if (IS_ERR(tmp))
2275 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002276
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002277 *frag = tmp;
2278
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002279 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2280 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002281
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002282 (*frag)->priority = skb->priority;
2283
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284 sent += count;
2285 len -= count;
2286
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002287 skb->len += (*frag)->len;
2288 skb->data_len += (*frag)->len;
2289
Linus Torvalds1da177e2005-04-16 15:20:36 -07002290 frag = &(*frag)->next;
2291 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002292
2293 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002294}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002295
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002296static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002297 struct msghdr *msg, size_t len,
2298 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002299{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002300 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002301 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002302 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002303 struct l2cap_hdr *lh;
2304
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002305 BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
2306 __le16_to_cpu(chan->psm), len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002307
2308 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002309
2310 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002311 msg->msg_flags & MSG_DONTWAIT);
2312 if (IS_ERR(skb))
2313 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002314
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002315 skb->priority = priority;
2316
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002317 /* Create L2CAP header */
2318 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002319 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002320 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002321 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002322
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002323 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002324 if (unlikely(err < 0)) {
2325 kfree_skb(skb);
2326 return ERR_PTR(err);
2327 }
2328 return skb;
2329}
2330
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002331static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002332 struct msghdr *msg, size_t len,
2333 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002334{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002335 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002336 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002337 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002338 struct l2cap_hdr *lh;
2339
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002340 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002341
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002342 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002343
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002344 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002345 msg->msg_flags & MSG_DONTWAIT);
2346 if (IS_ERR(skb))
2347 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002348
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002349 skb->priority = priority;
2350
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002351 /* Create L2CAP header */
2352 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002353 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002354 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002355
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002356 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002357 if (unlikely(err < 0)) {
2358 kfree_skb(skb);
2359 return ERR_PTR(err);
2360 }
2361 return skb;
2362}
2363
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002364static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002365 struct msghdr *msg, size_t len,
2366 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002367{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002368 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002369 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002370 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002371 struct l2cap_hdr *lh;
2372
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002373 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002374
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002375 if (!conn)
2376 return ERR_PTR(-ENOTCONN);
2377
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002378 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002379
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002380 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002381 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002382
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002383 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002384 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002385
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002386 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002387
2388 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002389 msg->msg_flags & MSG_DONTWAIT);
2390 if (IS_ERR(skb))
2391 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002392
2393 /* Create L2CAP header */
2394 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002395 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002396 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002397
Mat Martineau18a48e72012-05-17 20:53:34 -07002398 /* Control header is populated later */
2399 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2400 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2401 else
2402 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002403
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002404 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002405 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002406
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002407 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002408 if (unlikely(err < 0)) {
2409 kfree_skb(skb);
2410 return ERR_PTR(err);
2411 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002412
Mat Martineau18a48e72012-05-17 20:53:34 -07002413 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002414 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002415 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002416}
2417
Mat Martineau94122bb2012-05-02 09:42:02 -07002418static int l2cap_segment_sdu(struct l2cap_chan *chan,
2419 struct sk_buff_head *seg_queue,
2420 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002421{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002422 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002423 u16 sdu_len;
2424 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002425 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002426
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002427 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002428
Mat Martineau94122bb2012-05-02 09:42:02 -07002429 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2430 * so fragmented skbs are not used. The HCI layer's handling
2431 * of fragmented skbs is not compatible with ERTM's queueing.
2432 */
2433
2434 /* PDU size is derived from the HCI MTU */
2435 pdu_len = chan->conn->mtu;
2436
Mat Martineaua5495742012-10-23 15:24:21 -07002437 /* Constrain PDU size for BR/EDR connections */
2438 if (!chan->hs_hcon)
2439 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002440
2441 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002442 if (chan->fcs)
2443 pdu_len -= L2CAP_FCS_SIZE;
2444
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002445 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002446
2447 /* Remote device may have requested smaller PDUs */
2448 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2449
2450 if (len <= pdu_len) {
2451 sar = L2CAP_SAR_UNSEGMENTED;
2452 sdu_len = 0;
2453 pdu_len = len;
2454 } else {
2455 sar = L2CAP_SAR_START;
2456 sdu_len = len;
2457 pdu_len -= L2CAP_SDULEN_SIZE;
2458 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002459
2460 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002461 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002462
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002463 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002464 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002465 return PTR_ERR(skb);
2466 }
2467
Mat Martineau94122bb2012-05-02 09:42:02 -07002468 bt_cb(skb)->control.sar = sar;
2469 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002470
Mat Martineau94122bb2012-05-02 09:42:02 -07002471 len -= pdu_len;
2472 if (sdu_len) {
2473 sdu_len = 0;
2474 pdu_len += L2CAP_SDULEN_SIZE;
2475 }
2476
2477 if (len <= pdu_len) {
2478 sar = L2CAP_SAR_END;
2479 pdu_len = len;
2480 } else {
2481 sar = L2CAP_SAR_CONTINUE;
2482 }
2483 }
2484
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002485 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002486}
2487
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002488int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002489 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002490{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002491 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002492 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002493 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002494
2495 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002496 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002497 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002498 if (IS_ERR(skb))
2499 return PTR_ERR(skb);
2500
2501 l2cap_do_send(chan, skb);
2502 return len;
2503 }
2504
2505 switch (chan->mode) {
2506 case L2CAP_MODE_BASIC:
2507 /* Check outgoing MTU */
2508 if (len > chan->omtu)
2509 return -EMSGSIZE;
2510
2511 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002512 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002513 if (IS_ERR(skb))
2514 return PTR_ERR(skb);
2515
2516 l2cap_do_send(chan, skb);
2517 err = len;
2518 break;
2519
2520 case L2CAP_MODE_ERTM:
2521 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002522 /* Check outgoing MTU */
2523 if (len > chan->omtu) {
2524 err = -EMSGSIZE;
2525 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002526 }
2527
Mat Martineau94122bb2012-05-02 09:42:02 -07002528 __skb_queue_head_init(&seg_queue);
2529
2530 /* Do segmentation before calling in to the state machine,
2531 * since it's possible to block while waiting for memory
2532 * allocation.
2533 */
2534 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2535
2536 /* The channel could have been closed while segmenting,
2537 * check that it is still connected.
2538 */
2539 if (chan->state != BT_CONNECTED) {
2540 __skb_queue_purge(&seg_queue);
2541 err = -ENOTCONN;
2542 }
2543
2544 if (err)
2545 break;
2546
Mat Martineau37339372012-05-17 20:53:33 -07002547 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002548 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002549 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002550 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002551
Gustavo Padovand6603662012-05-21 13:58:22 -03002552 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002553
Mat Martineau94122bb2012-05-02 09:42:02 -07002554 /* If the skbs were not queued for sending, they'll still be in
2555 * seg_queue and need to be purged.
2556 */
2557 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002558 break;
2559
2560 default:
2561 BT_DBG("bad state %1.1x", chan->mode);
2562 err = -EBADFD;
2563 }
2564
2565 return err;
2566}
2567
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002568static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2569{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002570 struct l2cap_ctrl control;
2571 u16 seq;
2572
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002573 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002574
2575 memset(&control, 0, sizeof(control));
2576 control.sframe = 1;
2577 control.super = L2CAP_SUPER_SREJ;
2578
2579 for (seq = chan->expected_tx_seq; seq != txseq;
2580 seq = __next_seq(chan, seq)) {
2581 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2582 control.reqseq = seq;
2583 l2cap_send_sframe(chan, &control);
2584 l2cap_seq_list_append(&chan->srej_list, seq);
2585 }
2586 }
2587
2588 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002589}
2590
2591static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2592{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002593 struct l2cap_ctrl control;
2594
2595 BT_DBG("chan %p", chan);
2596
2597 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2598 return;
2599
2600 memset(&control, 0, sizeof(control));
2601 control.sframe = 1;
2602 control.super = L2CAP_SUPER_SREJ;
2603 control.reqseq = chan->srej_list.tail;
2604 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002605}
2606
2607static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2608{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002609 struct l2cap_ctrl control;
2610 u16 initial_head;
2611 u16 seq;
2612
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002613 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002614
2615 memset(&control, 0, sizeof(control));
2616 control.sframe = 1;
2617 control.super = L2CAP_SUPER_SREJ;
2618
2619 /* Capture initial list head to allow only one pass through the list. */
2620 initial_head = chan->srej_list.head;
2621
2622 do {
2623 seq = l2cap_seq_list_pop(&chan->srej_list);
2624 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2625 break;
2626
2627 control.reqseq = seq;
2628 l2cap_send_sframe(chan, &control);
2629 l2cap_seq_list_append(&chan->srej_list, seq);
2630 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002631}
2632
Mat Martineau608bcc62012-05-17 20:53:32 -07002633static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2634{
2635 struct sk_buff *acked_skb;
2636 u16 ackseq;
2637
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002638 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002639
2640 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2641 return;
2642
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002643 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002644 chan->expected_ack_seq, chan->unacked_frames);
2645
2646 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2647 ackseq = __next_seq(chan, ackseq)) {
2648
2649 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2650 if (acked_skb) {
2651 skb_unlink(acked_skb, &chan->tx_q);
2652 kfree_skb(acked_skb);
2653 chan->unacked_frames--;
2654 }
2655 }
2656
2657 chan->expected_ack_seq = reqseq;
2658
2659 if (chan->unacked_frames == 0)
2660 __clear_retrans_timer(chan);
2661
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002662 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002663}
2664
2665static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2666{
2667 BT_DBG("chan %p", chan);
2668
2669 chan->expected_tx_seq = chan->buffer_seq;
2670 l2cap_seq_list_clear(&chan->srej_list);
2671 skb_queue_purge(&chan->srej_q);
2672 chan->rx_state = L2CAP_RX_STATE_RECV;
2673}
2674
Gustavo Padovand6603662012-05-21 13:58:22 -03002675static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2676 struct l2cap_ctrl *control,
2677 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002678{
Mat Martineau608bcc62012-05-17 20:53:32 -07002679 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2680 event);
2681
2682 switch (event) {
2683 case L2CAP_EV_DATA_REQUEST:
2684 if (chan->tx_send_head == NULL)
2685 chan->tx_send_head = skb_peek(skbs);
2686
2687 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2688 l2cap_ertm_send(chan);
2689 break;
2690 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2691 BT_DBG("Enter LOCAL_BUSY");
2692 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2693
2694 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2695 /* The SREJ_SENT state must be aborted if we are to
2696 * enter the LOCAL_BUSY state.
2697 */
2698 l2cap_abort_rx_srej_sent(chan);
2699 }
2700
2701 l2cap_send_ack(chan);
2702
2703 break;
2704 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2705 BT_DBG("Exit LOCAL_BUSY");
2706 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2707
2708 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2709 struct l2cap_ctrl local_control;
2710
2711 memset(&local_control, 0, sizeof(local_control));
2712 local_control.sframe = 1;
2713 local_control.super = L2CAP_SUPER_RR;
2714 local_control.poll = 1;
2715 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002716 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002717
2718 chan->retry_count = 1;
2719 __set_monitor_timer(chan);
2720 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2721 }
2722 break;
2723 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2724 l2cap_process_reqseq(chan, control->reqseq);
2725 break;
2726 case L2CAP_EV_EXPLICIT_POLL:
2727 l2cap_send_rr_or_rnr(chan, 1);
2728 chan->retry_count = 1;
2729 __set_monitor_timer(chan);
2730 __clear_ack_timer(chan);
2731 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2732 break;
2733 case L2CAP_EV_RETRANS_TO:
2734 l2cap_send_rr_or_rnr(chan, 1);
2735 chan->retry_count = 1;
2736 __set_monitor_timer(chan);
2737 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2738 break;
2739 case L2CAP_EV_RECV_FBIT:
2740 /* Nothing to process */
2741 break;
2742 default:
2743 break;
2744 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002745}
2746
Gustavo Padovand6603662012-05-21 13:58:22 -03002747static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2748 struct l2cap_ctrl *control,
2749 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002750{
Mat Martineau608bcc62012-05-17 20:53:32 -07002751 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2752 event);
2753
2754 switch (event) {
2755 case L2CAP_EV_DATA_REQUEST:
2756 if (chan->tx_send_head == NULL)
2757 chan->tx_send_head = skb_peek(skbs);
2758 /* Queue data, but don't send. */
2759 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2760 break;
2761 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2762 BT_DBG("Enter LOCAL_BUSY");
2763 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2764
2765 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2766 /* The SREJ_SENT state must be aborted if we are to
2767 * enter the LOCAL_BUSY state.
2768 */
2769 l2cap_abort_rx_srej_sent(chan);
2770 }
2771
2772 l2cap_send_ack(chan);
2773
2774 break;
2775 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2776 BT_DBG("Exit LOCAL_BUSY");
2777 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2778
2779 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2780 struct l2cap_ctrl local_control;
2781 memset(&local_control, 0, sizeof(local_control));
2782 local_control.sframe = 1;
2783 local_control.super = L2CAP_SUPER_RR;
2784 local_control.poll = 1;
2785 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002786 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002787
2788 chan->retry_count = 1;
2789 __set_monitor_timer(chan);
2790 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2791 }
2792 break;
2793 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2794 l2cap_process_reqseq(chan, control->reqseq);
2795
2796 /* Fall through */
2797
2798 case L2CAP_EV_RECV_FBIT:
2799 if (control && control->final) {
2800 __clear_monitor_timer(chan);
2801 if (chan->unacked_frames > 0)
2802 __set_retrans_timer(chan);
2803 chan->retry_count = 0;
2804 chan->tx_state = L2CAP_TX_STATE_XMIT;
2805 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2806 }
2807 break;
2808 case L2CAP_EV_EXPLICIT_POLL:
2809 /* Ignore */
2810 break;
2811 case L2CAP_EV_MONITOR_TO:
2812 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2813 l2cap_send_rr_or_rnr(chan, 1);
2814 __set_monitor_timer(chan);
2815 chan->retry_count++;
2816 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002817 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002818 }
2819 break;
2820 default:
2821 break;
2822 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002823}
2824
Gustavo Padovand6603662012-05-21 13:58:22 -03002825static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2826 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002827{
Mat Martineau608bcc62012-05-17 20:53:32 -07002828 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2829 chan, control, skbs, event, chan->tx_state);
2830
2831 switch (chan->tx_state) {
2832 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002833 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002834 break;
2835 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002836 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002837 break;
2838 default:
2839 /* Ignore event */
2840 break;
2841 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002842}
2843
Mat Martineau4b51dae92012-05-17 20:53:37 -07002844static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2845 struct l2cap_ctrl *control)
2846{
2847 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002848 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002849}
2850
Mat Martineauf80842a2012-05-17 20:53:46 -07002851static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2852 struct l2cap_ctrl *control)
2853{
2854 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002855 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002856}
2857
Linus Torvalds1da177e2005-04-16 15:20:36 -07002858/* Copy frame to all raw sockets on that connection */
2859static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2860{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002861 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002862 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002863
2864 BT_DBG("conn %p", conn);
2865
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002866 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002867
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002868 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002869 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002870 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871 continue;
2872
2873 /* Don't send frame to the socket it came from */
2874 if (skb->sk == sk)
2875 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002876 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002877 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002878 continue;
2879
Gustavo Padovan80b98022012-05-27 22:27:51 -03002880 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002881 kfree_skb(nskb);
2882 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002883
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002884 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002885}
2886
2887/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002888static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2889 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002890{
2891 struct sk_buff *skb, **frag;
2892 struct l2cap_cmd_hdr *cmd;
2893 struct l2cap_hdr *lh;
2894 int len, count;
2895
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002896 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2897 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002898
Anderson Lizardo300b9622013-06-02 16:30:40 -04002899 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2900 return NULL;
2901
Linus Torvalds1da177e2005-04-16 15:20:36 -07002902 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2903 count = min_t(unsigned int, conn->mtu, len);
2904
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002905 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906 if (!skb)
2907 return NULL;
2908
2909 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002910 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002911
2912 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002913 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002914 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002915 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002916
2917 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2918 cmd->code = code;
2919 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002920 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002921
2922 if (dlen) {
2923 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2924 memcpy(skb_put(skb, count), data, count);
2925 data += count;
2926 }
2927
2928 len -= skb->len;
2929
2930 /* Continuation fragments (no L2CAP header) */
2931 frag = &skb_shinfo(skb)->frag_list;
2932 while (len) {
2933 count = min_t(unsigned int, conn->mtu, len);
2934
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002935 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002936 if (!*frag)
2937 goto fail;
2938
2939 memcpy(skb_put(*frag, count), data, count);
2940
2941 len -= count;
2942 data += count;
2943
2944 frag = &(*frag)->next;
2945 }
2946
2947 return skb;
2948
2949fail:
2950 kfree_skb(skb);
2951 return NULL;
2952}
2953
Gustavo Padovan2d792812012-10-06 10:07:01 +01002954static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2955 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002956{
2957 struct l2cap_conf_opt *opt = *ptr;
2958 int len;
2959
2960 len = L2CAP_CONF_OPT_SIZE + opt->len;
2961 *ptr += len;
2962
2963 *type = opt->type;
2964 *olen = opt->len;
2965
2966 switch (opt->len) {
2967 case 1:
2968 *val = *((u8 *) opt->val);
2969 break;
2970
2971 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002972 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002973 break;
2974
2975 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002976 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977 break;
2978
2979 default:
2980 *val = (unsigned long) opt->val;
2981 break;
2982 }
2983
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002984 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985 return len;
2986}
2987
Linus Torvalds1da177e2005-04-16 15:20:36 -07002988static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2989{
2990 struct l2cap_conf_opt *opt = *ptr;
2991
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002992 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002993
2994 opt->type = type;
2995 opt->len = len;
2996
2997 switch (len) {
2998 case 1:
2999 *((u8 *) opt->val) = val;
3000 break;
3001
3002 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003003 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003004 break;
3005
3006 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003007 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003008 break;
3009
3010 default:
3011 memcpy(opt->val, (void *) val, len);
3012 break;
3013 }
3014
3015 *ptr += L2CAP_CONF_OPT_SIZE + len;
3016}
3017
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003018static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
3019{
3020 struct l2cap_conf_efs efs;
3021
Szymon Janc1ec918c2011-11-16 09:32:21 +01003022 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003023 case L2CAP_MODE_ERTM:
3024 efs.id = chan->local_id;
3025 efs.stype = chan->local_stype;
3026 efs.msdu = cpu_to_le16(chan->local_msdu);
3027 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003028 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003029 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003030 break;
3031
3032 case L2CAP_MODE_STREAMING:
3033 efs.id = 1;
3034 efs.stype = L2CAP_SERV_BESTEFFORT;
3035 efs.msdu = cpu_to_le16(chan->local_msdu);
3036 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
3037 efs.acc_lat = 0;
3038 efs.flush_to = 0;
3039 break;
3040
3041 default:
3042 return;
3043 }
3044
3045 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003046 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003047}
3048
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003049static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003050{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003051 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003052 ack_timer.work);
3053 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003054
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003055 BT_DBG("chan %p", chan);
3056
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003057 l2cap_chan_lock(chan);
3058
Mat Martineau03625202012-05-17 20:53:51 -07003059 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3060 chan->last_acked_seq);
3061
3062 if (frames_to_ack)
3063 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003064
3065 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003066 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003067}
3068
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003069int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003070{
Mat Martineau3c588192012-04-11 10:48:42 -07003071 int err;
3072
Mat Martineau105bdf92012-04-27 16:50:48 -07003073 chan->next_tx_seq = 0;
3074 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003075 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003076 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003077 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003078 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003079 chan->last_acked_seq = 0;
3080 chan->sdu = NULL;
3081 chan->sdu_last_frag = NULL;
3082 chan->sdu_len = 0;
3083
Mat Martineaud34c34f2012-05-14 14:49:27 -07003084 skb_queue_head_init(&chan->tx_q);
3085
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003086 chan->local_amp_id = AMP_ID_BREDR;
3087 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003088 chan->move_state = L2CAP_MOVE_STABLE;
3089 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3090
Mat Martineau105bdf92012-04-27 16:50:48 -07003091 if (chan->mode != L2CAP_MODE_ERTM)
3092 return 0;
3093
3094 chan->rx_state = L2CAP_RX_STATE_RECV;
3095 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003096
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003097 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3098 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3099 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003100
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003101 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003102
Mat Martineau3c588192012-04-11 10:48:42 -07003103 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3104 if (err < 0)
3105 return err;
3106
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003107 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3108 if (err < 0)
3109 l2cap_seq_list_free(&chan->srej_list);
3110
3111 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003112}
3113
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003114static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3115{
3116 switch (mode) {
3117 case L2CAP_MODE_STREAMING:
3118 case L2CAP_MODE_ERTM:
3119 if (l2cap_mode_supported(mode, remote_feat_mask))
3120 return mode;
3121 /* fall through */
3122 default:
3123 return L2CAP_MODE_BASIC;
3124 }
3125}
3126
Marcel Holtmann848566b2013-10-01 22:59:22 -07003127static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003128{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003129 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003130}
3131
Marcel Holtmann848566b2013-10-01 22:59:22 -07003132static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003133{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003134 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003135}
3136
Mat Martineau36c86c82012-10-23 15:24:20 -07003137static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3138 struct l2cap_conf_rfc *rfc)
3139{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003140 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003141 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3142
3143 /* Class 1 devices have must have ERTM timeouts
3144 * exceeding the Link Supervision Timeout. The
3145 * default Link Supervision Timeout for AMP
3146 * controllers is 10 seconds.
3147 *
3148 * Class 1 devices use 0xffffffff for their
3149 * best-effort flush timeout, so the clamping logic
3150 * will result in a timeout that meets the above
3151 * requirement. ERTM timeouts are 16-bit values, so
3152 * the maximum timeout is 65.535 seconds.
3153 */
3154
3155 /* Convert timeout to milliseconds and round */
3156 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3157
3158 /* This is the recommended formula for class 2 devices
3159 * that start ERTM timers when packets are sent to the
3160 * controller.
3161 */
3162 ertm_to = 3 * ertm_to + 500;
3163
3164 if (ertm_to > 0xffff)
3165 ertm_to = 0xffff;
3166
3167 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3168 rfc->monitor_timeout = rfc->retrans_timeout;
3169 } else {
3170 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3171 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3172 }
3173}
3174
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003175static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3176{
3177 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003178 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003179 /* use extended control field */
3180 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003181 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3182 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003183 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003184 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003185 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3186 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003187 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003188}
3189
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003190static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003191{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003192 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003193 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003194 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003195 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003196
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003197 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003198
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003199 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003200 goto done;
3201
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003202 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003203 case L2CAP_MODE_STREAMING:
3204 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003205 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003206 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003207
Marcel Holtmann848566b2013-10-01 22:59:22 -07003208 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003209 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3210
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003211 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003212 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003213 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003214 break;
3215 }
3216
3217done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003218 if (chan->imtu != L2CAP_DEFAULT_MTU)
3219 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003220
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003221 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003222 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003223 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003224 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003225 break;
3226
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003227 rfc.mode = L2CAP_MODE_BASIC;
3228 rfc.txwin_size = 0;
3229 rfc.max_transmit = 0;
3230 rfc.retrans_timeout = 0;
3231 rfc.monitor_timeout = 0;
3232 rfc.max_pdu_size = 0;
3233
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003234 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003235 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003236 break;
3237
3238 case L2CAP_MODE_ERTM:
3239 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003240 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003241
3242 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003243
3244 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003245 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3246 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003247 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003248
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003249 l2cap_txwin_setup(chan);
3250
3251 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003252 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003253
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003254 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003255 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003256
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003257 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3258 l2cap_add_opt_efs(&ptr, chan);
3259
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003260 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3261 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003262 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003263
3264 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3265 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003266 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003267 chan->fcs = L2CAP_FCS_NONE;
3268 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3269 chan->fcs);
3270 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003271 break;
3272
3273 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003274 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003275 rfc.mode = L2CAP_MODE_STREAMING;
3276 rfc.txwin_size = 0;
3277 rfc.max_transmit = 0;
3278 rfc.retrans_timeout = 0;
3279 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003280
3281 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003282 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3283 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003284 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003285
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003286 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003287 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003288
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003289 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3290 l2cap_add_opt_efs(&ptr, chan);
3291
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003292 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3293 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003294 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003295 chan->fcs = L2CAP_FCS_NONE;
3296 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3297 chan->fcs);
3298 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003299 break;
3300 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003301
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003302 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003303 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003304
3305 return ptr - data;
3306}
3307
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003308static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003309{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003310 struct l2cap_conf_rsp *rsp = data;
3311 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003312 void *req = chan->conf_req;
3313 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003314 int type, hint, olen;
3315 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003316 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003317 struct l2cap_conf_efs efs;
3318 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003319 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003320 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003321 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003322
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003323 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003324
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003325 while (len >= L2CAP_CONF_OPT_SIZE) {
3326 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003327
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003328 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003329 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003330
3331 switch (type) {
3332 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003333 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003334 break;
3335
3336 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003337 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003338 break;
3339
3340 case L2CAP_CONF_QOS:
3341 break;
3342
Marcel Holtmann6464f352007-10-20 13:39:51 +02003343 case L2CAP_CONF_RFC:
3344 if (olen == sizeof(rfc))
3345 memcpy(&rfc, (void *) val, olen);
3346 break;
3347
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003348 case L2CAP_CONF_FCS:
3349 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003350 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003351 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003352
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003353 case L2CAP_CONF_EFS:
3354 remote_efs = 1;
3355 if (olen == sizeof(efs))
3356 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003357 break;
3358
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003359 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003360 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003361 return -ECONNREFUSED;
3362
3363 set_bit(FLAG_EXT_CTRL, &chan->flags);
3364 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003365 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003366 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003367 break;
3368
3369 default:
3370 if (hint)
3371 break;
3372
3373 result = L2CAP_CONF_UNKNOWN;
3374 *((u8 *) ptr++) = type;
3375 break;
3376 }
3377 }
3378
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003379 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003380 goto done;
3381
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003382 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003383 case L2CAP_MODE_STREAMING:
3384 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003385 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003386 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003387 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003388 break;
3389 }
3390
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003391 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003392 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003393 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3394 else
3395 return -ECONNREFUSED;
3396 }
3397
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003398 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003399 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003400
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003401 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003402 }
3403
3404done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003405 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003406 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003407 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003408
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003409 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003410 return -ECONNREFUSED;
3411
Gustavo Padovan2d792812012-10-06 10:07:01 +01003412 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3413 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003414 }
3415
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003416 if (result == L2CAP_CONF_SUCCESS) {
3417 /* Configure output options and let the other side know
3418 * which ones we don't like. */
3419
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003420 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3421 result = L2CAP_CONF_UNACCEPT;
3422 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003423 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003424 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003425 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003426 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003427
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003428 if (remote_efs) {
3429 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003430 efs.stype != L2CAP_SERV_NOTRAFIC &&
3431 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003432
3433 result = L2CAP_CONF_UNACCEPT;
3434
3435 if (chan->num_conf_req >= 1)
3436 return -ECONNREFUSED;
3437
3438 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003439 sizeof(efs),
3440 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003441 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003442 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003443 result = L2CAP_CONF_PENDING;
3444 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003445 }
3446 }
3447
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003448 switch (rfc.mode) {
3449 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003450 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003451 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003452 break;
3453
3454 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003455 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3456 chan->remote_tx_win = rfc.txwin_size;
3457 else
3458 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3459
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003460 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003461
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003462 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003463 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3464 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003465 rfc.max_pdu_size = cpu_to_le16(size);
3466 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003467
Mat Martineau36c86c82012-10-23 15:24:20 -07003468 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003469
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003470 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003471
3472 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003473 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003474
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003475 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3476 chan->remote_id = efs.id;
3477 chan->remote_stype = efs.stype;
3478 chan->remote_msdu = le16_to_cpu(efs.msdu);
3479 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003480 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003481 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003482 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003483 chan->remote_sdu_itime =
3484 le32_to_cpu(efs.sdu_itime);
3485 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003486 sizeof(efs),
3487 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003488 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003489 break;
3490
3491 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003492 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003493 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3494 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003495 rfc.max_pdu_size = cpu_to_le16(size);
3496 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003497
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003498 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003499
Gustavo Padovan2d792812012-10-06 10:07:01 +01003500 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3501 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003502
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003503 break;
3504
3505 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003506 result = L2CAP_CONF_UNACCEPT;
3507
3508 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003509 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003510 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003511
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003512 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003513 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003514 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003515 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003516 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003517 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003518
3519 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003520}
3521
Gustavo Padovan2d792812012-10-06 10:07:01 +01003522static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3523 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003524{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003525 struct l2cap_conf_req *req = data;
3526 void *ptr = req->data;
3527 int type, olen;
3528 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003529 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003530 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003531
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003532 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003533
3534 while (len >= L2CAP_CONF_OPT_SIZE) {
3535 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3536
3537 switch (type) {
3538 case L2CAP_CONF_MTU:
3539 if (val < L2CAP_DEFAULT_MIN_MTU) {
3540 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003541 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003542 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003543 chan->imtu = val;
3544 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003545 break;
3546
3547 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003548 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003549 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003550 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003551 break;
3552
3553 case L2CAP_CONF_RFC:
3554 if (olen == sizeof(rfc))
3555 memcpy(&rfc, (void *)val, olen);
3556
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003557 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003558 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003559 return -ECONNREFUSED;
3560
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003561 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003562
3563 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003564 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003565 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003566
3567 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003568 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003569 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003570 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003571 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003572
3573 case L2CAP_CONF_EFS:
3574 if (olen == sizeof(efs))
3575 memcpy(&efs, (void *)val, olen);
3576
3577 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003578 efs.stype != L2CAP_SERV_NOTRAFIC &&
3579 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003580 return -ECONNREFUSED;
3581
Gustavo Padovan2d792812012-10-06 10:07:01 +01003582 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3583 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003584 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003585
3586 case L2CAP_CONF_FCS:
3587 if (*result == L2CAP_CONF_PENDING)
3588 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003589 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003590 &chan->conf_state);
3591 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003592 }
3593 }
3594
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003595 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003596 return -ECONNREFUSED;
3597
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003598 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003599
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003600 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003601 switch (rfc.mode) {
3602 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003603 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3604 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3605 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003606 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3607 chan->ack_win = min_t(u16, chan->ack_win,
3608 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003609
3610 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3611 chan->local_msdu = le16_to_cpu(efs.msdu);
3612 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003613 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003614 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3615 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003616 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003617 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003618 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003619
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003620 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003621 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003622 }
3623 }
3624
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003625 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003626 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003627
3628 return ptr - data;
3629}
3630
Gustavo Padovan2d792812012-10-06 10:07:01 +01003631static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3632 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003633{
3634 struct l2cap_conf_rsp *rsp = data;
3635 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003636
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003637 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003638
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003639 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003640 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003641 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003642
3643 return ptr - data;
3644}
3645
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003646void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003647{
3648 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003649 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003650 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003651 u8 rsp_code;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003652
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003653 rsp.scid = cpu_to_le16(chan->dcid);
3654 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003655 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3656 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003657
3658 if (chan->hs_hcon)
3659 rsp_code = L2CAP_CREATE_CHAN_RSP;
3660 else
3661 rsp_code = L2CAP_CONN_RSP;
3662
3663 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3664
3665 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003666
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003667 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003668 return;
3669
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003670 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003671 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003672 chan->num_conf_req++;
3673}
3674
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003675static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003676{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003677 int type, olen;
3678 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003679 /* Use sane default values in case a misbehaving remote device
3680 * did not send an RFC or extended window size option.
3681 */
3682 u16 txwin_ext = chan->ack_win;
3683 struct l2cap_conf_rfc rfc = {
3684 .mode = chan->mode,
3685 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3686 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3687 .max_pdu_size = cpu_to_le16(chan->imtu),
3688 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3689 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003690
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003691 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003692
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003693 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003694 return;
3695
3696 while (len >= L2CAP_CONF_OPT_SIZE) {
3697 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3698
Mat Martineauc20f8e32012-07-10 05:47:07 -07003699 switch (type) {
3700 case L2CAP_CONF_RFC:
3701 if (olen == sizeof(rfc))
3702 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003703 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003704 case L2CAP_CONF_EWS:
3705 txwin_ext = val;
3706 break;
3707 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003708 }
3709
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003710 switch (rfc.mode) {
3711 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003712 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3713 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003714 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3715 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3716 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3717 else
3718 chan->ack_win = min_t(u16, chan->ack_win,
3719 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003720 break;
3721 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003722 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003723 }
3724}
3725
Gustavo Padovan2d792812012-10-06 10:07:01 +01003726static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003727 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3728 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003729{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003730 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003731
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003732 if (cmd_len < sizeof(*rej))
3733 return -EPROTO;
3734
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003735 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003736 return 0;
3737
3738 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003739 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003740 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003741
3742 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003743 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003744
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003745 l2cap_conn_start(conn);
3746 }
3747
3748 return 0;
3749}
3750
Mat Martineau17009152012-10-23 15:24:07 -07003751static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3752 struct l2cap_cmd_hdr *cmd,
3753 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003754{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003755 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3756 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003757 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003758 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003759 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003760
3761 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003762 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003763
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003764 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003765
3766 /* Check if we have socket listening on psm */
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003767 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07003768 &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003769 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003770 result = L2CAP_CR_BAD_PSM;
3771 goto sendresp;
3772 }
3773
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003774 parent = pchan->sk;
3775
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003776 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003777 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003778
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003779 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003780 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003781 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003782 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003783 result = L2CAP_CR_SEC_BLOCK;
3784 goto response;
3785 }
3786
Linus Torvalds1da177e2005-04-16 15:20:36 -07003787 result = L2CAP_CR_NO_MEM;
3788
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003789 /* Check if we already have channel with that dcid */
3790 if (__l2cap_get_chan_by_dcid(conn, scid))
3791 goto response;
3792
Gustavo Padovan80b98022012-05-27 22:27:51 -03003793 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003794 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003795 goto response;
3796
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003797 sk = chan->sk;
3798
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09003799 /* For certain devices (ex: HID mouse), support for authentication,
3800 * pairing and bonding is optional. For such devices, inorder to avoid
3801 * the ACL alive for too long after L2CAP disconnection, reset the ACL
3802 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
3803 */
3804 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3805
Marcel Holtmann7eafc592013-10-13 08:12:47 -07003806 bacpy(&chan->src, &conn->hcon->src);
3807 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07003808 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
3809 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003810 chan->psm = psm;
3811 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003812 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003813
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003814 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003815
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003816 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003817
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003818 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003819
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003820 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003821
Marcel Holtmann984947d2009-02-06 23:35:19 +01003822 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003823 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07003824 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003825 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003826 result = L2CAP_CR_PEND;
3827 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003828 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003829 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003830 /* Force pending result for AMP controllers.
3831 * The connection will succeed after the
3832 * physical link is up.
3833 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003834 if (amp_id == AMP_ID_BREDR) {
Mat Martineau17009152012-10-23 15:24:07 -07003835 __l2cap_state_change(chan, BT_CONFIG);
3836 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003837 } else {
3838 __l2cap_state_change(chan, BT_CONNECT2);
3839 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07003840 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003841 status = L2CAP_CS_NO_INFO;
3842 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003843 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003844 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003845 result = L2CAP_CR_PEND;
3846 status = L2CAP_CS_AUTHEN_PEND;
3847 }
3848 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003849 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003850 result = L2CAP_CR_PEND;
3851 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003852 }
3853
Linus Torvalds1da177e2005-04-16 15:20:36 -07003854response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003855 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003856 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003857
3858sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003859 rsp.scid = cpu_to_le16(scid);
3860 rsp.dcid = cpu_to_le16(dcid);
3861 rsp.result = cpu_to_le16(result);
3862 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003863 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003864
3865 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3866 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003867 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003868
3869 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3870 conn->info_ident = l2cap_get_ident(conn);
3871
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003872 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003873
Gustavo Padovan2d792812012-10-06 10:07:01 +01003874 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3875 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003876 }
3877
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003878 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003879 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003880 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003881 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003882 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003883 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003884 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003885 }
Mat Martineau17009152012-10-23 15:24:07 -07003886
3887 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003888}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003889
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003890static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003891 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003892{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303893 struct hci_dev *hdev = conn->hcon->hdev;
3894 struct hci_conn *hcon = conn->hcon;
3895
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003896 if (cmd_len < sizeof(struct l2cap_conn_req))
3897 return -EPROTO;
3898
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303899 hci_dev_lock(hdev);
3900 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3901 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3902 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3903 hcon->dst_type, 0, NULL, 0,
3904 hcon->dev_class);
3905 hci_dev_unlock(hdev);
3906
Gustavo Padovan300229f2012-10-12 19:40:40 +08003907 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003908 return 0;
3909}
3910
Mat Martineau5909cf32012-10-23 15:24:08 -07003911static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003912 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3913 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003914{
3915 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3916 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003917 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003918 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003919 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003920
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003921 if (cmd_len < sizeof(*rsp))
3922 return -EPROTO;
3923
Linus Torvalds1da177e2005-04-16 15:20:36 -07003924 scid = __le16_to_cpu(rsp->scid);
3925 dcid = __le16_to_cpu(rsp->dcid);
3926 result = __le16_to_cpu(rsp->result);
3927 status = __le16_to_cpu(rsp->status);
3928
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003929 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 +01003930 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003931
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003932 mutex_lock(&conn->chan_lock);
3933
Linus Torvalds1da177e2005-04-16 15:20:36 -07003934 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003935 chan = __l2cap_get_chan_by_scid(conn, scid);
3936 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003937 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003938 goto unlock;
3939 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003940 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003941 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3942 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003943 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003944 goto unlock;
3945 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003946 }
3947
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003948 err = 0;
3949
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003950 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003951
Linus Torvalds1da177e2005-04-16 15:20:36 -07003952 switch (result) {
3953 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003954 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003955 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003956 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003957 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003958
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003959 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003960 break;
3961
Linus Torvalds1da177e2005-04-16 15:20:36 -07003962 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003963 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003964 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003965 break;
3966
3967 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003968 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003969 break;
3970
3971 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003972 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003973 break;
3974 }
3975
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003976 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003977
3978unlock:
3979 mutex_unlock(&conn->chan_lock);
3980
3981 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003982}
3983
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003984static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003985{
3986 /* FCS is enabled only in ERTM or streaming mode, if one or both
3987 * sides request it.
3988 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003989 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003990 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003991 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003992 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003993}
3994
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003995static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3996 u8 ident, u16 flags)
3997{
3998 struct l2cap_conn *conn = chan->conn;
3999
4000 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
4001 flags);
4002
4003 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
4004 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
4005
4006 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
4007 l2cap_build_conf_rsp(chan, data,
4008 L2CAP_CONF_SUCCESS, flags), data);
4009}
4010
Gustavo Padovan2d792812012-10-06 10:07:01 +01004011static inline int l2cap_config_req(struct l2cap_conn *conn,
4012 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4013 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004014{
4015 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
4016 u16 dcid, flags;
4017 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004018 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07004019 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004020
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004021 if (cmd_len < sizeof(*req))
4022 return -EPROTO;
4023
Linus Torvalds1da177e2005-04-16 15:20:36 -07004024 dcid = __le16_to_cpu(req->dcid);
4025 flags = __le16_to_cpu(req->flags);
4026
4027 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
4028
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004029 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004030 if (!chan)
Johan Hedberg21870b52013-09-16 13:05:14 +03004031 return -EBADSLT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004032
David S. Miller033b1142011-07-21 13:38:42 -07004033 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004034 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004035
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004036 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004037 rej.scid = cpu_to_le16(chan->scid);
4038 rej.dcid = cpu_to_le16(chan->dcid);
4039
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004040 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004041 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004042 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004043 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004044
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004045 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004046 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004047 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004048 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004049 l2cap_build_conf_rsp(chan, rsp,
4050 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004051 goto unlock;
4052 }
4053
4054 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004055 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4056 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004057
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004058 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004059 /* Incomplete config. Send empty response. */
4060 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004061 l2cap_build_conf_rsp(chan, rsp,
4062 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004063 goto unlock;
4064 }
4065
4066 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004067 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004068 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004069 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004070 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004071 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004072
Mat Martineau1500109b2012-10-23 15:24:15 -07004073 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004074 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004075 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004076
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004077 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004078 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004079
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004080 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004081 goto unlock;
4082
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004083 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004084 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004085
Mat Martineau105bdf92012-04-27 16:50:48 -07004086 if (chan->mode == L2CAP_MODE_ERTM ||
4087 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004088 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004089
Mat Martineau3c588192012-04-11 10:48:42 -07004090 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004091 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004092 else
4093 l2cap_chan_ready(chan);
4094
Marcel Holtmann876d9482007-10-20 13:35:42 +02004095 goto unlock;
4096 }
4097
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004098 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004099 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004100 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004101 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004102 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004103 }
4104
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004105 /* Got Conf Rsp PENDING from remote side and asume we sent
4106 Conf Rsp PENDING in the code above */
4107 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004108 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004109
4110 /* check compatibility */
4111
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004112 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004113 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004114 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4115 else
4116 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004117 }
4118
Linus Torvalds1da177e2005-04-16 15:20:36 -07004119unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004120 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004121 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004122}
4123
Gustavo Padovan2d792812012-10-06 10:07:01 +01004124static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004125 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4126 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004127{
4128 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4129 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004130 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004131 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004132 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004133
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004134 if (cmd_len < sizeof(*rsp))
4135 return -EPROTO;
4136
Linus Torvalds1da177e2005-04-16 15:20:36 -07004137 scid = __le16_to_cpu(rsp->scid);
4138 flags = __le16_to_cpu(rsp->flags);
4139 result = __le16_to_cpu(rsp->result);
4140
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004141 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4142 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004143
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004144 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004145 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004146 return 0;
4147
4148 switch (result) {
4149 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004150 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004151 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004152 break;
4153
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004154 case L2CAP_CONF_PENDING:
4155 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4156
4157 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4158 char buf[64];
4159
4160 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004161 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004162 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004163 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004164 goto done;
4165 }
4166
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004167 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004168 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4169 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004170 } else {
4171 if (l2cap_check_efs(chan)) {
4172 amp_create_logical_link(chan);
4173 chan->ident = cmd->ident;
4174 }
4175 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004176 }
4177 goto done;
4178
Linus Torvalds1da177e2005-04-16 15:20:36 -07004179 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004180 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004181 char req[64];
4182
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004183 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004184 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004185 goto done;
4186 }
4187
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004188 /* throw out any old stored conf requests */
4189 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004190 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004191 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004192 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004193 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004194 goto done;
4195 }
4196
4197 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004198 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004199 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004200 if (result != L2CAP_CONF_SUCCESS)
4201 goto done;
4202 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004203 }
4204
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004205 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004206 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004207
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004208 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004209 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004210 goto done;
4211 }
4212
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004213 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004214 goto done;
4215
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004216 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004217
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004218 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004219 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004220
Mat Martineau105bdf92012-04-27 16:50:48 -07004221 if (chan->mode == L2CAP_MODE_ERTM ||
4222 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004223 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004224
Mat Martineau3c588192012-04-11 10:48:42 -07004225 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004226 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004227 else
4228 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004229 }
4230
4231done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004232 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004233 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004234}
4235
Gustavo Padovan2d792812012-10-06 10:07:01 +01004236static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004237 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4238 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004239{
4240 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4241 struct l2cap_disconn_rsp rsp;
4242 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004243 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004244 struct sock *sk;
4245
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004246 if (cmd_len != sizeof(*req))
4247 return -EPROTO;
4248
Linus Torvalds1da177e2005-04-16 15:20:36 -07004249 scid = __le16_to_cpu(req->scid);
4250 dcid = __le16_to_cpu(req->dcid);
4251
4252 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4253
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004254 mutex_lock(&conn->chan_lock);
4255
4256 chan = __l2cap_get_chan_by_scid(conn, dcid);
4257 if (!chan) {
4258 mutex_unlock(&conn->chan_lock);
Johan Hedbergc4ea2492013-09-16 13:05:15 +03004259 return -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004260 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004261
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004262 l2cap_chan_lock(chan);
4263
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004264 sk = chan->sk;
4265
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004266 rsp.dcid = cpu_to_le16(chan->scid);
4267 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004268 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4269
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004270 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004271 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004272 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004273
Mat Martineau61d6ef32012-04-27 16:50:50 -07004274 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004275 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004276
4277 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004278
Gustavo Padovan80b98022012-05-27 22:27:51 -03004279 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004280 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004281
4282 mutex_unlock(&conn->chan_lock);
4283
Linus Torvalds1da177e2005-04-16 15:20:36 -07004284 return 0;
4285}
4286
Gustavo Padovan2d792812012-10-06 10:07:01 +01004287static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004288 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4289 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004290{
4291 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4292 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004293 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004294
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004295 if (cmd_len != sizeof(*rsp))
4296 return -EPROTO;
4297
Linus Torvalds1da177e2005-04-16 15:20:36 -07004298 scid = __le16_to_cpu(rsp->scid);
4299 dcid = __le16_to_cpu(rsp->dcid);
4300
4301 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4302
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004303 mutex_lock(&conn->chan_lock);
4304
4305 chan = __l2cap_get_chan_by_scid(conn, scid);
4306 if (!chan) {
4307 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004308 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004309 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004310
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004311 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004312
Mat Martineau61d6ef32012-04-27 16:50:50 -07004313 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004314 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004315
4316 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004317
Gustavo Padovan80b98022012-05-27 22:27:51 -03004318 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004319 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004320
4321 mutex_unlock(&conn->chan_lock);
4322
Linus Torvalds1da177e2005-04-16 15:20:36 -07004323 return 0;
4324}
4325
Gustavo Padovan2d792812012-10-06 10:07:01 +01004326static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004327 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4328 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004329{
4330 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004331 u16 type;
4332
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004333 if (cmd_len != sizeof(*req))
4334 return -EPROTO;
4335
Linus Torvalds1da177e2005-04-16 15:20:36 -07004336 type = __le16_to_cpu(req->type);
4337
4338 BT_DBG("type 0x%4.4x", type);
4339
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004340 if (type == L2CAP_IT_FEAT_MASK) {
4341 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004342 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004343 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004344 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4345 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004346 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004347 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004348 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004349 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004350 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004351 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004352
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004353 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004354 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4355 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004356 } else if (type == L2CAP_IT_FIXED_CHAN) {
4357 u8 buf[12];
4358 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004359
Marcel Holtmann848566b2013-10-01 22:59:22 -07004360 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004361 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4362 else
4363 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4364
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004365 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4366 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004367 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004368 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4369 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004370 } else {
4371 struct l2cap_info_rsp rsp;
4372 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004373 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004374 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4375 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004376 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004377
4378 return 0;
4379}
4380
Gustavo Padovan2d792812012-10-06 10:07:01 +01004381static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004382 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4383 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004384{
4385 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4386 u16 type, result;
4387
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304388 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004389 return -EPROTO;
4390
Linus Torvalds1da177e2005-04-16 15:20:36 -07004391 type = __le16_to_cpu(rsp->type);
4392 result = __le16_to_cpu(rsp->result);
4393
4394 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4395
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004396 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4397 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004398 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004399 return 0;
4400
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004401 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004402
Ville Tervoadb08ed2010-08-04 09:43:33 +03004403 if (result != L2CAP_IR_SUCCESS) {
4404 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4405 conn->info_ident = 0;
4406
4407 l2cap_conn_start(conn);
4408
4409 return 0;
4410 }
4411
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004412 switch (type) {
4413 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004414 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004415
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004416 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004417 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004418 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004419
4420 conn->info_ident = l2cap_get_ident(conn);
4421
4422 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004423 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004424 } else {
4425 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4426 conn->info_ident = 0;
4427
4428 l2cap_conn_start(conn);
4429 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004430 break;
4431
4432 case L2CAP_IT_FIXED_CHAN:
4433 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004434 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004435 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004436
4437 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004438 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004439 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004440
Linus Torvalds1da177e2005-04-16 15:20:36 -07004441 return 0;
4442}
4443
Mat Martineau17009152012-10-23 15:24:07 -07004444static int l2cap_create_channel_req(struct l2cap_conn *conn,
4445 struct l2cap_cmd_hdr *cmd,
4446 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004447{
4448 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004449 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004450 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004451 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004452 u16 psm, scid;
4453
4454 if (cmd_len != sizeof(*req))
4455 return -EPROTO;
4456
Marcel Holtmann848566b2013-10-01 22:59:22 -07004457 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004458 return -EINVAL;
4459
4460 psm = le16_to_cpu(req->psm);
4461 scid = le16_to_cpu(req->scid);
4462
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004463 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 -07004464
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004465 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004466 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004467 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4468 req->amp_id);
4469 return 0;
4470 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004471
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004472 /* Validate AMP controller id */
4473 hdev = hci_dev_get(req->amp_id);
4474 if (!hdev)
4475 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004476
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004477 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004478 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004479 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004480 }
4481
4482 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4483 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004484 if (chan) {
4485 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4486 struct hci_conn *hs_hcon;
4487
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004488 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4489 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004490 if (!hs_hcon) {
4491 hci_dev_put(hdev);
Johan Hedberg21870b52013-09-16 13:05:14 +03004492 return -EBADSLT;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004493 }
4494
4495 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4496
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004497 mgr->bredr_chan = chan;
4498 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004499 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004500 conn->mtu = hdev->block_mtu;
4501 }
4502
4503 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004504
4505 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004506
4507error:
4508 rsp.dcid = 0;
4509 rsp.scid = cpu_to_le16(scid);
4510 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4511 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4512
4513 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4514 sizeof(rsp), &rsp);
4515
Johan Hedbergdc280802013-09-16 13:05:13 +03004516 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004517}
4518
Mat Martineau8eb200b2012-10-23 15:24:17 -07004519static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4520{
4521 struct l2cap_move_chan_req req;
4522 u8 ident;
4523
4524 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4525
4526 ident = l2cap_get_ident(chan->conn);
4527 chan->ident = ident;
4528
4529 req.icid = cpu_to_le16(chan->scid);
4530 req.dest_amp_id = dest_amp_id;
4531
4532 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4533 &req);
4534
4535 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4536}
4537
Mat Martineau1500109b2012-10-23 15:24:15 -07004538static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004539{
4540 struct l2cap_move_chan_rsp rsp;
4541
Mat Martineau1500109b2012-10-23 15:24:15 -07004542 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004543
Mat Martineau1500109b2012-10-23 15:24:15 -07004544 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004545 rsp.result = cpu_to_le16(result);
4546
Mat Martineau1500109b2012-10-23 15:24:15 -07004547 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4548 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004549}
4550
Mat Martineau5b155ef2012-10-23 15:24:14 -07004551static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004552{
4553 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004554
Mat Martineau5b155ef2012-10-23 15:24:14 -07004555 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004556
Mat Martineau5b155ef2012-10-23 15:24:14 -07004557 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004558
Mat Martineau5b155ef2012-10-23 15:24:14 -07004559 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004560 cfm.result = cpu_to_le16(result);
4561
Mat Martineau5b155ef2012-10-23 15:24:14 -07004562 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4563 sizeof(cfm), &cfm);
4564
4565 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4566}
4567
4568static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4569{
4570 struct l2cap_move_chan_cfm cfm;
4571
4572 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4573
4574 cfm.icid = cpu_to_le16(icid);
4575 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4576
4577 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4578 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004579}
4580
4581static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004582 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004583{
4584 struct l2cap_move_chan_cfm_rsp rsp;
4585
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004586 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004587
4588 rsp.icid = cpu_to_le16(icid);
4589 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4590}
4591
Mat Martineau5f3847a2012-10-23 15:24:12 -07004592static void __release_logical_link(struct l2cap_chan *chan)
4593{
4594 chan->hs_hchan = NULL;
4595 chan->hs_hcon = NULL;
4596
4597 /* Placeholder - release the logical link */
4598}
4599
Mat Martineau1500109b2012-10-23 15:24:15 -07004600static void l2cap_logical_fail(struct l2cap_chan *chan)
4601{
4602 /* Logical link setup failed */
4603 if (chan->state != BT_CONNECTED) {
4604 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004605 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004606 return;
4607 }
4608
4609 switch (chan->move_role) {
4610 case L2CAP_MOVE_ROLE_RESPONDER:
4611 l2cap_move_done(chan);
4612 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4613 break;
4614 case L2CAP_MOVE_ROLE_INITIATOR:
4615 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4616 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4617 /* Remote has only sent pending or
4618 * success responses, clean up
4619 */
4620 l2cap_move_done(chan);
4621 }
4622
4623 /* Other amp move states imply that the move
4624 * has already aborted
4625 */
4626 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4627 break;
4628 }
4629}
4630
4631static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4632 struct hci_chan *hchan)
4633{
4634 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004635
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004636 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004637 chan->hs_hcon->l2cap_data = chan->conn;
4638
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004639 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004640
4641 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004642 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004643
4644 set_default_fcs(chan);
4645
4646 err = l2cap_ertm_init(chan);
4647 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004648 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004649 else
4650 l2cap_chan_ready(chan);
4651 }
4652}
4653
4654static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4655 struct hci_chan *hchan)
4656{
4657 chan->hs_hcon = hchan->conn;
4658 chan->hs_hcon->l2cap_data = chan->conn;
4659
4660 BT_DBG("move_state %d", chan->move_state);
4661
4662 switch (chan->move_state) {
4663 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4664 /* Move confirm will be sent after a success
4665 * response is received
4666 */
4667 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4668 break;
4669 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4670 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4671 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4672 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4673 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4674 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4675 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4676 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4677 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4678 }
4679 break;
4680 default:
4681 /* Move was not in expected state, free the channel */
4682 __release_logical_link(chan);
4683
4684 chan->move_state = L2CAP_MOVE_STABLE;
4685 }
4686}
4687
4688/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004689void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4690 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004691{
Mat Martineau1500109b2012-10-23 15:24:15 -07004692 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4693
4694 if (status) {
4695 l2cap_logical_fail(chan);
4696 __release_logical_link(chan);
4697 return;
4698 }
4699
4700 if (chan->state != BT_CONNECTED) {
4701 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004702 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004703 l2cap_logical_finish_create(chan, hchan);
4704 } else {
4705 l2cap_logical_finish_move(chan, hchan);
4706 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004707}
4708
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004709void l2cap_move_start(struct l2cap_chan *chan)
4710{
4711 BT_DBG("chan %p", chan);
4712
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004713 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004714 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4715 return;
4716 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4717 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4718 /* Placeholder - start physical link setup */
4719 } else {
4720 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4721 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4722 chan->move_id = 0;
4723 l2cap_move_setup(chan);
4724 l2cap_send_move_chan_req(chan, 0);
4725 }
4726}
4727
Mat Martineau8eb200b2012-10-23 15:24:17 -07004728static void l2cap_do_create(struct l2cap_chan *chan, int result,
4729 u8 local_amp_id, u8 remote_amp_id)
4730{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004731 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4732 local_amp_id, remote_amp_id);
4733
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004734 chan->fcs = L2CAP_FCS_NONE;
4735
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004736 /* Outgoing channel on AMP */
4737 if (chan->state == BT_CONNECT) {
4738 if (result == L2CAP_CR_SUCCESS) {
4739 chan->local_amp_id = local_amp_id;
4740 l2cap_send_create_chan_req(chan, remote_amp_id);
4741 } else {
4742 /* Revert to BR/EDR connect */
4743 l2cap_send_conn_req(chan);
4744 }
4745
4746 return;
4747 }
4748
4749 /* Incoming channel on AMP */
4750 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004751 struct l2cap_conn_rsp rsp;
4752 char buf[128];
4753 rsp.scid = cpu_to_le16(chan->dcid);
4754 rsp.dcid = cpu_to_le16(chan->scid);
4755
Mat Martineau8eb200b2012-10-23 15:24:17 -07004756 if (result == L2CAP_CR_SUCCESS) {
4757 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004758 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4759 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004760 } else {
4761 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004762 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4763 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004764 }
4765
4766 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4767 sizeof(rsp), &rsp);
4768
4769 if (result == L2CAP_CR_SUCCESS) {
4770 __l2cap_state_change(chan, BT_CONFIG);
4771 set_bit(CONF_REQ_SENT, &chan->conf_state);
4772 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4773 L2CAP_CONF_REQ,
4774 l2cap_build_conf_req(chan, buf), buf);
4775 chan->num_conf_req++;
4776 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004777 }
4778}
4779
4780static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4781 u8 remote_amp_id)
4782{
4783 l2cap_move_setup(chan);
4784 chan->move_id = local_amp_id;
4785 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4786
4787 l2cap_send_move_chan_req(chan, remote_amp_id);
4788}
4789
4790static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4791{
4792 struct hci_chan *hchan = NULL;
4793
4794 /* Placeholder - get hci_chan for logical link */
4795
4796 if (hchan) {
4797 if (hchan->state == BT_CONNECTED) {
4798 /* Logical link is ready to go */
4799 chan->hs_hcon = hchan->conn;
4800 chan->hs_hcon->l2cap_data = chan->conn;
4801 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4802 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4803
4804 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4805 } else {
4806 /* Wait for logical link to be ready */
4807 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4808 }
4809 } else {
4810 /* Logical link not available */
4811 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4812 }
4813}
4814
4815static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4816{
4817 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4818 u8 rsp_result;
4819 if (result == -EINVAL)
4820 rsp_result = L2CAP_MR_BAD_ID;
4821 else
4822 rsp_result = L2CAP_MR_NOT_ALLOWED;
4823
4824 l2cap_send_move_chan_rsp(chan, rsp_result);
4825 }
4826
4827 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4828 chan->move_state = L2CAP_MOVE_STABLE;
4829
4830 /* Restart data transmission */
4831 l2cap_ertm_send(chan);
4832}
4833
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004834/* Invoke with locked chan */
4835void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004836{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004837 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004838 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004839
Mat Martineau8eb200b2012-10-23 15:24:17 -07004840 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4841 chan, result, local_amp_id, remote_amp_id);
4842
Mat Martineau8eb200b2012-10-23 15:24:17 -07004843 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4844 l2cap_chan_unlock(chan);
4845 return;
4846 }
4847
4848 if (chan->state != BT_CONNECTED) {
4849 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4850 } else if (result != L2CAP_MR_SUCCESS) {
4851 l2cap_do_move_cancel(chan, result);
4852 } else {
4853 switch (chan->move_role) {
4854 case L2CAP_MOVE_ROLE_INITIATOR:
4855 l2cap_do_move_initiate(chan, local_amp_id,
4856 remote_amp_id);
4857 break;
4858 case L2CAP_MOVE_ROLE_RESPONDER:
4859 l2cap_do_move_respond(chan, result);
4860 break;
4861 default:
4862 l2cap_do_move_cancel(chan, result);
4863 break;
4864 }
4865 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004866}
4867
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004868static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004869 struct l2cap_cmd_hdr *cmd,
4870 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004871{
4872 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004873 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004874 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004875 u16 icid = 0;
4876 u16 result = L2CAP_MR_NOT_ALLOWED;
4877
4878 if (cmd_len != sizeof(*req))
4879 return -EPROTO;
4880
4881 icid = le16_to_cpu(req->icid);
4882
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004883 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004884
Marcel Holtmann848566b2013-10-01 22:59:22 -07004885 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004886 return -EINVAL;
4887
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004888 chan = l2cap_get_chan_by_dcid(conn, icid);
4889 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004890 rsp.icid = cpu_to_le16(icid);
4891 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4892 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4893 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004894 return 0;
4895 }
4896
Mat Martineau1500109b2012-10-23 15:24:15 -07004897 chan->ident = cmd->ident;
4898
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004899 if (chan->scid < L2CAP_CID_DYN_START ||
4900 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4901 (chan->mode != L2CAP_MODE_ERTM &&
4902 chan->mode != L2CAP_MODE_STREAMING)) {
4903 result = L2CAP_MR_NOT_ALLOWED;
4904 goto send_move_response;
4905 }
4906
4907 if (chan->local_amp_id == req->dest_amp_id) {
4908 result = L2CAP_MR_SAME_ID;
4909 goto send_move_response;
4910 }
4911
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004912 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004913 struct hci_dev *hdev;
4914 hdev = hci_dev_get(req->dest_amp_id);
4915 if (!hdev || hdev->dev_type != HCI_AMP ||
4916 !test_bit(HCI_UP, &hdev->flags)) {
4917 if (hdev)
4918 hci_dev_put(hdev);
4919
4920 result = L2CAP_MR_BAD_ID;
4921 goto send_move_response;
4922 }
4923 hci_dev_put(hdev);
4924 }
4925
4926 /* Detect a move collision. Only send a collision response
4927 * if this side has "lost", otherwise proceed with the move.
4928 * The winner has the larger bd_addr.
4929 */
4930 if ((__chan_is_moving(chan) ||
4931 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07004932 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004933 result = L2CAP_MR_COLLISION;
4934 goto send_move_response;
4935 }
4936
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004937 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4938 l2cap_move_setup(chan);
4939 chan->move_id = req->dest_amp_id;
4940 icid = chan->dcid;
4941
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004942 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004943 /* Moving to BR/EDR */
4944 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4945 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4946 result = L2CAP_MR_PEND;
4947 } else {
4948 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4949 result = L2CAP_MR_SUCCESS;
4950 }
4951 } else {
4952 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4953 /* Placeholder - uncomment when amp functions are available */
4954 /*amp_accept_physical(chan, req->dest_amp_id);*/
4955 result = L2CAP_MR_PEND;
4956 }
4957
4958send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004959 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004960
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004961 l2cap_chan_unlock(chan);
4962
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004963 return 0;
4964}
4965
Mat Martineau5b155ef2012-10-23 15:24:14 -07004966static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4967{
4968 struct l2cap_chan *chan;
4969 struct hci_chan *hchan = NULL;
4970
4971 chan = l2cap_get_chan_by_scid(conn, icid);
4972 if (!chan) {
4973 l2cap_send_move_chan_cfm_icid(conn, icid);
4974 return;
4975 }
4976
4977 __clear_chan_timer(chan);
4978 if (result == L2CAP_MR_PEND)
4979 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4980
4981 switch (chan->move_state) {
4982 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4983 /* Move confirm will be sent when logical link
4984 * is complete.
4985 */
4986 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4987 break;
4988 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4989 if (result == L2CAP_MR_PEND) {
4990 break;
4991 } else if (test_bit(CONN_LOCAL_BUSY,
4992 &chan->conn_state)) {
4993 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4994 } else {
4995 /* Logical link is up or moving to BR/EDR,
4996 * proceed with move
4997 */
4998 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4999 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5000 }
5001 break;
5002 case L2CAP_MOVE_WAIT_RSP:
5003 /* Moving to AMP */
5004 if (result == L2CAP_MR_SUCCESS) {
5005 /* Remote is ready, send confirm immediately
5006 * after logical link is ready
5007 */
5008 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5009 } else {
5010 /* Both logical link and move success
5011 * are required to confirm
5012 */
5013 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
5014 }
5015
5016 /* Placeholder - get hci_chan for logical link */
5017 if (!hchan) {
5018 /* Logical link not available */
5019 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5020 break;
5021 }
5022
5023 /* If the logical link is not yet connected, do not
5024 * send confirmation.
5025 */
5026 if (hchan->state != BT_CONNECTED)
5027 break;
5028
5029 /* Logical link is already ready to go */
5030
5031 chan->hs_hcon = hchan->conn;
5032 chan->hs_hcon->l2cap_data = chan->conn;
5033
5034 if (result == L2CAP_MR_SUCCESS) {
5035 /* Can confirm now */
5036 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5037 } else {
5038 /* Now only need move success
5039 * to confirm
5040 */
5041 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
5042 }
5043
5044 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5045 break;
5046 default:
5047 /* Any other amp move state means the move failed. */
5048 chan->move_id = chan->local_amp_id;
5049 l2cap_move_done(chan);
5050 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5051 }
5052
5053 l2cap_chan_unlock(chan);
5054}
5055
5056static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5057 u16 result)
5058{
5059 struct l2cap_chan *chan;
5060
5061 chan = l2cap_get_chan_by_ident(conn, ident);
5062 if (!chan) {
5063 /* Could not locate channel, icid is best guess */
5064 l2cap_send_move_chan_cfm_icid(conn, icid);
5065 return;
5066 }
5067
5068 __clear_chan_timer(chan);
5069
5070 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5071 if (result == L2CAP_MR_COLLISION) {
5072 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5073 } else {
5074 /* Cleanup - cancel move */
5075 chan->move_id = chan->local_amp_id;
5076 l2cap_move_done(chan);
5077 }
5078 }
5079
5080 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5081
5082 l2cap_chan_unlock(chan);
5083}
5084
5085static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5086 struct l2cap_cmd_hdr *cmd,
5087 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005088{
5089 struct l2cap_move_chan_rsp *rsp = data;
5090 u16 icid, result;
5091
5092 if (cmd_len != sizeof(*rsp))
5093 return -EPROTO;
5094
5095 icid = le16_to_cpu(rsp->icid);
5096 result = le16_to_cpu(rsp->result);
5097
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005098 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005099
Mat Martineau5b155ef2012-10-23 15:24:14 -07005100 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5101 l2cap_move_continue(conn, icid, result);
5102 else
5103 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005104
5105 return 0;
5106}
5107
Mat Martineau5f3847a2012-10-23 15:24:12 -07005108static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5109 struct l2cap_cmd_hdr *cmd,
5110 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005111{
5112 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005113 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005114 u16 icid, result;
5115
5116 if (cmd_len != sizeof(*cfm))
5117 return -EPROTO;
5118
5119 icid = le16_to_cpu(cfm->icid);
5120 result = le16_to_cpu(cfm->result);
5121
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005122 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005123
Mat Martineau5f3847a2012-10-23 15:24:12 -07005124 chan = l2cap_get_chan_by_dcid(conn, icid);
5125 if (!chan) {
5126 /* Spec requires a response even if the icid was not found */
5127 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5128 return 0;
5129 }
5130
5131 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5132 if (result == L2CAP_MC_CONFIRMED) {
5133 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005134 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005135 __release_logical_link(chan);
5136 } else {
5137 chan->move_id = chan->local_amp_id;
5138 }
5139
5140 l2cap_move_done(chan);
5141 }
5142
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005143 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5144
Mat Martineau5f3847a2012-10-23 15:24:12 -07005145 l2cap_chan_unlock(chan);
5146
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005147 return 0;
5148}
5149
5150static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005151 struct l2cap_cmd_hdr *cmd,
5152 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005153{
5154 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005155 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005156 u16 icid;
5157
5158 if (cmd_len != sizeof(*rsp))
5159 return -EPROTO;
5160
5161 icid = le16_to_cpu(rsp->icid);
5162
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005163 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005164
Mat Martineau3fd71a02012-10-23 15:24:16 -07005165 chan = l2cap_get_chan_by_scid(conn, icid);
5166 if (!chan)
5167 return 0;
5168
5169 __clear_chan_timer(chan);
5170
5171 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5172 chan->local_amp_id = chan->move_id;
5173
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005174 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005175 __release_logical_link(chan);
5176
5177 l2cap_move_done(chan);
5178 }
5179
5180 l2cap_chan_unlock(chan);
5181
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005182 return 0;
5183}
5184
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005185static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005186 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005187{
5188 u16 max_latency;
5189
5190 if (min > max || min < 6 || max > 3200)
5191 return -EINVAL;
5192
5193 if (to_multiplier < 10 || to_multiplier > 3200)
5194 return -EINVAL;
5195
5196 if (max >= to_multiplier * 8)
5197 return -EINVAL;
5198
5199 max_latency = (to_multiplier * 8 / max) - 1;
5200 if (latency > 499 || latency > max_latency)
5201 return -EINVAL;
5202
5203 return 0;
5204}
5205
5206static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005207 struct l2cap_cmd_hdr *cmd,
5208 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005209{
5210 struct hci_conn *hcon = conn->hcon;
5211 struct l2cap_conn_param_update_req *req;
5212 struct l2cap_conn_param_update_rsp rsp;
5213 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005214 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005215
5216 if (!(hcon->link_mode & HCI_LM_MASTER))
5217 return -EINVAL;
5218
5219 cmd_len = __le16_to_cpu(cmd->len);
5220 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5221 return -EPROTO;
5222
5223 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005224 min = __le16_to_cpu(req->min);
5225 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005226 latency = __le16_to_cpu(req->latency);
5227 to_multiplier = __le16_to_cpu(req->to_multiplier);
5228
5229 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 +01005230 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005231
5232 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005233
5234 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5235 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005236 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005237 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005238 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005239
5240 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005241 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005242
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005243 if (!err)
5244 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5245
Claudio Takahaside731152011-02-11 19:28:55 -02005246 return 0;
5247}
5248
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005249static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005250 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5251 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005252{
5253 int err = 0;
5254
5255 switch (cmd->code) {
5256 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005257 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005258 break;
5259
5260 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005261 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005262 break;
5263
5264 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005265 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005266 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005267 break;
5268
5269 case L2CAP_CONF_REQ:
5270 err = l2cap_config_req(conn, cmd, cmd_len, data);
5271 break;
5272
5273 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005274 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005275 break;
5276
5277 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005278 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005279 break;
5280
5281 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005282 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005283 break;
5284
5285 case L2CAP_ECHO_REQ:
5286 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5287 break;
5288
5289 case L2CAP_ECHO_RSP:
5290 break;
5291
5292 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005293 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005294 break;
5295
5296 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005297 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005298 break;
5299
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005300 case L2CAP_CREATE_CHAN_REQ:
5301 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5302 break;
5303
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005304 case L2CAP_MOVE_CHAN_REQ:
5305 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5306 break;
5307
5308 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005309 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005310 break;
5311
5312 case L2CAP_MOVE_CHAN_CFM:
5313 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5314 break;
5315
5316 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005317 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005318 break;
5319
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005320 default:
5321 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5322 err = -EINVAL;
5323 break;
5324 }
5325
5326 return err;
5327}
5328
5329static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005330 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005331{
5332 switch (cmd->code) {
5333 case L2CAP_COMMAND_REJ:
5334 return 0;
5335
5336 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005337 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005338
5339 case L2CAP_CONN_PARAM_UPDATE_RSP:
5340 return 0;
5341
5342 default:
5343 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5344 return -EINVAL;
5345 }
5346}
5347
Johan Hedberg7c2005d2013-09-16 13:05:16 +03005348static __le16 l2cap_err_to_reason(int err)
5349{
5350 switch (err) {
5351 case -EBADSLT:
5352 return __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
5353 case -EMSGSIZE:
5354 return __constant_cpu_to_le16(L2CAP_REJ_MTU_EXCEEDED);
5355 case -EINVAL:
5356 case -EPROTO:
5357 default:
5358 return __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
5359 }
5360}
5361
Johan Hedbergc5623552013-04-29 19:35:33 +03005362static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5363 struct sk_buff *skb)
5364{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005365 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005366 struct l2cap_cmd_hdr *cmd;
5367 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005368 int err;
5369
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005370 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005371 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005372
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005373 if (skb->len < L2CAP_CMD_HDR_SIZE)
5374 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005375
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005376 cmd = (void *) skb->data;
5377 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005378
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005379 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005380
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005381 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005382
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005383 if (len != skb->len || !cmd->ident) {
5384 BT_DBG("corrupted command");
5385 goto drop;
5386 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005387
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005388 err = l2cap_le_sig_cmd(conn, cmd, skb->data);
5389 if (err) {
5390 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005391
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005392 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005393
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005394 rej.reason = l2cap_err_to_reason(err);
5395 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5396 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005397 }
5398
Marcel Holtmann3b166292013-10-02 08:28:21 -07005399drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005400 kfree_skb(skb);
5401}
5402
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005403static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005404 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005405{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005406 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005407 u8 *data = skb->data;
5408 int len = skb->len;
5409 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005410 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005411
5412 l2cap_raw_recv(conn, skb);
5413
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005414 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005415 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005416
Linus Torvalds1da177e2005-04-16 15:20:36 -07005417 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005418 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005419 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5420 data += L2CAP_CMD_HDR_SIZE;
5421 len -= L2CAP_CMD_HDR_SIZE;
5422
Al Viro88219a02007-07-29 00:17:25 -07005423 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005424
Gustavo Padovan2d792812012-10-06 10:07:01 +01005425 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5426 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005427
Al Viro88219a02007-07-29 00:17:25 -07005428 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005429 BT_DBG("corrupted command");
5430 break;
5431 }
5432
Johan Hedbergc5623552013-04-29 19:35:33 +03005433 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005434 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005435 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005436
5437 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005438
Johan Hedberg7c2005d2013-09-16 13:05:16 +03005439 rej.reason = l2cap_err_to_reason(err);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005440 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5441 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005442 }
5443
Al Viro88219a02007-07-29 00:17:25 -07005444 data += cmd_len;
5445 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005446 }
5447
Marcel Holtmann3b166292013-10-02 08:28:21 -07005448drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005449 kfree_skb(skb);
5450}
5451
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005452static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005453{
5454 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005455 int hdr_size;
5456
5457 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5458 hdr_size = L2CAP_EXT_HDR_SIZE;
5459 else
5460 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005461
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005462 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005463 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005464 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5465 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5466
5467 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005468 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005469 }
5470 return 0;
5471}
5472
Mat Martineau6ea00482012-05-17 20:53:52 -07005473static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005474{
Mat Martineaue31f7632012-05-17 20:53:41 -07005475 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005476
Mat Martineaue31f7632012-05-17 20:53:41 -07005477 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005478
Mat Martineaue31f7632012-05-17 20:53:41 -07005479 memset(&control, 0, sizeof(control));
5480 control.sframe = 1;
5481 control.final = 1;
5482 control.reqseq = chan->buffer_seq;
5483 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005484
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005485 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005486 control.super = L2CAP_SUPER_RNR;
5487 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005488 }
5489
Mat Martineaue31f7632012-05-17 20:53:41 -07005490 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5491 chan->unacked_frames > 0)
5492 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005493
Mat Martineaue31f7632012-05-17 20:53:41 -07005494 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005495 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005496
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005497 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005498 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5499 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5500 * send it now.
5501 */
5502 control.super = L2CAP_SUPER_RR;
5503 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005504 }
5505}
5506
Gustavo Padovan2d792812012-10-06 10:07:01 +01005507static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5508 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005509{
Mat Martineau84084a32011-07-22 14:54:00 -07005510 /* skb->len reflects data in skb as well as all fragments
5511 * skb->data_len reflects only data in fragments
5512 */
5513 if (!skb_has_frag_list(skb))
5514 skb_shinfo(skb)->frag_list = new_frag;
5515
5516 new_frag->next = NULL;
5517
5518 (*last_frag)->next = new_frag;
5519 *last_frag = new_frag;
5520
5521 skb->len += new_frag->len;
5522 skb->data_len += new_frag->len;
5523 skb->truesize += new_frag->truesize;
5524}
5525
Mat Martineau4b51dae92012-05-17 20:53:37 -07005526static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5527 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005528{
5529 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005530
Mat Martineau4b51dae92012-05-17 20:53:37 -07005531 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005532 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005533 if (chan->sdu)
5534 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005535
Gustavo Padovan80b98022012-05-27 22:27:51 -03005536 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005537 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005538
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005539 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005540 if (chan->sdu)
5541 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005542
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005543 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005544 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005545
Mat Martineau84084a32011-07-22 14:54:00 -07005546 if (chan->sdu_len > chan->imtu) {
5547 err = -EMSGSIZE;
5548 break;
5549 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005550
Mat Martineau84084a32011-07-22 14:54:00 -07005551 if (skb->len >= chan->sdu_len)
5552 break;
5553
5554 chan->sdu = skb;
5555 chan->sdu_last_frag = skb;
5556
5557 skb = NULL;
5558 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005559 break;
5560
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005561 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005562 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005563 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005564
Mat Martineau84084a32011-07-22 14:54:00 -07005565 append_skb_frag(chan->sdu, skb,
5566 &chan->sdu_last_frag);
5567 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005568
Mat Martineau84084a32011-07-22 14:54:00 -07005569 if (chan->sdu->len >= chan->sdu_len)
5570 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005571
Mat Martineau84084a32011-07-22 14:54:00 -07005572 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005573 break;
5574
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005575 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005576 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005577 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005578
Mat Martineau84084a32011-07-22 14:54:00 -07005579 append_skb_frag(chan->sdu, skb,
5580 &chan->sdu_last_frag);
5581 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005582
Mat Martineau84084a32011-07-22 14:54:00 -07005583 if (chan->sdu->len != chan->sdu_len)
5584 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005585
Gustavo Padovan80b98022012-05-27 22:27:51 -03005586 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005587
Mat Martineau84084a32011-07-22 14:54:00 -07005588 if (!err) {
5589 /* Reassembly complete */
5590 chan->sdu = NULL;
5591 chan->sdu_last_frag = NULL;
5592 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005593 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005594 break;
5595 }
5596
Mat Martineau84084a32011-07-22 14:54:00 -07005597 if (err) {
5598 kfree_skb(skb);
5599 kfree_skb(chan->sdu);
5600 chan->sdu = NULL;
5601 chan->sdu_last_frag = NULL;
5602 chan->sdu_len = 0;
5603 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005604
Mat Martineau84084a32011-07-22 14:54:00 -07005605 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005606}
5607
Mat Martineau32b32732012-10-23 15:24:11 -07005608static int l2cap_resegment(struct l2cap_chan *chan)
5609{
5610 /* Placeholder */
5611 return 0;
5612}
5613
Mat Martineaue3281402011-07-07 09:39:02 -07005614void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005615{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005616 u8 event;
5617
5618 if (chan->mode != L2CAP_MODE_ERTM)
5619 return;
5620
5621 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005622 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005623}
5624
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005625static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5626{
Mat Martineau63838722012-05-17 20:53:45 -07005627 int err = 0;
5628 /* Pass sequential frames to l2cap_reassemble_sdu()
5629 * until a gap is encountered.
5630 */
5631
5632 BT_DBG("chan %p", chan);
5633
5634 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5635 struct sk_buff *skb;
5636 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5637 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5638
5639 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5640
5641 if (!skb)
5642 break;
5643
5644 skb_unlink(skb, &chan->srej_q);
5645 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5646 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5647 if (err)
5648 break;
5649 }
5650
5651 if (skb_queue_empty(&chan->srej_q)) {
5652 chan->rx_state = L2CAP_RX_STATE_RECV;
5653 l2cap_send_ack(chan);
5654 }
5655
5656 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005657}
5658
5659static void l2cap_handle_srej(struct l2cap_chan *chan,
5660 struct l2cap_ctrl *control)
5661{
Mat Martineauf80842a2012-05-17 20:53:46 -07005662 struct sk_buff *skb;
5663
5664 BT_DBG("chan %p, control %p", chan, control);
5665
5666 if (control->reqseq == chan->next_tx_seq) {
5667 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005668 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005669 return;
5670 }
5671
5672 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5673
5674 if (skb == NULL) {
5675 BT_DBG("Seq %d not available for retransmission",
5676 control->reqseq);
5677 return;
5678 }
5679
5680 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5681 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005682 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005683 return;
5684 }
5685
5686 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5687
5688 if (control->poll) {
5689 l2cap_pass_to_tx(chan, control);
5690
5691 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5692 l2cap_retransmit(chan, control);
5693 l2cap_ertm_send(chan);
5694
5695 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5696 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5697 chan->srej_save_reqseq = control->reqseq;
5698 }
5699 } else {
5700 l2cap_pass_to_tx_fbit(chan, control);
5701
5702 if (control->final) {
5703 if (chan->srej_save_reqseq != control->reqseq ||
5704 !test_and_clear_bit(CONN_SREJ_ACT,
5705 &chan->conn_state))
5706 l2cap_retransmit(chan, control);
5707 } else {
5708 l2cap_retransmit(chan, control);
5709 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5710 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5711 chan->srej_save_reqseq = control->reqseq;
5712 }
5713 }
5714 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005715}
5716
5717static void l2cap_handle_rej(struct l2cap_chan *chan,
5718 struct l2cap_ctrl *control)
5719{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005720 struct sk_buff *skb;
5721
5722 BT_DBG("chan %p, control %p", chan, control);
5723
5724 if (control->reqseq == chan->next_tx_seq) {
5725 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005726 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005727 return;
5728 }
5729
5730 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5731
5732 if (chan->max_tx && skb &&
5733 bt_cb(skb)->control.retries >= chan->max_tx) {
5734 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005735 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005736 return;
5737 }
5738
5739 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5740
5741 l2cap_pass_to_tx(chan, control);
5742
5743 if (control->final) {
5744 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5745 l2cap_retransmit_all(chan, control);
5746 } else {
5747 l2cap_retransmit_all(chan, control);
5748 l2cap_ertm_send(chan);
5749 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5750 set_bit(CONN_REJ_ACT, &chan->conn_state);
5751 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005752}
5753
Mat Martineau4b51dae92012-05-17 20:53:37 -07005754static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5755{
5756 BT_DBG("chan %p, txseq %d", chan, txseq);
5757
5758 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5759 chan->expected_tx_seq);
5760
5761 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5762 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005763 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005764 /* See notes below regarding "double poll" and
5765 * invalid packets.
5766 */
5767 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5768 BT_DBG("Invalid/Ignore - after SREJ");
5769 return L2CAP_TXSEQ_INVALID_IGNORE;
5770 } else {
5771 BT_DBG("Invalid - in window after SREJ sent");
5772 return L2CAP_TXSEQ_INVALID;
5773 }
5774 }
5775
5776 if (chan->srej_list.head == txseq) {
5777 BT_DBG("Expected SREJ");
5778 return L2CAP_TXSEQ_EXPECTED_SREJ;
5779 }
5780
5781 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5782 BT_DBG("Duplicate SREJ - txseq already stored");
5783 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5784 }
5785
5786 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5787 BT_DBG("Unexpected SREJ - not requested");
5788 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5789 }
5790 }
5791
5792 if (chan->expected_tx_seq == txseq) {
5793 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5794 chan->tx_win) {
5795 BT_DBG("Invalid - txseq outside tx window");
5796 return L2CAP_TXSEQ_INVALID;
5797 } else {
5798 BT_DBG("Expected");
5799 return L2CAP_TXSEQ_EXPECTED;
5800 }
5801 }
5802
5803 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005804 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005805 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5806 return L2CAP_TXSEQ_DUPLICATE;
5807 }
5808
5809 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5810 /* A source of invalid packets is a "double poll" condition,
5811 * where delays cause us to send multiple poll packets. If
5812 * the remote stack receives and processes both polls,
5813 * sequence numbers can wrap around in such a way that a
5814 * resent frame has a sequence number that looks like new data
5815 * with a sequence gap. This would trigger an erroneous SREJ
5816 * request.
5817 *
5818 * Fortunately, this is impossible with a tx window that's
5819 * less than half of the maximum sequence number, which allows
5820 * invalid frames to be safely ignored.
5821 *
5822 * With tx window sizes greater than half of the tx window
5823 * maximum, the frame is invalid and cannot be ignored. This
5824 * causes a disconnect.
5825 */
5826
5827 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5828 BT_DBG("Invalid/Ignore - txseq outside tx window");
5829 return L2CAP_TXSEQ_INVALID_IGNORE;
5830 } else {
5831 BT_DBG("Invalid - txseq outside tx window");
5832 return L2CAP_TXSEQ_INVALID;
5833 }
5834 } else {
5835 BT_DBG("Unexpected - txseq indicates missing frames");
5836 return L2CAP_TXSEQ_UNEXPECTED;
5837 }
5838}
5839
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005840static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5841 struct l2cap_ctrl *control,
5842 struct sk_buff *skb, u8 event)
5843{
5844 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005845 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005846
5847 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5848 event);
5849
5850 switch (event) {
5851 case L2CAP_EV_RECV_IFRAME:
5852 switch (l2cap_classify_txseq(chan, control->txseq)) {
5853 case L2CAP_TXSEQ_EXPECTED:
5854 l2cap_pass_to_tx(chan, control);
5855
5856 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5857 BT_DBG("Busy, discarding expected seq %d",
5858 control->txseq);
5859 break;
5860 }
5861
5862 chan->expected_tx_seq = __next_seq(chan,
5863 control->txseq);
5864
5865 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005866 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005867
5868 err = l2cap_reassemble_sdu(chan, skb, control);
5869 if (err)
5870 break;
5871
5872 if (control->final) {
5873 if (!test_and_clear_bit(CONN_REJ_ACT,
5874 &chan->conn_state)) {
5875 control->final = 0;
5876 l2cap_retransmit_all(chan, control);
5877 l2cap_ertm_send(chan);
5878 }
5879 }
5880
5881 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5882 l2cap_send_ack(chan);
5883 break;
5884 case L2CAP_TXSEQ_UNEXPECTED:
5885 l2cap_pass_to_tx(chan, control);
5886
5887 /* Can't issue SREJ frames in the local busy state.
5888 * Drop this frame, it will be seen as missing
5889 * when local busy is exited.
5890 */
5891 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5892 BT_DBG("Busy, discarding unexpected seq %d",
5893 control->txseq);
5894 break;
5895 }
5896
5897 /* There was a gap in the sequence, so an SREJ
5898 * must be sent for each missing frame. The
5899 * current frame is stored for later use.
5900 */
5901 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005902 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005903 BT_DBG("Queued %p (queue len %d)", skb,
5904 skb_queue_len(&chan->srej_q));
5905
5906 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5907 l2cap_seq_list_clear(&chan->srej_list);
5908 l2cap_send_srej(chan, control->txseq);
5909
5910 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5911 break;
5912 case L2CAP_TXSEQ_DUPLICATE:
5913 l2cap_pass_to_tx(chan, control);
5914 break;
5915 case L2CAP_TXSEQ_INVALID_IGNORE:
5916 break;
5917 case L2CAP_TXSEQ_INVALID:
5918 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005919 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005920 break;
5921 }
5922 break;
5923 case L2CAP_EV_RECV_RR:
5924 l2cap_pass_to_tx(chan, control);
5925 if (control->final) {
5926 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5927
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005928 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5929 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005930 control->final = 0;
5931 l2cap_retransmit_all(chan, control);
5932 }
5933
5934 l2cap_ertm_send(chan);
5935 } else if (control->poll) {
5936 l2cap_send_i_or_rr_or_rnr(chan);
5937 } else {
5938 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5939 &chan->conn_state) &&
5940 chan->unacked_frames)
5941 __set_retrans_timer(chan);
5942
5943 l2cap_ertm_send(chan);
5944 }
5945 break;
5946 case L2CAP_EV_RECV_RNR:
5947 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5948 l2cap_pass_to_tx(chan, control);
5949 if (control && control->poll) {
5950 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5951 l2cap_send_rr_or_rnr(chan, 0);
5952 }
5953 __clear_retrans_timer(chan);
5954 l2cap_seq_list_clear(&chan->retrans_list);
5955 break;
5956 case L2CAP_EV_RECV_REJ:
5957 l2cap_handle_rej(chan, control);
5958 break;
5959 case L2CAP_EV_RECV_SREJ:
5960 l2cap_handle_srej(chan, control);
5961 break;
5962 default:
5963 break;
5964 }
5965
5966 if (skb && !skb_in_use) {
5967 BT_DBG("Freeing %p", skb);
5968 kfree_skb(skb);
5969 }
5970
5971 return err;
5972}
5973
5974static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5975 struct l2cap_ctrl *control,
5976 struct sk_buff *skb, u8 event)
5977{
5978 int err = 0;
5979 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005980 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005981
5982 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5983 event);
5984
5985 switch (event) {
5986 case L2CAP_EV_RECV_IFRAME:
5987 switch (l2cap_classify_txseq(chan, txseq)) {
5988 case L2CAP_TXSEQ_EXPECTED:
5989 /* Keep frame for reassembly later */
5990 l2cap_pass_to_tx(chan, control);
5991 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005992 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005993 BT_DBG("Queued %p (queue len %d)", skb,
5994 skb_queue_len(&chan->srej_q));
5995
5996 chan->expected_tx_seq = __next_seq(chan, txseq);
5997 break;
5998 case L2CAP_TXSEQ_EXPECTED_SREJ:
5999 l2cap_seq_list_pop(&chan->srej_list);
6000
6001 l2cap_pass_to_tx(chan, control);
6002 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006003 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006004 BT_DBG("Queued %p (queue len %d)", skb,
6005 skb_queue_len(&chan->srej_q));
6006
6007 err = l2cap_rx_queued_iframes(chan);
6008 if (err)
6009 break;
6010
6011 break;
6012 case L2CAP_TXSEQ_UNEXPECTED:
6013 /* Got a frame that can't be reassembled yet.
6014 * Save it for later, and send SREJs to cover
6015 * the missing frames.
6016 */
6017 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006018 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006019 BT_DBG("Queued %p (queue len %d)", skb,
6020 skb_queue_len(&chan->srej_q));
6021
6022 l2cap_pass_to_tx(chan, control);
6023 l2cap_send_srej(chan, control->txseq);
6024 break;
6025 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
6026 /* This frame was requested with an SREJ, but
6027 * some expected retransmitted frames are
6028 * missing. Request retransmission of missing
6029 * SREJ'd frames.
6030 */
6031 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006032 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006033 BT_DBG("Queued %p (queue len %d)", skb,
6034 skb_queue_len(&chan->srej_q));
6035
6036 l2cap_pass_to_tx(chan, control);
6037 l2cap_send_srej_list(chan, control->txseq);
6038 break;
6039 case L2CAP_TXSEQ_DUPLICATE_SREJ:
6040 /* We've already queued this frame. Drop this copy. */
6041 l2cap_pass_to_tx(chan, control);
6042 break;
6043 case L2CAP_TXSEQ_DUPLICATE:
6044 /* Expecting a later sequence number, so this frame
6045 * was already received. Ignore it completely.
6046 */
6047 break;
6048 case L2CAP_TXSEQ_INVALID_IGNORE:
6049 break;
6050 case L2CAP_TXSEQ_INVALID:
6051 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006052 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006053 break;
6054 }
6055 break;
6056 case L2CAP_EV_RECV_RR:
6057 l2cap_pass_to_tx(chan, control);
6058 if (control->final) {
6059 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6060
6061 if (!test_and_clear_bit(CONN_REJ_ACT,
6062 &chan->conn_state)) {
6063 control->final = 0;
6064 l2cap_retransmit_all(chan, control);
6065 }
6066
6067 l2cap_ertm_send(chan);
6068 } else if (control->poll) {
6069 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6070 &chan->conn_state) &&
6071 chan->unacked_frames) {
6072 __set_retrans_timer(chan);
6073 }
6074
6075 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6076 l2cap_send_srej_tail(chan);
6077 } else {
6078 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6079 &chan->conn_state) &&
6080 chan->unacked_frames)
6081 __set_retrans_timer(chan);
6082
6083 l2cap_send_ack(chan);
6084 }
6085 break;
6086 case L2CAP_EV_RECV_RNR:
6087 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6088 l2cap_pass_to_tx(chan, control);
6089 if (control->poll) {
6090 l2cap_send_srej_tail(chan);
6091 } else {
6092 struct l2cap_ctrl rr_control;
6093 memset(&rr_control, 0, sizeof(rr_control));
6094 rr_control.sframe = 1;
6095 rr_control.super = L2CAP_SUPER_RR;
6096 rr_control.reqseq = chan->buffer_seq;
6097 l2cap_send_sframe(chan, &rr_control);
6098 }
6099
6100 break;
6101 case L2CAP_EV_RECV_REJ:
6102 l2cap_handle_rej(chan, control);
6103 break;
6104 case L2CAP_EV_RECV_SREJ:
6105 l2cap_handle_srej(chan, control);
6106 break;
6107 }
6108
6109 if (skb && !skb_in_use) {
6110 BT_DBG("Freeing %p", skb);
6111 kfree_skb(skb);
6112 }
6113
6114 return err;
6115}
6116
Mat Martineau32b32732012-10-23 15:24:11 -07006117static int l2cap_finish_move(struct l2cap_chan *chan)
6118{
6119 BT_DBG("chan %p", chan);
6120
6121 chan->rx_state = L2CAP_RX_STATE_RECV;
6122
6123 if (chan->hs_hcon)
6124 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6125 else
6126 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6127
6128 return l2cap_resegment(chan);
6129}
6130
6131static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6132 struct l2cap_ctrl *control,
6133 struct sk_buff *skb, u8 event)
6134{
6135 int err;
6136
6137 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6138 event);
6139
6140 if (!control->poll)
6141 return -EPROTO;
6142
6143 l2cap_process_reqseq(chan, control->reqseq);
6144
6145 if (!skb_queue_empty(&chan->tx_q))
6146 chan->tx_send_head = skb_peek(&chan->tx_q);
6147 else
6148 chan->tx_send_head = NULL;
6149
6150 /* Rewind next_tx_seq to the point expected
6151 * by the receiver.
6152 */
6153 chan->next_tx_seq = control->reqseq;
6154 chan->unacked_frames = 0;
6155
6156 err = l2cap_finish_move(chan);
6157 if (err)
6158 return err;
6159
6160 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6161 l2cap_send_i_or_rr_or_rnr(chan);
6162
6163 if (event == L2CAP_EV_RECV_IFRAME)
6164 return -EPROTO;
6165
6166 return l2cap_rx_state_recv(chan, control, NULL, event);
6167}
6168
6169static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6170 struct l2cap_ctrl *control,
6171 struct sk_buff *skb, u8 event)
6172{
6173 int err;
6174
6175 if (!control->final)
6176 return -EPROTO;
6177
6178 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6179
6180 chan->rx_state = L2CAP_RX_STATE_RECV;
6181 l2cap_process_reqseq(chan, control->reqseq);
6182
6183 if (!skb_queue_empty(&chan->tx_q))
6184 chan->tx_send_head = skb_peek(&chan->tx_q);
6185 else
6186 chan->tx_send_head = NULL;
6187
6188 /* Rewind next_tx_seq to the point expected
6189 * by the receiver.
6190 */
6191 chan->next_tx_seq = control->reqseq;
6192 chan->unacked_frames = 0;
6193
6194 if (chan->hs_hcon)
6195 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6196 else
6197 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6198
6199 err = l2cap_resegment(chan);
6200
6201 if (!err)
6202 err = l2cap_rx_state_recv(chan, control, skb, event);
6203
6204 return err;
6205}
6206
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006207static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6208{
6209 /* Make sure reqseq is for a packet that has been sent but not acked */
6210 u16 unacked;
6211
6212 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6213 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6214}
6215
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006216static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6217 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006218{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006219 int err = 0;
6220
6221 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6222 control, skb, event, chan->rx_state);
6223
6224 if (__valid_reqseq(chan, control->reqseq)) {
6225 switch (chan->rx_state) {
6226 case L2CAP_RX_STATE_RECV:
6227 err = l2cap_rx_state_recv(chan, control, skb, event);
6228 break;
6229 case L2CAP_RX_STATE_SREJ_SENT:
6230 err = l2cap_rx_state_srej_sent(chan, control, skb,
6231 event);
6232 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006233 case L2CAP_RX_STATE_WAIT_P:
6234 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6235 break;
6236 case L2CAP_RX_STATE_WAIT_F:
6237 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6238 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006239 default:
6240 /* shut it down */
6241 break;
6242 }
6243 } else {
6244 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6245 control->reqseq, chan->next_tx_seq,
6246 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006247 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006248 }
6249
6250 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006251}
6252
6253static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6254 struct sk_buff *skb)
6255{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006256 int err = 0;
6257
6258 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6259 chan->rx_state);
6260
6261 if (l2cap_classify_txseq(chan, control->txseq) ==
6262 L2CAP_TXSEQ_EXPECTED) {
6263 l2cap_pass_to_tx(chan, control);
6264
6265 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6266 __next_seq(chan, chan->buffer_seq));
6267
6268 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6269
6270 l2cap_reassemble_sdu(chan, skb, control);
6271 } else {
6272 if (chan->sdu) {
6273 kfree_skb(chan->sdu);
6274 chan->sdu = NULL;
6275 }
6276 chan->sdu_last_frag = NULL;
6277 chan->sdu_len = 0;
6278
6279 if (skb) {
6280 BT_DBG("Freeing %p", skb);
6281 kfree_skb(skb);
6282 }
6283 }
6284
6285 chan->last_acked_seq = control->txseq;
6286 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6287
6288 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006289}
6290
6291static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6292{
6293 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6294 u16 len;
6295 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006296
Mat Martineaub76bbd62012-04-11 10:48:43 -07006297 __unpack_control(chan, skb);
6298
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006299 len = skb->len;
6300
6301 /*
6302 * We can just drop the corrupted I-frame here.
6303 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006304 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006305 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006306 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006307 goto drop;
6308
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006309 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006310 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006311
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006312 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006313 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006314
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006315 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006316 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006317 goto drop;
6318 }
6319
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006320 if (!control->sframe) {
6321 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006322
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006323 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6324 control->sar, control->reqseq, control->final,
6325 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006326
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006327 /* Validate F-bit - F=0 always valid, F=1 only
6328 * valid in TX WAIT_F
6329 */
6330 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006331 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006332
6333 if (chan->mode != L2CAP_MODE_STREAMING) {
6334 event = L2CAP_EV_RECV_IFRAME;
6335 err = l2cap_rx(chan, control, skb, event);
6336 } else {
6337 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006338 }
6339
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006340 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006341 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006342 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006343 const u8 rx_func_to_event[4] = {
6344 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6345 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6346 };
6347
6348 /* Only I-frames are expected in streaming mode */
6349 if (chan->mode == L2CAP_MODE_STREAMING)
6350 goto drop;
6351
6352 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6353 control->reqseq, control->final, control->poll,
6354 control->super);
6355
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006356 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006357 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006358 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006359 goto drop;
6360 }
6361
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006362 /* Validate F and P bits */
6363 if (control->final && (control->poll ||
6364 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6365 goto drop;
6366
6367 event = rx_func_to_event[control->super];
6368 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006369 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006370 }
6371
6372 return 0;
6373
6374drop:
6375 kfree_skb(skb);
6376 return 0;
6377}
6378
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006379static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6380 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006381{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006382 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006383
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006384 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006385 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006386 if (cid == L2CAP_CID_A2MP) {
6387 chan = a2mp_channel_create(conn, skb);
6388 if (!chan) {
6389 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006390 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006391 }
6392
6393 l2cap_chan_lock(chan);
6394 } else {
6395 BT_DBG("unknown cid 0x%4.4x", cid);
6396 /* Drop packet and return */
6397 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006398 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006399 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006400 }
6401
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006402 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006403
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006404 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006405 goto drop;
6406
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006407 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006408 case L2CAP_MODE_BASIC:
6409 /* If socket recv buffers overflows we drop data here
6410 * which is *bad* because L2CAP has to be reliable.
6411 * But we don't have any other choice. L2CAP doesn't
6412 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006413
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006414 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006415 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006416
Gustavo Padovan80b98022012-05-27 22:27:51 -03006417 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006418 goto done;
6419 break;
6420
6421 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006422 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006423 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006424 goto done;
6425
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006426 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006427 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006428 break;
6429 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006430
6431drop:
6432 kfree_skb(skb);
6433
6434done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006435 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006436}
6437
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006438static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6439 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006440{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006441 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006442 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006443
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006444 if (hcon->type != ACL_LINK)
6445 goto drop;
6446
Marcel Holtmann6f59b902013-10-13 05:24:01 -07006447 chan = l2cap_global_chan_by_psm(0, psm, &conn->hcon->src,
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07006448 &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006449 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006450 goto drop;
6451
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006452 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006453
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006454 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006455 goto drop;
6456
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006457 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006458 goto drop;
6459
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006460 /* Store remote BD_ADDR and PSM for msg_name */
6461 bacpy(&bt_cb(skb)->bdaddr, &conn->hcon->dst);
6462 bt_cb(skb)->psm = psm;
6463
Gustavo Padovan80b98022012-05-27 22:27:51 -03006464 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006465 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006466
6467drop:
6468 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006469}
6470
Marcel Holtmann72f78352013-04-23 00:59:00 -07006471static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006472 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006473{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006474 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006475 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006476
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006477 if (hcon->type != LE_LINK)
6478 goto drop;
6479
Johan Hedbergaf1c0132013-04-29 19:35:42 +03006480 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann6f59b902013-10-13 05:24:01 -07006481 &conn->hcon->src, &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006482 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006483 goto drop;
6484
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006485 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006486
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006487 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006488 goto drop;
6489
Gustavo Padovan80b98022012-05-27 22:27:51 -03006490 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006491 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006492
6493drop:
6494 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006495}
6496
Linus Torvalds1da177e2005-04-16 15:20:36 -07006497static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6498{
6499 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006500 u16 cid, len;
6501 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006502
6503 skb_pull(skb, L2CAP_HDR_SIZE);
6504 cid = __le16_to_cpu(lh->cid);
6505 len = __le16_to_cpu(lh->len);
6506
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006507 if (len != skb->len) {
6508 kfree_skb(skb);
6509 return;
6510 }
6511
Linus Torvalds1da177e2005-04-16 15:20:36 -07006512 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6513
6514 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006515 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006516 l2cap_sig_channel(conn, skb);
6517 break;
6518
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006519 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006520 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006521 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006522 l2cap_conless_channel(conn, psm, skb);
6523 break;
6524
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006525 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006526 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006527 break;
6528
Marcel Holtmanna2877622013-10-02 23:46:54 -07006529 case L2CAP_CID_LE_SIGNALING:
6530 l2cap_le_sig_channel(conn, skb);
6531 break;
6532
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006533 case L2CAP_CID_SMP:
6534 if (smp_sig_channel(conn, skb))
6535 l2cap_conn_del(conn->hcon, EACCES);
6536 break;
6537
Linus Torvalds1da177e2005-04-16 15:20:36 -07006538 default:
6539 l2cap_data_channel(conn, cid, skb);
6540 break;
6541 }
6542}
6543
6544/* ---- L2CAP interface with lower layer (HCI) ---- */
6545
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006546int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006547{
6548 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006549 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006550
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006551 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006552
6553 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006554 read_lock(&chan_list_lock);
6555 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006556 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006557 continue;
6558
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006559 if (!bacmp(&c->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006560 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006561 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006562 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006563 exact++;
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006564 } else if (!bacmp(&c->src, BDADDR_ANY)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006565 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006566 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006567 lm2 |= HCI_LM_MASTER;
6568 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006569 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006570 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006571
6572 return exact ? lm1 : lm2;
6573}
6574
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006575void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006576{
Marcel Holtmann01394182006-07-03 10:02:46 +02006577 struct l2cap_conn *conn;
6578
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006579 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006580
Linus Torvalds1da177e2005-04-16 15:20:36 -07006581 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006582 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006583 if (conn)
6584 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006585 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006586 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006587 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006588}
6589
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006590int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006591{
6592 struct l2cap_conn *conn = hcon->l2cap_data;
6593
6594 BT_DBG("hcon %p", hcon);
6595
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006596 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006597 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006598 return conn->disc_reason;
6599}
6600
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006601void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006602{
6603 BT_DBG("hcon %p reason %d", hcon, reason);
6604
Joe Perchese1750722011-06-29 18:18:29 -07006605 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006606}
6607
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006608static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006609{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006610 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006611 return;
6612
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006613 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006614 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006615 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006616 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006617 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006618 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006619 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006620 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006621 }
6622}
6623
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006624int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006625{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006626 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006627 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006628
Marcel Holtmann01394182006-07-03 10:02:46 +02006629 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006630 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006631
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006632 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006633
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006634 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306635 if (!status && encrypt)
6636 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006637 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006638 }
6639
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006640 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006641
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006642 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006643 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006644
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006645 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6646 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006647
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006648 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6649 l2cap_chan_unlock(chan);
6650 continue;
6651 }
6652
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006653 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006654 if (!status && encrypt) {
6655 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006656 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006657 }
6658
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006659 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006660 continue;
6661 }
6662
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006663 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006664 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006665 continue;
6666 }
6667
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006668 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006669 chan->state == BT_CONFIG)) {
Marcel Holtmannd97c8992013-10-14 02:53:54 -07006670 chan->ops->resume(chan);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006671 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006672 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006673 continue;
6674 }
6675
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006676 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006677 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006678 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006679 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006680 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006681 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006682 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006683 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006684 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006685 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006686
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006687 lock_sock(sk);
6688
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006689 if (!status) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07006690 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006691 res = L2CAP_CR_PEND;
6692 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006693 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006694 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006695 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006696 res = L2CAP_CR_SUCCESS;
6697 stat = L2CAP_CS_NO_INFO;
6698 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006699 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006700 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006701 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006702 res = L2CAP_CR_SEC_BLOCK;
6703 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006704 }
6705
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006706 release_sock(sk);
6707
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006708 rsp.scid = cpu_to_le16(chan->dcid);
6709 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006710 rsp.result = cpu_to_le16(res);
6711 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006712 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006713 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006714
6715 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6716 res == L2CAP_CR_SUCCESS) {
6717 char buf[128];
6718 set_bit(CONF_REQ_SENT, &chan->conf_state);
6719 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6720 L2CAP_CONF_REQ,
6721 l2cap_build_conf_req(chan, buf),
6722 buf);
6723 chan->num_conf_req++;
6724 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006725 }
6726
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006727 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006728 }
6729
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006730 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006731
Linus Torvalds1da177e2005-04-16 15:20:36 -07006732 return 0;
6733}
6734
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006735int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006736{
6737 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006738 struct l2cap_hdr *hdr;
6739 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006740
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006741 /* For AMP controller do not create l2cap conn */
6742 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6743 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006744
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006745 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006746 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006747
6748 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006749 goto drop;
6750
6751 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6752
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006753 switch (flags) {
6754 case ACL_START:
6755 case ACL_START_NO_FLUSH:
6756 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006757 if (conn->rx_len) {
6758 BT_ERR("Unexpected start frame (len %d)", skb->len);
6759 kfree_skb(conn->rx_skb);
6760 conn->rx_skb = NULL;
6761 conn->rx_len = 0;
6762 l2cap_conn_unreliable(conn, ECOMM);
6763 }
6764
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006765 /* Start fragment always begin with Basic L2CAP header */
6766 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006767 BT_ERR("Frame is too short (len %d)", skb->len);
6768 l2cap_conn_unreliable(conn, ECOMM);
6769 goto drop;
6770 }
6771
6772 hdr = (struct l2cap_hdr *) skb->data;
6773 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6774
6775 if (len == skb->len) {
6776 /* Complete frame received */
6777 l2cap_recv_frame(conn, skb);
6778 return 0;
6779 }
6780
6781 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6782
6783 if (skb->len > len) {
6784 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006785 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006786 l2cap_conn_unreliable(conn, ECOMM);
6787 goto drop;
6788 }
6789
6790 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006791 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006792 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006793 goto drop;
6794
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006795 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006796 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006797 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006798 break;
6799
6800 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006801 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6802
6803 if (!conn->rx_len) {
6804 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6805 l2cap_conn_unreliable(conn, ECOMM);
6806 goto drop;
6807 }
6808
6809 if (skb->len > conn->rx_len) {
6810 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006811 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006812 kfree_skb(conn->rx_skb);
6813 conn->rx_skb = NULL;
6814 conn->rx_len = 0;
6815 l2cap_conn_unreliable(conn, ECOMM);
6816 goto drop;
6817 }
6818
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006819 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006820 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006821 conn->rx_len -= skb->len;
6822
6823 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006824 /* Complete frame received. l2cap_recv_frame
6825 * takes ownership of the skb so set the global
6826 * rx_skb pointer to NULL first.
6827 */
6828 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006829 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006830 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006831 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006832 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006833 }
6834
6835drop:
6836 kfree_skb(skb);
6837 return 0;
6838}
6839
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006840static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006841{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006842 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006843
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006844 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006845
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006846 list_for_each_entry(c, &chan_list, global_l) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006847 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006848 &c->src, &c->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006849 c->state, __le16_to_cpu(c->psm),
6850 c->scid, c->dcid, c->imtu, c->omtu,
6851 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006852 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006853
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006854 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006855
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006856 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006857}
6858
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006859static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6860{
6861 return single_open(file, l2cap_debugfs_show, inode->i_private);
6862}
6863
6864static const struct file_operations l2cap_debugfs_fops = {
6865 .open = l2cap_debugfs_open,
6866 .read = seq_read,
6867 .llseek = seq_lseek,
6868 .release = single_release,
6869};
6870
6871static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006872
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006873int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006874{
6875 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006876
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006877 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006878 if (err < 0)
6879 return err;
6880
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006881 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006882 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6883 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006884 if (!l2cap_debugfs)
6885 BT_ERR("Failed to create L2CAP debug file");
6886 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006887
Linus Torvalds1da177e2005-04-16 15:20:36 -07006888 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006889}
6890
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006891void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006892{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006893 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006894 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006895}
6896
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006897module_param(disable_ertm, bool, 0644);
6898MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");