blob: 769c379b3eebd6397561def6355e484168f9187e [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. Padovan89bc500e2011-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. Padovan89bc500e2011-06-03 00:19:47 -0300231 chan->state = state;
Gustavo Padovan80b98022012-05-27 22:27:51 -0300232 chan->ops->state_change(chan, state);
Gustavo F. Padovan89bc500e2011-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{
246 struct sock *sk = chan->sk;
247
248 sk->sk_err = err;
249}
250
251static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
252{
253 struct sock *sk = chan->sk;
254
255 lock_sock(sk);
256 __l2cap_chan_set_err(chan, err);
257 release_sock(sk);
258}
259
Mat Martineau4239d162012-05-17 20:53:49 -0700260static void __set_retrans_timer(struct l2cap_chan *chan)
261{
262 if (!delayed_work_pending(&chan->monitor_timer) &&
263 chan->retrans_timeout) {
264 l2cap_set_timer(chan, &chan->retrans_timer,
265 msecs_to_jiffies(chan->retrans_timeout));
266 }
267}
268
269static void __set_monitor_timer(struct l2cap_chan *chan)
270{
271 __clear_retrans_timer(chan);
272 if (chan->monitor_timeout) {
273 l2cap_set_timer(chan, &chan->monitor_timer,
274 msecs_to_jiffies(chan->monitor_timeout));
275 }
276}
277
Mat Martineau608bcc62012-05-17 20:53:32 -0700278static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
279 u16 seq)
280{
281 struct sk_buff *skb;
282
283 skb_queue_walk(head, skb) {
284 if (bt_cb(skb)->control.txseq == seq)
285 return skb;
286 }
287
288 return NULL;
289}
290
Mat Martineau3c588192012-04-11 10:48:42 -0700291/* ---- L2CAP sequence number lists ---- */
292
293/* For ERTM, ordered lists of sequence numbers must be tracked for
294 * SREJ requests that are received and for frames that are to be
295 * retransmitted. These seq_list functions implement a singly-linked
296 * list in an array, where membership in the list can also be checked
297 * in constant time. Items can also be added to the tail of the list
298 * and removed from the head in constant time, without further memory
299 * allocs or frees.
300 */
301
302static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
303{
304 size_t alloc_size, i;
305
306 /* Allocated size is a power of 2 to map sequence numbers
307 * (which may be up to 14 bits) in to a smaller array that is
308 * sized for the negotiated ERTM transmit windows.
309 */
310 alloc_size = roundup_pow_of_two(size);
311
312 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
313 if (!seq_list->list)
314 return -ENOMEM;
315
316 seq_list->mask = alloc_size - 1;
317 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
318 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
319 for (i = 0; i < alloc_size; i++)
320 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
321
322 return 0;
323}
324
325static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
326{
327 kfree(seq_list->list);
328}
329
330static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
331 u16 seq)
332{
333 /* Constant-time check for list membership */
334 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
335}
336
337static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
338{
339 u16 mask = seq_list->mask;
340
341 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
342 /* In case someone tries to pop the head of an empty list */
343 return L2CAP_SEQ_LIST_CLEAR;
344 } else if (seq_list->head == seq) {
345 /* Head can be removed in constant time */
346 seq_list->head = seq_list->list[seq & mask];
347 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
348
349 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
350 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
351 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
352 }
353 } else {
354 /* Walk the list to find the sequence number */
355 u16 prev = seq_list->head;
356 while (seq_list->list[prev & mask] != seq) {
357 prev = seq_list->list[prev & mask];
358 if (prev == L2CAP_SEQ_LIST_TAIL)
359 return L2CAP_SEQ_LIST_CLEAR;
360 }
361
362 /* Unlink the number from the list and clear it */
363 seq_list->list[prev & mask] = seq_list->list[seq & mask];
364 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
365 if (seq_list->tail == seq)
366 seq_list->tail = prev;
367 }
368 return seq;
369}
370
371static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
372{
373 /* Remove the head in constant time */
374 return l2cap_seq_list_remove(seq_list, seq_list->head);
375}
376
377static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
378{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300379 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700380
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300381 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
382 return;
383
384 for (i = 0; i <= seq_list->mask; i++)
385 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
386
387 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
388 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700389}
390
391static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
392{
393 u16 mask = seq_list->mask;
394
395 /* All appends happen in constant time */
396
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300397 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
398 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700399
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300400 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
401 seq_list->head = seq;
402 else
403 seq_list->list[seq_list->tail & mask] = seq;
404
405 seq_list->tail = seq;
406 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700407}
408
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300409static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300410{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300411 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100412 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200413 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300414 int reason;
415
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200416 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300417
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200418 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200419 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300420
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300421 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300422 reason = ECONNREFUSED;
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300423 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100424 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300425 reason = ECONNREFUSED;
426 else
427 reason = ETIMEDOUT;
428
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300429 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300430
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200431 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300432
Gustavo Padovan80b98022012-05-27 22:27:51 -0300433 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200434 mutex_unlock(&conn->chan_lock);
435
Ulisses Furquim371fd832011-12-21 20:02:36 -0200436 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300437}
438
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300439struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200440{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300441 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200442
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300443 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
444 if (!chan)
445 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200446
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200447 mutex_init(&chan->lock);
448
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200449 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300450 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200451 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300452
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300453 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300454
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300455 chan->state = BT_OPEN;
456
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530457 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300458
Mat Martineau28270112012-05-17 21:14:09 -0700459 /* This flag is cleared in l2cap_chan_ready() */
460 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
461
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300462 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100463
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300464 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200465}
466
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530467static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300468{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530469 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
470
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530471 BT_DBG("chan %p", chan);
472
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200473 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300474 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200475 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300476
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530477 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300478}
479
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530480void l2cap_chan_hold(struct l2cap_chan *c)
481{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530482 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530483
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530484 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530485}
486
487void l2cap_chan_put(struct l2cap_chan *c)
488{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530489 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530490
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530491 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530492}
493
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300494void l2cap_chan_set_defaults(struct l2cap_chan *chan)
495{
496 chan->fcs = L2CAP_FCS_CRC16;
497 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
498 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
499 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700500 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300501 chan->sec_level = BT_SECURITY_LOW;
502
503 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
504}
505
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300506void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200507{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300508 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200509 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200510
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200511 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100512
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300513 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200514
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200515 switch (chan->chan_type) {
516 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300517 if (conn->hcon->type == LE_LINK) {
518 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300519 chan->omtu = L2CAP_DEFAULT_MTU;
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300520 if (chan->dcid == L2CAP_CID_ATT)
521 chan->scid = L2CAP_CID_ATT;
522 else
523 chan->scid = l2cap_alloc_cid(conn);
Ville Tervob62f3282011-02-10 22:38:50 -0300524 } else {
525 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300526 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300527 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300528 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200529 break;
530
531 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200532 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300533 chan->scid = L2CAP_CID_CONN_LESS;
534 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300535 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200536 break;
537
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300538 case L2CAP_CHAN_CONN_FIX_A2MP:
539 chan->scid = L2CAP_CID_A2MP;
540 chan->dcid = L2CAP_CID_A2MP;
541 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
542 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
543 break;
544
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200545 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200546 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300547 chan->scid = L2CAP_CID_SIGNALING;
548 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300549 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200550 }
551
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300552 chan->local_id = L2CAP_BESTEFFORT_ID;
553 chan->local_stype = L2CAP_SERV_BESTEFFORT;
554 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
555 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
556 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300557 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300558
Ulisses Furquim371fd832011-12-21 20:02:36 -0200559 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300560
Johan Hedberg5ee98912013-04-29 19:35:43 +0300561 hci_conn_hold(conn->hcon);
562
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200563 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200564}
565
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300566void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200567{
568 mutex_lock(&conn->chan_lock);
569 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200570 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200571}
572
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300573void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200574{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300575 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200576
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300577 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200578
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300579 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200580
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900581 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300582 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300583 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200584 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200585
Ulisses Furquim371fd832011-12-21 20:02:36 -0200586 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300587
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300588 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300589
590 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200591 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300592
593 if (mgr && mgr->bredr_chan == chan)
594 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200595 }
596
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200597 if (chan->hs_hchan) {
598 struct hci_chan *hs_hchan = chan->hs_hchan;
599
600 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
601 amp_disconnect_logical_link(hs_hchan);
602 }
603
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100604 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200605
Mat Martineau28270112012-05-17 21:14:09 -0700606 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300607 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300608
Gustavo Padovanee556f62012-05-18 20:22:38 -0300609 switch(chan->mode) {
610 case L2CAP_MODE_BASIC:
611 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300612
Gustavo Padovanee556f62012-05-18 20:22:38 -0300613 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300614 __clear_retrans_timer(chan);
615 __clear_monitor_timer(chan);
616 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300617
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300618 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300619
Mat Martineau3c588192012-04-11 10:48:42 -0700620 l2cap_seq_list_free(&chan->srej_list);
621 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300622
623 /* fall through */
624
625 case L2CAP_MODE_STREAMING:
626 skb_queue_purge(&chan->tx_q);
627 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300628 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300629
630 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200631}
632
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300633void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300634{
635 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300636
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700637 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300638
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300639 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300640 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100641 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300642 break;
643
644 case BT_CONNECTED:
645 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300646 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100647 conn->hcon->type == ACL_LINK) {
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700648 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300649 __set_chan_timer(chan, sk->sk_sndtimeo);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200650 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300651 } else
652 l2cap_chan_del(chan, reason);
653 break;
654
655 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300656 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100657 conn->hcon->type == ACL_LINK) {
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700658 struct sock *sk = chan->sk;
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300659 struct l2cap_conn_rsp rsp;
660 __u16 result;
661
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300662 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300663 result = L2CAP_CR_SEC_BLOCK;
664 else
665 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300666 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300667
668 rsp.scid = cpu_to_le16(chan->dcid);
669 rsp.dcid = cpu_to_le16(chan->scid);
670 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300671 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300672 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100673 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300674 }
675
676 l2cap_chan_del(chan, reason);
677 break;
678
679 case BT_CONNECT:
680 case BT_DISCONN:
681 l2cap_chan_del(chan, reason);
682 break;
683
684 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100685 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300686 break;
687 }
688}
689
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300690static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530691{
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700692 switch (chan->chan_type) {
693 case L2CAP_CHAN_RAW:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300694 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530695 case BT_SECURITY_HIGH:
696 return HCI_AT_DEDICATED_BONDING_MITM;
697 case BT_SECURITY_MEDIUM:
698 return HCI_AT_DEDICATED_BONDING;
699 default:
700 return HCI_AT_NO_BONDING;
701 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700702 break;
Marcel Holtmann3124b842013-10-12 07:19:32 -0700703 case L2CAP_CHAN_CONN_LESS:
704 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_3DSP)) {
705 if (chan->sec_level == BT_SECURITY_LOW)
706 chan->sec_level = BT_SECURITY_SDP;
707 }
708 if (chan->sec_level == BT_SECURITY_HIGH)
709 return HCI_AT_NO_BONDING_MITM;
710 else
711 return HCI_AT_NO_BONDING;
712 break;
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700713 case L2CAP_CHAN_CONN_ORIENTED:
714 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
715 if (chan->sec_level == BT_SECURITY_LOW)
716 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530717
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700718 if (chan->sec_level == BT_SECURITY_HIGH)
719 return HCI_AT_NO_BONDING_MITM;
720 else
721 return HCI_AT_NO_BONDING;
722 }
723 /* fall through */
724 default:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300725 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530726 case BT_SECURITY_HIGH:
727 return HCI_AT_GENERAL_BONDING_MITM;
728 case BT_SECURITY_MEDIUM:
729 return HCI_AT_GENERAL_BONDING;
730 default:
731 return HCI_AT_NO_BONDING;
732 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700733 break;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530734 }
735}
736
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200737/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200738int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200739{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300740 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100741 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200742
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300743 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100744
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300745 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200746}
747
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200748static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200749{
750 u8 id;
751
752 /* Get next available identificator.
753 * 1 - 128 are used by kernel.
754 * 129 - 199 are reserved.
755 * 200 - 254 are used by utilities like l2ping, etc.
756 */
757
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200758 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200759
760 if (++conn->tx_ident > 128)
761 conn->tx_ident = 1;
762
763 id = conn->tx_ident;
764
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200765 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200766
767 return id;
768}
769
Gustavo Padovan2d792812012-10-06 10:07:01 +0100770static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
771 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200772{
773 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200774 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200775
776 BT_DBG("code 0x%2.2x", code);
777
778 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300779 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200780
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200781 if (lmp_no_flush_capable(conn->hcon->hdev))
782 flags = ACL_START_NO_FLUSH;
783 else
784 flags = ACL_START;
785
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700786 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200787 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700788
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200789 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200790}
791
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700792static bool __chan_is_moving(struct l2cap_chan *chan)
793{
794 return chan->move_state != L2CAP_MOVE_STABLE &&
795 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
796}
797
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200798static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
799{
800 struct hci_conn *hcon = chan->conn->hcon;
801 u16 flags;
802
803 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100804 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200805
Mat Martineaud5f8a752012-10-23 15:24:18 -0700806 if (chan->hs_hcon && !__chan_is_moving(chan)) {
807 if (chan->hs_hchan)
808 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
809 else
810 kfree_skb(skb);
811
812 return;
813 }
814
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200815 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100816 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200817 flags = ACL_START_NO_FLUSH;
818 else
819 flags = ACL_START;
820
821 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
822 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823}
824
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700825static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
826{
827 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
828 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
829
830 if (enh & L2CAP_CTRL_FRAME_TYPE) {
831 /* S-Frame */
832 control->sframe = 1;
833 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
834 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
835
836 control->sar = 0;
837 control->txseq = 0;
838 } else {
839 /* I-Frame */
840 control->sframe = 0;
841 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
842 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
843
844 control->poll = 0;
845 control->super = 0;
846 }
847}
848
849static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
850{
851 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
852 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
853
854 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
855 /* S-Frame */
856 control->sframe = 1;
857 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
858 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
859
860 control->sar = 0;
861 control->txseq = 0;
862 } else {
863 /* I-Frame */
864 control->sframe = 0;
865 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
866 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
867
868 control->poll = 0;
869 control->super = 0;
870 }
871}
872
873static inline void __unpack_control(struct l2cap_chan *chan,
874 struct sk_buff *skb)
875{
876 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
877 __unpack_extended_control(get_unaligned_le32(skb->data),
878 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700879 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700880 } else {
881 __unpack_enhanced_control(get_unaligned_le16(skb->data),
882 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700883 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700884 }
885}
886
887static u32 __pack_extended_control(struct l2cap_ctrl *control)
888{
889 u32 packed;
890
891 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
892 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
893
894 if (control->sframe) {
895 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
896 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
897 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
898 } else {
899 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
900 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
901 }
902
903 return packed;
904}
905
906static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
907{
908 u16 packed;
909
910 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
911 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
912
913 if (control->sframe) {
914 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
915 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
916 packed |= L2CAP_CTRL_FRAME_TYPE;
917 } else {
918 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
919 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
920 }
921
922 return packed;
923}
924
925static inline void __pack_control(struct l2cap_chan *chan,
926 struct l2cap_ctrl *control,
927 struct sk_buff *skb)
928{
929 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
930 put_unaligned_le32(__pack_extended_control(control),
931 skb->data + L2CAP_HDR_SIZE);
932 } else {
933 put_unaligned_le16(__pack_enhanced_control(control),
934 skb->data + L2CAP_HDR_SIZE);
935 }
936}
937
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300938static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
939{
940 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
941 return L2CAP_EXT_HDR_SIZE;
942 else
943 return L2CAP_ENH_HDR_SIZE;
944}
945
Mat Martineaua67d7f62012-05-17 20:53:35 -0700946static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
947 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300948{
949 struct sk_buff *skb;
950 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300951 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300952
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300953 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300954 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300955
Mat Martineaua67d7f62012-05-17 20:53:35 -0700956 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300957
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300958 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700959 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300960
961 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300962 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300963 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300964
Mat Martineaua67d7f62012-05-17 20:53:35 -0700965 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
966 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
967 else
968 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300969
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300970 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700971 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300972 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300973 }
974
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200975 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700976 return skb;
977}
978
979static void l2cap_send_sframe(struct l2cap_chan *chan,
980 struct l2cap_ctrl *control)
981{
982 struct sk_buff *skb;
983 u32 control_field;
984
985 BT_DBG("chan %p, control %p", chan, control);
986
987 if (!control->sframe)
988 return;
989
Mat Martineaub99e13a2012-10-23 15:24:19 -0700990 if (__chan_is_moving(chan))
991 return;
992
Mat Martineaua67d7f62012-05-17 20:53:35 -0700993 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
994 !control->poll)
995 control->final = 1;
996
997 if (control->super == L2CAP_SUPER_RR)
998 clear_bit(CONN_RNR_SENT, &chan->conn_state);
999 else if (control->super == L2CAP_SUPER_RNR)
1000 set_bit(CONN_RNR_SENT, &chan->conn_state);
1001
1002 if (control->super != L2CAP_SUPER_SREJ) {
1003 chan->last_acked_seq = control->reqseq;
1004 __clear_ack_timer(chan);
1005 }
1006
1007 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
1008 control->final, control->poll, control->super);
1009
1010 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1011 control_field = __pack_extended_control(control);
1012 else
1013 control_field = __pack_enhanced_control(control);
1014
1015 skb = l2cap_create_sframe_pdu(chan, control_field);
1016 if (!IS_ERR(skb))
1017 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001018}
1019
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001020static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001021{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001022 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001023
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001024 BT_DBG("chan %p, poll %d", chan, poll);
1025
1026 memset(&control, 0, sizeof(control));
1027 control.sframe = 1;
1028 control.poll = poll;
1029
1030 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1031 control.super = L2CAP_SUPER_RNR;
1032 else
1033 control.super = L2CAP_SUPER_RR;
1034
1035 control.reqseq = chan->buffer_seq;
1036 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001037}
1038
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001039static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001040{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001041 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001042}
1043
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001044static bool __amp_capable(struct l2cap_chan *chan)
1045{
1046 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001047 struct hci_dev *hdev;
1048 bool amp_available = false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001049
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001050 if (!conn->hs_enabled)
1051 return false;
1052
1053 if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
1054 return false;
1055
1056 read_lock(&hci_dev_list_lock);
1057 list_for_each_entry(hdev, &hci_dev_list, list) {
1058 if (hdev->amp_type != AMP_TYPE_BREDR &&
1059 test_bit(HCI_UP, &hdev->flags)) {
1060 amp_available = true;
1061 break;
1062 }
1063 }
1064 read_unlock(&hci_dev_list_lock);
1065
1066 if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED)
1067 return amp_available;
Marcel Holtmann848566b2013-10-01 22:59:22 -07001068
1069 return false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001070}
1071
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001072static bool l2cap_check_efs(struct l2cap_chan *chan)
1073{
1074 /* Check EFS parameters */
1075 return true;
1076}
1077
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001078void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001079{
1080 struct l2cap_conn *conn = chan->conn;
1081 struct l2cap_conn_req req;
1082
1083 req.scid = cpu_to_le16(chan->scid);
1084 req.psm = chan->psm;
1085
1086 chan->ident = l2cap_get_ident(conn);
1087
1088 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1089
1090 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1091}
1092
Mat Martineau8eb200b2012-10-23 15:24:17 -07001093static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1094{
1095 struct l2cap_create_chan_req req;
1096 req.scid = cpu_to_le16(chan->scid);
1097 req.psm = chan->psm;
1098 req.amp_id = amp_id;
1099
1100 chan->ident = l2cap_get_ident(chan->conn);
1101
1102 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1103 sizeof(req), &req);
1104}
1105
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001106static void l2cap_move_setup(struct l2cap_chan *chan)
1107{
1108 struct sk_buff *skb;
1109
1110 BT_DBG("chan %p", chan);
1111
1112 if (chan->mode != L2CAP_MODE_ERTM)
1113 return;
1114
1115 __clear_retrans_timer(chan);
1116 __clear_monitor_timer(chan);
1117 __clear_ack_timer(chan);
1118
1119 chan->retry_count = 0;
1120 skb_queue_walk(&chan->tx_q, skb) {
1121 if (bt_cb(skb)->control.retries)
1122 bt_cb(skb)->control.retries = 1;
1123 else
1124 break;
1125 }
1126
1127 chan->expected_tx_seq = chan->buffer_seq;
1128
1129 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1130 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1131 l2cap_seq_list_clear(&chan->retrans_list);
1132 l2cap_seq_list_clear(&chan->srej_list);
1133 skb_queue_purge(&chan->srej_q);
1134
1135 chan->tx_state = L2CAP_TX_STATE_XMIT;
1136 chan->rx_state = L2CAP_RX_STATE_MOVE;
1137
1138 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1139}
1140
Mat Martineau5f3847a2012-10-23 15:24:12 -07001141static void l2cap_move_done(struct l2cap_chan *chan)
1142{
1143 u8 move_role = chan->move_role;
1144 BT_DBG("chan %p", chan);
1145
1146 chan->move_state = L2CAP_MOVE_STABLE;
1147 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1148
1149 if (chan->mode != L2CAP_MODE_ERTM)
1150 return;
1151
1152 switch (move_role) {
1153 case L2CAP_MOVE_ROLE_INITIATOR:
1154 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1155 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1156 break;
1157 case L2CAP_MOVE_ROLE_RESPONDER:
1158 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1159 break;
1160 }
1161}
1162
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001163static void l2cap_chan_ready(struct l2cap_chan *chan)
1164{
Mat Martineau28270112012-05-17 21:14:09 -07001165 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001166 chan->conf_state = 0;
1167 __clear_chan_timer(chan);
1168
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001169 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001170
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001171 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001172}
1173
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001174static void l2cap_start_connection(struct l2cap_chan *chan)
1175{
1176 if (__amp_capable(chan)) {
1177 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1178 a2mp_discover_amp(chan);
1179 } else {
1180 l2cap_send_conn_req(chan);
1181 }
1182}
1183
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001184static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001185{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001186 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001187
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001188 if (conn->hcon->type == LE_LINK) {
1189 l2cap_chan_ready(chan);
1190 return;
1191 }
1192
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001193 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001194 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1195 return;
1196
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001197 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001198 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001199 l2cap_start_connection(chan);
1200 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001201 } else {
1202 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001203 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001204
1205 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1206 conn->info_ident = l2cap_get_ident(conn);
1207
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001208 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001209
Gustavo Padovan2d792812012-10-06 10:07:01 +01001210 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1211 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001212 }
1213}
1214
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001215static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1216{
1217 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001218 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001219 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1220
1221 switch (mode) {
1222 case L2CAP_MODE_ERTM:
1223 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1224 case L2CAP_MODE_STREAMING:
1225 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1226 default:
1227 return 0x00;
1228 }
1229}
1230
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001231static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001232{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001233 struct sock *sk = chan->sk;
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001234 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001235 struct l2cap_disconn_req req;
1236
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001237 if (!conn)
1238 return;
1239
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001240 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001241 __clear_retrans_timer(chan);
1242 __clear_monitor_timer(chan);
1243 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001244 }
1245
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001246 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001247 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001248 return;
1249 }
1250
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001251 req.dcid = cpu_to_le16(chan->dcid);
1252 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001253 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1254 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001255
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001256 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001257 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001258 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001259 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001260}
1261
Linus Torvalds1da177e2005-04-16 15:20:36 -07001262/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001263static void l2cap_conn_start(struct l2cap_conn *conn)
1264{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001265 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001266
1267 BT_DBG("conn %p", conn);
1268
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001269 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001270
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001271 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001272 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001273
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001274 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001275 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001276 continue;
1277 }
1278
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001279 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001280 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001281 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001282 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001283 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001284 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001285
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001286 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001287 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001288 &chan->conf_state)) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001289 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001290 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001291 continue;
1292 }
1293
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001294 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001295
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001296 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001297 struct sock *sk = chan->sk;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001298 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001299 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001300 rsp.scid = cpu_to_le16(chan->dcid);
1301 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001302
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001303 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001304 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001305 if (test_bit(BT_SK_DEFER_SETUP,
1306 &bt_sk(sk)->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001307 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1308 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001309 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001310
1311 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001312 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001313 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1314 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001315 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001316 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001317 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001318 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1319 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001320 }
1321
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001322 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001323 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001324
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001325 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001326 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001327 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001328 continue;
1329 }
1330
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001331 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001332 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001333 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001334 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001335 }
1336
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001337 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001338 }
1339
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001340 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001341}
1342
Ido Yarivc2287682012-04-20 15:46:07 -03001343/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001344 * Returns closest match, locked.
1345 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001346static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001347 bdaddr_t *src,
1348 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001349{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001350 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001351
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001352 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001353
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001354 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001355 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001356 continue;
1357
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001358 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001359 int src_match, dst_match;
1360 int src_any, dst_any;
1361
Ville Tervob62f3282011-02-10 22:38:50 -03001362 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001363 src_match = !bacmp(&c->src, src);
1364 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001365 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001366 read_unlock(&chan_list_lock);
1367 return c;
1368 }
Ville Tervob62f3282011-02-10 22:38:50 -03001369
1370 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001371 src_any = !bacmp(&c->src, BDADDR_ANY);
1372 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001373 if ((src_match && dst_any) || (src_any && dst_match) ||
1374 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001375 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001376 }
1377 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001378
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001379 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001380
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001381 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001382}
1383
1384static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1385{
Johan Hedberg60bac1842013-04-29 19:35:41 +03001386 struct sock *parent;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001387 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001388
1389 BT_DBG("");
1390
1391 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001392 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Marcel Holtmann6f59b902013-10-13 05:24:01 -07001393 &conn->hcon->src, &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001394 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001395 return;
1396
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001397 /* Client ATT sockets should override the server one */
1398 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1399 return;
1400
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001401 parent = pchan->sk;
1402
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001403 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001404
Gustavo Padovan80b98022012-05-27 22:27:51 -03001405 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001406 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001407 goto clean;
1408
Johan Hedberg9f22398c2013-04-29 19:35:38 +03001409 chan->dcid = L2CAP_CID_ATT;
1410
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001411 bacpy(&chan->src, &conn->hcon->src);
1412 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001413 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
1414 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Ville Tervob62f3282011-02-10 22:38:50 -03001415
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001416 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001417
Ville Tervob62f3282011-02-10 22:38:50 -03001418clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001419 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001420}
1421
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001422static void l2cap_conn_ready(struct l2cap_conn *conn)
1423{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001424 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001425 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001426
1427 BT_DBG("conn %p", conn);
1428
Johan Hedbergd8729922013-04-29 19:35:39 +03001429 /* For outgoing pairing which doesn't necessarily have an
1430 * associated socket (e.g. mgmt_pair_device).
1431 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001432 if (hcon->out && hcon->type == LE_LINK)
1433 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001434
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001435 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001436
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001437 if (hcon->type == LE_LINK)
1438 l2cap_le_conn_ready(conn);
1439
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001440 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001441
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001442 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001443
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001444 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1445 l2cap_chan_unlock(chan);
1446 continue;
1447 }
1448
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001449 if (hcon->type == LE_LINK) {
1450 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001451 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001452
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001453 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001454 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001455 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001456 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001457 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001458 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001459 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001460
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001461 } else if (chan->state == BT_CONNECT) {
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001462 l2cap_do_start(chan);
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001463 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001464
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001465 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001466 }
1467
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001468 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001469}
1470
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001471/* Notify sockets that we cannot guaranty reliability anymore */
1472static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1473{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001474 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001475
1476 BT_DBG("conn %p", conn);
1477
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001478 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001479
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001480 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001481 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001482 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001483 }
1484
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001485 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001486}
1487
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001488static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001489{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001490 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001491 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001492
Marcel Holtmann984947d2009-02-06 23:35:19 +01001493 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001494 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001495
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001496 l2cap_conn_start(conn);
1497}
1498
David Herrmann2c8e1412013-04-06 20:28:45 +02001499/*
1500 * l2cap_user
1501 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1502 * callback is called during registration. The ->remove callback is called
1503 * during unregistration.
1504 * An l2cap_user object can either be explicitly unregistered or when the
1505 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1506 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1507 * External modules must own a reference to the l2cap_conn object if they intend
1508 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1509 * any time if they don't.
1510 */
1511
1512int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1513{
1514 struct hci_dev *hdev = conn->hcon->hdev;
1515 int ret;
1516
1517 /* We need to check whether l2cap_conn is registered. If it is not, we
1518 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1519 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1520 * relies on the parent hci_conn object to be locked. This itself relies
1521 * on the hci_dev object to be locked. So we must lock the hci device
1522 * here, too. */
1523
1524 hci_dev_lock(hdev);
1525
1526 if (user->list.next || user->list.prev) {
1527 ret = -EINVAL;
1528 goto out_unlock;
1529 }
1530
1531 /* conn->hchan is NULL after l2cap_conn_del() was called */
1532 if (!conn->hchan) {
1533 ret = -ENODEV;
1534 goto out_unlock;
1535 }
1536
1537 ret = user->probe(conn, user);
1538 if (ret)
1539 goto out_unlock;
1540
1541 list_add(&user->list, &conn->users);
1542 ret = 0;
1543
1544out_unlock:
1545 hci_dev_unlock(hdev);
1546 return ret;
1547}
1548EXPORT_SYMBOL(l2cap_register_user);
1549
1550void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1551{
1552 struct hci_dev *hdev = conn->hcon->hdev;
1553
1554 hci_dev_lock(hdev);
1555
1556 if (!user->list.next || !user->list.prev)
1557 goto out_unlock;
1558
1559 list_del(&user->list);
1560 user->list.next = NULL;
1561 user->list.prev = NULL;
1562 user->remove(conn, user);
1563
1564out_unlock:
1565 hci_dev_unlock(hdev);
1566}
1567EXPORT_SYMBOL(l2cap_unregister_user);
1568
1569static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1570{
1571 struct l2cap_user *user;
1572
1573 while (!list_empty(&conn->users)) {
1574 user = list_first_entry(&conn->users, struct l2cap_user, list);
1575 list_del(&user->list);
1576 user->list.next = NULL;
1577 user->list.prev = NULL;
1578 user->remove(conn, user);
1579 }
1580}
1581
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001582static void l2cap_conn_del(struct hci_conn *hcon, int err)
1583{
1584 struct l2cap_conn *conn = hcon->l2cap_data;
1585 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001586
1587 if (!conn)
1588 return;
1589
1590 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1591
1592 kfree_skb(conn->rx_skb);
1593
David Herrmann2c8e1412013-04-06 20:28:45 +02001594 l2cap_unregister_all_users(conn);
1595
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001596 mutex_lock(&conn->chan_lock);
1597
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001598 /* Kill channels */
1599 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001600 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001601 l2cap_chan_lock(chan);
1602
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001603 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001604
1605 l2cap_chan_unlock(chan);
1606
Gustavo Padovan80b98022012-05-27 22:27:51 -03001607 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001608 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001609 }
1610
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001611 mutex_unlock(&conn->chan_lock);
1612
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001613 hci_chan_del(conn->hchan);
1614
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001615 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001616 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001617
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001618 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001619 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001620 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001621 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001622
1623 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001624 conn->hchan = NULL;
1625 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001626}
1627
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001628static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001629{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001630 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001631 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001632
Johan Hedbergd06cc412012-06-06 18:44:11 +08001633 BT_DBG("conn %p", conn);
1634
1635 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1636 smp_chan_destroy(conn);
1637 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1638 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001639}
1640
Claudio Takahasibaf43252013-04-11 13:55:50 -03001641static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642{
Marcel Holtmann01394182006-07-03 10:02:46 +02001643 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001644 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645
Claudio Takahasibaf43252013-04-11 13:55:50 -03001646 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647 return conn;
1648
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001649 hchan = hci_chan_create(hcon);
1650 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001653 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001654 if (!conn) {
1655 hci_chan_del(hchan);
1656 return NULL;
1657 }
1658
David Herrmann9c903e32013-04-06 20:28:44 +02001659 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660 hcon->l2cap_data = conn;
1661 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001662 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001663 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001665 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001666
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001667 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001668 case LE_LINK:
1669 if (hcon->hdev->le_mtu) {
1670 conn->mtu = hcon->hdev->le_mtu;
1671 break;
1672 }
1673 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001674 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001675 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001676 break;
1677 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001678
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001679 conn->feat_mask = 0;
1680
Marcel Holtmann848566b2013-10-01 22:59:22 -07001681 if (hcon->type == ACL_LINK)
1682 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
1683 &hcon->hdev->dev_flags);
1684
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001686 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001687
1688 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001689 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001691 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001692 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001693 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001694 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001695
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001696 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001697
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 return conn;
1699}
1700
David Herrmann9c903e32013-04-06 20:28:44 +02001701static void l2cap_conn_free(struct kref *ref)
1702{
1703 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1704
1705 hci_conn_put(conn->hcon);
1706 kfree(conn);
1707}
1708
1709void l2cap_conn_get(struct l2cap_conn *conn)
1710{
1711 kref_get(&conn->ref);
1712}
1713EXPORT_SYMBOL(l2cap_conn_get);
1714
1715void l2cap_conn_put(struct l2cap_conn *conn)
1716{
1717 kref_put(&conn->ref, l2cap_conn_free);
1718}
1719EXPORT_SYMBOL(l2cap_conn_put);
1720
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722
Ido Yarivc2287682012-04-20 15:46:07 -03001723/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724 * Returns closest match.
1725 */
Ido Yarivc2287682012-04-20 15:46:07 -03001726static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1727 bdaddr_t *src,
1728 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001730 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001732 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001733
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001734 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001735 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736 continue;
1737
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001738 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001739 int src_match, dst_match;
1740 int src_any, dst_any;
1741
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001743 src_match = !bacmp(&c->src, src);
1744 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001745 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001746 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001747 return c;
1748 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749
1750 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001751 src_any = !bacmp(&c->src, BDADDR_ANY);
1752 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001753 if ((src_match && dst_any) || (src_any && dst_match) ||
1754 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001755 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 }
1757 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001759 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001760
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001761 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762}
1763
Andre Guedes8e9f9892012-04-24 21:02:55 -03001764int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1765 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001767 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768 struct l2cap_conn *conn;
1769 struct hci_conn *hcon;
1770 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001771 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001772 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001774 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301775 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001777 hdev = hci_get_route(dst, &chan->src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001778 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 return -EHOSTUNREACH;
1780
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001781 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001783 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001784
1785 /* PSM must be odd and lsb of upper byte must be 0 */
1786 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001787 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001788 err = -EINVAL;
1789 goto done;
1790 }
1791
1792 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1793 err = -EINVAL;
1794 goto done;
1795 }
1796
1797 switch (chan->mode) {
1798 case L2CAP_MODE_BASIC:
1799 break;
1800 case L2CAP_MODE_ERTM:
1801 case L2CAP_MODE_STREAMING:
1802 if (!disable_ertm)
1803 break;
1804 /* fall through */
1805 default:
1806 err = -ENOTSUPP;
1807 goto done;
1808 }
1809
Gustavo Padovan0797e012012-05-27 22:27:54 -03001810 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001811 case BT_CONNECT:
1812 case BT_CONNECT2:
1813 case BT_CONFIG:
1814 /* Already connecting */
1815 err = 0;
1816 goto done;
1817
1818 case BT_CONNECTED:
1819 /* Already connected */
1820 err = -EISCONN;
1821 goto done;
1822
1823 case BT_OPEN:
1824 case BT_BOUND:
1825 /* Can connect */
1826 break;
1827
1828 default:
1829 err = -EBADFD;
1830 goto done;
1831 }
1832
1833 /* Set destination address and psm */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001834 bacpy(&chan->dst, dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001835 chan->dst_type = dst_type;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001836
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001837 chan->psm = psm;
1838 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001840 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001841
Johan Hedbergf224ca52013-04-29 19:35:36 +03001842 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001843 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001844 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001845 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001846 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001847 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001848
Ville Tervo30e76272011-02-22 16:10:53 -03001849 if (IS_ERR(hcon)) {
1850 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001852 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853
Claudio Takahasibaf43252013-04-11 13:55:50 -03001854 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001856 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001857 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858 goto done;
1859 }
1860
Johan Hedberg141d5702013-04-29 19:35:37 +03001861 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1862 hci_conn_drop(hcon);
1863 err = -EBUSY;
1864 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001865 }
1866
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 /* Update source addr of the socket */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001868 bacpy(&chan->src, &hcon->src);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001869 chan->src_type = bdaddr_type(hcon, hcon->src_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001871 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001872 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001873 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001874
Johan Hedberg5ee98912013-04-29 19:35:43 +03001875 /* l2cap_chan_add takes its own ref so we can drop this one */
1876 hci_conn_drop(hcon);
1877
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001878 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001879 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880
1881 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001882 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001883 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001884 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001885 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001886 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001887 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888 }
1889
Ville Tervo30e76272011-02-22 16:10:53 -03001890 err = 0;
1891
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001893 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001894 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895 hci_dev_put(hdev);
1896 return err;
1897}
1898
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001899int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001900{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001901 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001902 DECLARE_WAITQUEUE(wait, current);
1903 int err = 0;
1904 int timeo = HZ/5;
1905
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001906 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001907 set_current_state(TASK_INTERRUPTIBLE);
1908 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001909 if (!timeo)
1910 timeo = HZ/5;
1911
1912 if (signal_pending(current)) {
1913 err = sock_intr_errno(timeo);
1914 break;
1915 }
1916
1917 release_sock(sk);
1918 timeo = schedule_timeout(timeo);
1919 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001920 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001921
1922 err = sock_error(sk);
1923 if (err)
1924 break;
1925 }
1926 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001927 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001928 return err;
1929}
1930
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001931static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001932{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001933 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001934 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001935
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001936 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001937
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001938 l2cap_chan_lock(chan);
1939
Mat Martineau80909e02012-05-17 20:53:50 -07001940 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001941 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001942 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001943 return;
1944 }
1945
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001946 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001947
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001948 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001949 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001950}
1951
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001952static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001953{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001954 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001955 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001956
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001957 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001958
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001959 l2cap_chan_lock(chan);
1960
Mat Martineau80909e02012-05-17 20:53:50 -07001961 if (!chan->conn) {
1962 l2cap_chan_unlock(chan);
1963 l2cap_chan_put(chan);
1964 return;
1965 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001966
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001967 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001968 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001969 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001970}
1971
Gustavo Padovand6603662012-05-21 13:58:22 -03001972static void l2cap_streaming_send(struct l2cap_chan *chan,
1973 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001974{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001975 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001976 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001977
Mat Martineau37339372012-05-17 20:53:33 -07001978 BT_DBG("chan %p, skbs %p", chan, skbs);
1979
Mat Martineaub99e13a2012-10-23 15:24:19 -07001980 if (__chan_is_moving(chan))
1981 return;
1982
Mat Martineau37339372012-05-17 20:53:33 -07001983 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1984
1985 while (!skb_queue_empty(&chan->tx_q)) {
1986
1987 skb = skb_dequeue(&chan->tx_q);
1988
1989 bt_cb(skb)->control.retries = 1;
1990 control = &bt_cb(skb)->control;
1991
1992 control->reqseq = 0;
1993 control->txseq = chan->next_tx_seq;
1994
1995 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001996
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001997 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001998 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1999 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002000 }
2001
Gustavo F. Padovan43434782011-04-12 18:31:57 -03002002 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002003
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002004 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07002005
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002006 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07002007 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002008 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002009}
2010
Szymon Janc67c9e842011-07-28 16:24:33 +02002011static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002012{
2013 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07002014 struct l2cap_ctrl *control;
2015 int sent = 0;
2016
2017 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002018
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03002019 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03002020 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002021
Mat Martineau94122bb2012-05-02 09:42:02 -07002022 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2023 return 0;
2024
Mat Martineaub99e13a2012-10-23 15:24:19 -07002025 if (__chan_is_moving(chan))
2026 return 0;
2027
Mat Martineau18a48e72012-05-17 20:53:34 -07002028 while (chan->tx_send_head &&
2029 chan->unacked_frames < chan->remote_tx_win &&
2030 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002031
Mat Martineau18a48e72012-05-17 20:53:34 -07002032 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002033
Mat Martineau18a48e72012-05-17 20:53:34 -07002034 bt_cb(skb)->control.retries = 1;
2035 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03002036
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002037 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07002038 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002039
Mat Martineau18a48e72012-05-17 20:53:34 -07002040 control->reqseq = chan->buffer_seq;
2041 chan->last_acked_seq = chan->buffer_seq;
2042 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002043
Mat Martineau18a48e72012-05-17 20:53:34 -07002044 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002045
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002046 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002047 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2048 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002049 }
2050
Mat Martineau18a48e72012-05-17 20:53:34 -07002051 /* Clone after data has been modified. Data is assumed to be
2052 read-only (for locking purposes) on cloned sk_buffs.
2053 */
2054 tx_skb = skb_clone(skb, GFP_KERNEL);
2055
2056 if (!tx_skb)
2057 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002058
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002059 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002060
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002061 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002062 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002063 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002064 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002065
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002066 if (skb_queue_is_last(&chan->tx_q, skb))
2067 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002068 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002069 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002070
2071 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002072 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002073 }
2074
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002075 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2076 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002077
2078 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002079}
2080
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002081static void l2cap_ertm_resend(struct l2cap_chan *chan)
2082{
2083 struct l2cap_ctrl control;
2084 struct sk_buff *skb;
2085 struct sk_buff *tx_skb;
2086 u16 seq;
2087
2088 BT_DBG("chan %p", chan);
2089
2090 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2091 return;
2092
Mat Martineaub99e13a2012-10-23 15:24:19 -07002093 if (__chan_is_moving(chan))
2094 return;
2095
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002096 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2097 seq = l2cap_seq_list_pop(&chan->retrans_list);
2098
2099 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2100 if (!skb) {
2101 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002102 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002103 continue;
2104 }
2105
2106 bt_cb(skb)->control.retries++;
2107 control = bt_cb(skb)->control;
2108
2109 if (chan->max_tx != 0 &&
2110 bt_cb(skb)->control.retries > chan->max_tx) {
2111 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002112 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002113 l2cap_seq_list_clear(&chan->retrans_list);
2114 break;
2115 }
2116
2117 control.reqseq = chan->buffer_seq;
2118 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2119 control.final = 1;
2120 else
2121 control.final = 0;
2122
2123 if (skb_cloned(skb)) {
2124 /* Cloned sk_buffs are read-only, so we need a
2125 * writeable copy
2126 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002127 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002128 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002129 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002130 }
2131
2132 if (!tx_skb) {
2133 l2cap_seq_list_clear(&chan->retrans_list);
2134 break;
2135 }
2136
2137 /* Update skb contents */
2138 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2139 put_unaligned_le32(__pack_extended_control(&control),
2140 tx_skb->data + L2CAP_HDR_SIZE);
2141 } else {
2142 put_unaligned_le16(__pack_enhanced_control(&control),
2143 tx_skb->data + L2CAP_HDR_SIZE);
2144 }
2145
2146 if (chan->fcs == L2CAP_FCS_CRC16) {
2147 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2148 put_unaligned_le16(fcs, skb_put(tx_skb,
2149 L2CAP_FCS_SIZE));
2150 }
2151
2152 l2cap_do_send(chan, tx_skb);
2153
2154 BT_DBG("Resent txseq %d", control.txseq);
2155
2156 chan->last_acked_seq = chan->buffer_seq;
2157 }
2158}
2159
Mat Martineauf80842a2012-05-17 20:53:46 -07002160static void l2cap_retransmit(struct l2cap_chan *chan,
2161 struct l2cap_ctrl *control)
2162{
2163 BT_DBG("chan %p, control %p", chan, control);
2164
2165 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2166 l2cap_ertm_resend(chan);
2167}
2168
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002169static void l2cap_retransmit_all(struct l2cap_chan *chan,
2170 struct l2cap_ctrl *control)
2171{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002172 struct sk_buff *skb;
2173
2174 BT_DBG("chan %p, control %p", chan, control);
2175
2176 if (control->poll)
2177 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2178
2179 l2cap_seq_list_clear(&chan->retrans_list);
2180
2181 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2182 return;
2183
2184 if (chan->unacked_frames) {
2185 skb_queue_walk(&chan->tx_q, skb) {
2186 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002187 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002188 break;
2189 }
2190
2191 skb_queue_walk_from(&chan->tx_q, skb) {
2192 if (skb == chan->tx_send_head)
2193 break;
2194
2195 l2cap_seq_list_append(&chan->retrans_list,
2196 bt_cb(skb)->control.txseq);
2197 }
2198
2199 l2cap_ertm_resend(chan);
2200 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002201}
2202
Szymon Jancb17e73b2012-01-11 10:59:47 +01002203static void l2cap_send_ack(struct l2cap_chan *chan)
2204{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002205 struct l2cap_ctrl control;
2206 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2207 chan->last_acked_seq);
2208 int threshold;
2209
2210 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2211 chan, chan->last_acked_seq, chan->buffer_seq);
2212
2213 memset(&control, 0, sizeof(control));
2214 control.sframe = 1;
2215
2216 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2217 chan->rx_state == L2CAP_RX_STATE_RECV) {
2218 __clear_ack_timer(chan);
2219 control.super = L2CAP_SUPER_RNR;
2220 control.reqseq = chan->buffer_seq;
2221 l2cap_send_sframe(chan, &control);
2222 } else {
2223 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2224 l2cap_ertm_send(chan);
2225 /* If any i-frames were sent, they included an ack */
2226 if (chan->buffer_seq == chan->last_acked_seq)
2227 frames_to_ack = 0;
2228 }
2229
Mat Martineauc20f8e32012-07-10 05:47:07 -07002230 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002231 * Calculate without mul or div
2232 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002233 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002234 threshold += threshold << 1;
2235 threshold >>= 2;
2236
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002237 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002238 threshold);
2239
2240 if (frames_to_ack >= threshold) {
2241 __clear_ack_timer(chan);
2242 control.super = L2CAP_SUPER_RR;
2243 control.reqseq = chan->buffer_seq;
2244 l2cap_send_sframe(chan, &control);
2245 frames_to_ack = 0;
2246 }
2247
2248 if (frames_to_ack)
2249 __set_ack_timer(chan);
2250 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002251}
2252
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002253static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2254 struct msghdr *msg, int len,
2255 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002256{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002257 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002258 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002259 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002260
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002261 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002262 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002263
2264 sent += count;
2265 len -= count;
2266
2267 /* Continuation fragments (no L2CAP header) */
2268 frag = &skb_shinfo(skb)->frag_list;
2269 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002270 struct sk_buff *tmp;
2271
Linus Torvalds1da177e2005-04-16 15:20:36 -07002272 count = min_t(unsigned int, conn->mtu, len);
2273
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002274 tmp = chan->ops->alloc_skb(chan, count,
2275 msg->msg_flags & MSG_DONTWAIT);
2276 if (IS_ERR(tmp))
2277 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002278
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002279 *frag = tmp;
2280
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002281 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2282 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002283
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002284 (*frag)->priority = skb->priority;
2285
Linus Torvalds1da177e2005-04-16 15:20:36 -07002286 sent += count;
2287 len -= count;
2288
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002289 skb->len += (*frag)->len;
2290 skb->data_len += (*frag)->len;
2291
Linus Torvalds1da177e2005-04-16 15:20:36 -07002292 frag = &(*frag)->next;
2293 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002294
2295 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002296}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002298static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002299 struct msghdr *msg, size_t len,
2300 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002301{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002302 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002303 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002304 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002305 struct l2cap_hdr *lh;
2306
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002307 BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
2308 __le16_to_cpu(chan->psm), len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002309
2310 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002311
2312 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002313 msg->msg_flags & MSG_DONTWAIT);
2314 if (IS_ERR(skb))
2315 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002316
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002317 skb->priority = priority;
2318
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002319 /* Create L2CAP header */
2320 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002321 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002322 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002323 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002324
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002325 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002326 if (unlikely(err < 0)) {
2327 kfree_skb(skb);
2328 return ERR_PTR(err);
2329 }
2330 return skb;
2331}
2332
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002333static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002334 struct msghdr *msg, size_t len,
2335 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002336{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002337 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002338 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002339 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002340 struct l2cap_hdr *lh;
2341
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002342 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002343
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002344 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002345
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002346 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002347 msg->msg_flags & MSG_DONTWAIT);
2348 if (IS_ERR(skb))
2349 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002350
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002351 skb->priority = priority;
2352
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002353 /* Create L2CAP header */
2354 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002355 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002356 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002357
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002358 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002359 if (unlikely(err < 0)) {
2360 kfree_skb(skb);
2361 return ERR_PTR(err);
2362 }
2363 return skb;
2364}
2365
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002366static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002367 struct msghdr *msg, size_t len,
2368 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002369{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002370 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002371 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002372 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002373 struct l2cap_hdr *lh;
2374
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002375 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002376
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002377 if (!conn)
2378 return ERR_PTR(-ENOTCONN);
2379
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002380 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002381
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002382 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002383 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002384
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002385 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002386 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002387
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002388 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002389
2390 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002391 msg->msg_flags & MSG_DONTWAIT);
2392 if (IS_ERR(skb))
2393 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002394
2395 /* Create L2CAP header */
2396 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002397 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002398 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002399
Mat Martineau18a48e72012-05-17 20:53:34 -07002400 /* Control header is populated later */
2401 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2402 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2403 else
2404 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002405
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002406 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002407 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002408
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002409 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002410 if (unlikely(err < 0)) {
2411 kfree_skb(skb);
2412 return ERR_PTR(err);
2413 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002414
Mat Martineau18a48e72012-05-17 20:53:34 -07002415 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002416 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002417 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002418}
2419
Mat Martineau94122bb2012-05-02 09:42:02 -07002420static int l2cap_segment_sdu(struct l2cap_chan *chan,
2421 struct sk_buff_head *seg_queue,
2422 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002423{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002424 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002425 u16 sdu_len;
2426 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002427 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002428
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002429 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002430
Mat Martineau94122bb2012-05-02 09:42:02 -07002431 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2432 * so fragmented skbs are not used. The HCI layer's handling
2433 * of fragmented skbs is not compatible with ERTM's queueing.
2434 */
2435
2436 /* PDU size is derived from the HCI MTU */
2437 pdu_len = chan->conn->mtu;
2438
Mat Martineaua5495742012-10-23 15:24:21 -07002439 /* Constrain PDU size for BR/EDR connections */
2440 if (!chan->hs_hcon)
2441 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002442
2443 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002444 if (chan->fcs)
2445 pdu_len -= L2CAP_FCS_SIZE;
2446
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002447 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002448
2449 /* Remote device may have requested smaller PDUs */
2450 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2451
2452 if (len <= pdu_len) {
2453 sar = L2CAP_SAR_UNSEGMENTED;
2454 sdu_len = 0;
2455 pdu_len = len;
2456 } else {
2457 sar = L2CAP_SAR_START;
2458 sdu_len = len;
2459 pdu_len -= L2CAP_SDULEN_SIZE;
2460 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002461
2462 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002463 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002464
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002465 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002466 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002467 return PTR_ERR(skb);
2468 }
2469
Mat Martineau94122bb2012-05-02 09:42:02 -07002470 bt_cb(skb)->control.sar = sar;
2471 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002472
Mat Martineau94122bb2012-05-02 09:42:02 -07002473 len -= pdu_len;
2474 if (sdu_len) {
2475 sdu_len = 0;
2476 pdu_len += L2CAP_SDULEN_SIZE;
2477 }
2478
2479 if (len <= pdu_len) {
2480 sar = L2CAP_SAR_END;
2481 pdu_len = len;
2482 } else {
2483 sar = L2CAP_SAR_CONTINUE;
2484 }
2485 }
2486
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002487 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002488}
2489
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002490int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002491 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002492{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002493 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002494 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002495 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002496
2497 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002498 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002499 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002500 if (IS_ERR(skb))
2501 return PTR_ERR(skb);
2502
2503 l2cap_do_send(chan, skb);
2504 return len;
2505 }
2506
2507 switch (chan->mode) {
2508 case L2CAP_MODE_BASIC:
2509 /* Check outgoing MTU */
2510 if (len > chan->omtu)
2511 return -EMSGSIZE;
2512
2513 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002514 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002515 if (IS_ERR(skb))
2516 return PTR_ERR(skb);
2517
2518 l2cap_do_send(chan, skb);
2519 err = len;
2520 break;
2521
2522 case L2CAP_MODE_ERTM:
2523 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002524 /* Check outgoing MTU */
2525 if (len > chan->omtu) {
2526 err = -EMSGSIZE;
2527 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002528 }
2529
Mat Martineau94122bb2012-05-02 09:42:02 -07002530 __skb_queue_head_init(&seg_queue);
2531
2532 /* Do segmentation before calling in to the state machine,
2533 * since it's possible to block while waiting for memory
2534 * allocation.
2535 */
2536 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2537
2538 /* The channel could have been closed while segmenting,
2539 * check that it is still connected.
2540 */
2541 if (chan->state != BT_CONNECTED) {
2542 __skb_queue_purge(&seg_queue);
2543 err = -ENOTCONN;
2544 }
2545
2546 if (err)
2547 break;
2548
Mat Martineau37339372012-05-17 20:53:33 -07002549 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002550 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002551 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002552 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002553
Gustavo Padovand6603662012-05-21 13:58:22 -03002554 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002555
Mat Martineau94122bb2012-05-02 09:42:02 -07002556 /* If the skbs were not queued for sending, they'll still be in
2557 * seg_queue and need to be purged.
2558 */
2559 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002560 break;
2561
2562 default:
2563 BT_DBG("bad state %1.1x", chan->mode);
2564 err = -EBADFD;
2565 }
2566
2567 return err;
2568}
2569
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002570static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2571{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002572 struct l2cap_ctrl control;
2573 u16 seq;
2574
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002575 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002576
2577 memset(&control, 0, sizeof(control));
2578 control.sframe = 1;
2579 control.super = L2CAP_SUPER_SREJ;
2580
2581 for (seq = chan->expected_tx_seq; seq != txseq;
2582 seq = __next_seq(chan, seq)) {
2583 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2584 control.reqseq = seq;
2585 l2cap_send_sframe(chan, &control);
2586 l2cap_seq_list_append(&chan->srej_list, seq);
2587 }
2588 }
2589
2590 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002591}
2592
2593static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2594{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002595 struct l2cap_ctrl control;
2596
2597 BT_DBG("chan %p", chan);
2598
2599 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2600 return;
2601
2602 memset(&control, 0, sizeof(control));
2603 control.sframe = 1;
2604 control.super = L2CAP_SUPER_SREJ;
2605 control.reqseq = chan->srej_list.tail;
2606 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002607}
2608
2609static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2610{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002611 struct l2cap_ctrl control;
2612 u16 initial_head;
2613 u16 seq;
2614
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002615 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002616
2617 memset(&control, 0, sizeof(control));
2618 control.sframe = 1;
2619 control.super = L2CAP_SUPER_SREJ;
2620
2621 /* Capture initial list head to allow only one pass through the list. */
2622 initial_head = chan->srej_list.head;
2623
2624 do {
2625 seq = l2cap_seq_list_pop(&chan->srej_list);
2626 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2627 break;
2628
2629 control.reqseq = seq;
2630 l2cap_send_sframe(chan, &control);
2631 l2cap_seq_list_append(&chan->srej_list, seq);
2632 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002633}
2634
Mat Martineau608bcc62012-05-17 20:53:32 -07002635static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2636{
2637 struct sk_buff *acked_skb;
2638 u16 ackseq;
2639
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002640 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002641
2642 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2643 return;
2644
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002645 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002646 chan->expected_ack_seq, chan->unacked_frames);
2647
2648 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2649 ackseq = __next_seq(chan, ackseq)) {
2650
2651 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2652 if (acked_skb) {
2653 skb_unlink(acked_skb, &chan->tx_q);
2654 kfree_skb(acked_skb);
2655 chan->unacked_frames--;
2656 }
2657 }
2658
2659 chan->expected_ack_seq = reqseq;
2660
2661 if (chan->unacked_frames == 0)
2662 __clear_retrans_timer(chan);
2663
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002664 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002665}
2666
2667static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2668{
2669 BT_DBG("chan %p", chan);
2670
2671 chan->expected_tx_seq = chan->buffer_seq;
2672 l2cap_seq_list_clear(&chan->srej_list);
2673 skb_queue_purge(&chan->srej_q);
2674 chan->rx_state = L2CAP_RX_STATE_RECV;
2675}
2676
Gustavo Padovand6603662012-05-21 13:58:22 -03002677static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2678 struct l2cap_ctrl *control,
2679 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002680{
Mat Martineau608bcc62012-05-17 20:53:32 -07002681 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2682 event);
2683
2684 switch (event) {
2685 case L2CAP_EV_DATA_REQUEST:
2686 if (chan->tx_send_head == NULL)
2687 chan->tx_send_head = skb_peek(skbs);
2688
2689 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2690 l2cap_ertm_send(chan);
2691 break;
2692 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2693 BT_DBG("Enter LOCAL_BUSY");
2694 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2695
2696 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2697 /* The SREJ_SENT state must be aborted if we are to
2698 * enter the LOCAL_BUSY state.
2699 */
2700 l2cap_abort_rx_srej_sent(chan);
2701 }
2702
2703 l2cap_send_ack(chan);
2704
2705 break;
2706 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2707 BT_DBG("Exit LOCAL_BUSY");
2708 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2709
2710 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2711 struct l2cap_ctrl local_control;
2712
2713 memset(&local_control, 0, sizeof(local_control));
2714 local_control.sframe = 1;
2715 local_control.super = L2CAP_SUPER_RR;
2716 local_control.poll = 1;
2717 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002718 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002719
2720 chan->retry_count = 1;
2721 __set_monitor_timer(chan);
2722 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2723 }
2724 break;
2725 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2726 l2cap_process_reqseq(chan, control->reqseq);
2727 break;
2728 case L2CAP_EV_EXPLICIT_POLL:
2729 l2cap_send_rr_or_rnr(chan, 1);
2730 chan->retry_count = 1;
2731 __set_monitor_timer(chan);
2732 __clear_ack_timer(chan);
2733 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2734 break;
2735 case L2CAP_EV_RETRANS_TO:
2736 l2cap_send_rr_or_rnr(chan, 1);
2737 chan->retry_count = 1;
2738 __set_monitor_timer(chan);
2739 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2740 break;
2741 case L2CAP_EV_RECV_FBIT:
2742 /* Nothing to process */
2743 break;
2744 default:
2745 break;
2746 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002747}
2748
Gustavo Padovand6603662012-05-21 13:58:22 -03002749static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2750 struct l2cap_ctrl *control,
2751 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002752{
Mat Martineau608bcc62012-05-17 20:53:32 -07002753 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2754 event);
2755
2756 switch (event) {
2757 case L2CAP_EV_DATA_REQUEST:
2758 if (chan->tx_send_head == NULL)
2759 chan->tx_send_head = skb_peek(skbs);
2760 /* Queue data, but don't send. */
2761 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2762 break;
2763 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2764 BT_DBG("Enter LOCAL_BUSY");
2765 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2766
2767 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2768 /* The SREJ_SENT state must be aborted if we are to
2769 * enter the LOCAL_BUSY state.
2770 */
2771 l2cap_abort_rx_srej_sent(chan);
2772 }
2773
2774 l2cap_send_ack(chan);
2775
2776 break;
2777 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2778 BT_DBG("Exit LOCAL_BUSY");
2779 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2780
2781 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2782 struct l2cap_ctrl local_control;
2783 memset(&local_control, 0, sizeof(local_control));
2784 local_control.sframe = 1;
2785 local_control.super = L2CAP_SUPER_RR;
2786 local_control.poll = 1;
2787 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002788 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002789
2790 chan->retry_count = 1;
2791 __set_monitor_timer(chan);
2792 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2793 }
2794 break;
2795 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2796 l2cap_process_reqseq(chan, control->reqseq);
2797
2798 /* Fall through */
2799
2800 case L2CAP_EV_RECV_FBIT:
2801 if (control && control->final) {
2802 __clear_monitor_timer(chan);
2803 if (chan->unacked_frames > 0)
2804 __set_retrans_timer(chan);
2805 chan->retry_count = 0;
2806 chan->tx_state = L2CAP_TX_STATE_XMIT;
2807 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2808 }
2809 break;
2810 case L2CAP_EV_EXPLICIT_POLL:
2811 /* Ignore */
2812 break;
2813 case L2CAP_EV_MONITOR_TO:
2814 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2815 l2cap_send_rr_or_rnr(chan, 1);
2816 __set_monitor_timer(chan);
2817 chan->retry_count++;
2818 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002819 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002820 }
2821 break;
2822 default:
2823 break;
2824 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002825}
2826
Gustavo Padovand6603662012-05-21 13:58:22 -03002827static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2828 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002829{
Mat Martineau608bcc62012-05-17 20:53:32 -07002830 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2831 chan, control, skbs, event, chan->tx_state);
2832
2833 switch (chan->tx_state) {
2834 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002835 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002836 break;
2837 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002838 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002839 break;
2840 default:
2841 /* Ignore event */
2842 break;
2843 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002844}
2845
Mat Martineau4b51dae92012-05-17 20:53:37 -07002846static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2847 struct l2cap_ctrl *control)
2848{
2849 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002850 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002851}
2852
Mat Martineauf80842a2012-05-17 20:53:46 -07002853static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2854 struct l2cap_ctrl *control)
2855{
2856 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002857 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002858}
2859
Linus Torvalds1da177e2005-04-16 15:20:36 -07002860/* Copy frame to all raw sockets on that connection */
2861static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2862{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002863 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002864 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865
2866 BT_DBG("conn %p", conn);
2867
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002868 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002869
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002870 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002871 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002872 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002873 continue;
2874
2875 /* Don't send frame to the socket it came from */
2876 if (skb->sk == sk)
2877 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002878 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002879 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002880 continue;
2881
Gustavo Padovan80b98022012-05-27 22:27:51 -03002882 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002883 kfree_skb(nskb);
2884 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002885
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002886 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887}
2888
2889/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002890static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2891 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892{
2893 struct sk_buff *skb, **frag;
2894 struct l2cap_cmd_hdr *cmd;
2895 struct l2cap_hdr *lh;
2896 int len, count;
2897
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002898 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2899 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002900
Anderson Lizardo300b9622013-06-02 16:30:40 -04002901 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2902 return NULL;
2903
Linus Torvalds1da177e2005-04-16 15:20:36 -07002904 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2905 count = min_t(unsigned int, conn->mtu, len);
2906
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002907 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002908 if (!skb)
2909 return NULL;
2910
2911 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002912 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002913
2914 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002915 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002916 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002917 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918
2919 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2920 cmd->code = code;
2921 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002922 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002923
2924 if (dlen) {
2925 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2926 memcpy(skb_put(skb, count), data, count);
2927 data += count;
2928 }
2929
2930 len -= skb->len;
2931
2932 /* Continuation fragments (no L2CAP header) */
2933 frag = &skb_shinfo(skb)->frag_list;
2934 while (len) {
2935 count = min_t(unsigned int, conn->mtu, len);
2936
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002937 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002938 if (!*frag)
2939 goto fail;
2940
2941 memcpy(skb_put(*frag, count), data, count);
2942
2943 len -= count;
2944 data += count;
2945
2946 frag = &(*frag)->next;
2947 }
2948
2949 return skb;
2950
2951fail:
2952 kfree_skb(skb);
2953 return NULL;
2954}
2955
Gustavo Padovan2d792812012-10-06 10:07:01 +01002956static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2957 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002958{
2959 struct l2cap_conf_opt *opt = *ptr;
2960 int len;
2961
2962 len = L2CAP_CONF_OPT_SIZE + opt->len;
2963 *ptr += len;
2964
2965 *type = opt->type;
2966 *olen = opt->len;
2967
2968 switch (opt->len) {
2969 case 1:
2970 *val = *((u8 *) opt->val);
2971 break;
2972
2973 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002974 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002975 break;
2976
2977 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002978 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979 break;
2980
2981 default:
2982 *val = (unsigned long) opt->val;
2983 break;
2984 }
2985
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002986 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987 return len;
2988}
2989
Linus Torvalds1da177e2005-04-16 15:20:36 -07002990static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2991{
2992 struct l2cap_conf_opt *opt = *ptr;
2993
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002994 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002995
2996 opt->type = type;
2997 opt->len = len;
2998
2999 switch (len) {
3000 case 1:
3001 *((u8 *) opt->val) = val;
3002 break;
3003
3004 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003005 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003006 break;
3007
3008 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003009 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003010 break;
3011
3012 default:
3013 memcpy(opt->val, (void *) val, len);
3014 break;
3015 }
3016
3017 *ptr += L2CAP_CONF_OPT_SIZE + len;
3018}
3019
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003020static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
3021{
3022 struct l2cap_conf_efs efs;
3023
Szymon Janc1ec918c2011-11-16 09:32:21 +01003024 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003025 case L2CAP_MODE_ERTM:
3026 efs.id = chan->local_id;
3027 efs.stype = chan->local_stype;
3028 efs.msdu = cpu_to_le16(chan->local_msdu);
3029 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003030 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003031 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003032 break;
3033
3034 case L2CAP_MODE_STREAMING:
3035 efs.id = 1;
3036 efs.stype = L2CAP_SERV_BESTEFFORT;
3037 efs.msdu = cpu_to_le16(chan->local_msdu);
3038 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
3039 efs.acc_lat = 0;
3040 efs.flush_to = 0;
3041 break;
3042
3043 default:
3044 return;
3045 }
3046
3047 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003048 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003049}
3050
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003051static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003052{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003053 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003054 ack_timer.work);
3055 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003056
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003057 BT_DBG("chan %p", chan);
3058
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003059 l2cap_chan_lock(chan);
3060
Mat Martineau03625202012-05-17 20:53:51 -07003061 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3062 chan->last_acked_seq);
3063
3064 if (frames_to_ack)
3065 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003066
3067 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003068 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003069}
3070
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003071int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003072{
Mat Martineau3c588192012-04-11 10:48:42 -07003073 int err;
3074
Mat Martineau105bdf92012-04-27 16:50:48 -07003075 chan->next_tx_seq = 0;
3076 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003077 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003078 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003079 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003080 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003081 chan->last_acked_seq = 0;
3082 chan->sdu = NULL;
3083 chan->sdu_last_frag = NULL;
3084 chan->sdu_len = 0;
3085
Mat Martineaud34c34f2012-05-14 14:49:27 -07003086 skb_queue_head_init(&chan->tx_q);
3087
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003088 chan->local_amp_id = AMP_ID_BREDR;
3089 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003090 chan->move_state = L2CAP_MOVE_STABLE;
3091 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3092
Mat Martineau105bdf92012-04-27 16:50:48 -07003093 if (chan->mode != L2CAP_MODE_ERTM)
3094 return 0;
3095
3096 chan->rx_state = L2CAP_RX_STATE_RECV;
3097 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003098
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003099 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3100 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3101 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003102
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003103 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003104
Mat Martineau3c588192012-04-11 10:48:42 -07003105 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3106 if (err < 0)
3107 return err;
3108
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003109 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3110 if (err < 0)
3111 l2cap_seq_list_free(&chan->srej_list);
3112
3113 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003114}
3115
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003116static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3117{
3118 switch (mode) {
3119 case L2CAP_MODE_STREAMING:
3120 case L2CAP_MODE_ERTM:
3121 if (l2cap_mode_supported(mode, remote_feat_mask))
3122 return mode;
3123 /* fall through */
3124 default:
3125 return L2CAP_MODE_BASIC;
3126 }
3127}
3128
Marcel Holtmann848566b2013-10-01 22:59:22 -07003129static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003130{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003131 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003132}
3133
Marcel Holtmann848566b2013-10-01 22:59:22 -07003134static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003135{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003136 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003137}
3138
Mat Martineau36c86c82012-10-23 15:24:20 -07003139static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3140 struct l2cap_conf_rfc *rfc)
3141{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003142 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003143 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3144
3145 /* Class 1 devices have must have ERTM timeouts
3146 * exceeding the Link Supervision Timeout. The
3147 * default Link Supervision Timeout for AMP
3148 * controllers is 10 seconds.
3149 *
3150 * Class 1 devices use 0xffffffff for their
3151 * best-effort flush timeout, so the clamping logic
3152 * will result in a timeout that meets the above
3153 * requirement. ERTM timeouts are 16-bit values, so
3154 * the maximum timeout is 65.535 seconds.
3155 */
3156
3157 /* Convert timeout to milliseconds and round */
3158 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3159
3160 /* This is the recommended formula for class 2 devices
3161 * that start ERTM timers when packets are sent to the
3162 * controller.
3163 */
3164 ertm_to = 3 * ertm_to + 500;
3165
3166 if (ertm_to > 0xffff)
3167 ertm_to = 0xffff;
3168
3169 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3170 rfc->monitor_timeout = rfc->retrans_timeout;
3171 } else {
3172 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3173 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3174 }
3175}
3176
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003177static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3178{
3179 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003180 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003181 /* use extended control field */
3182 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003183 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3184 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003185 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003186 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003187 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3188 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003189 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003190}
3191
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003192static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003193{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003194 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003195 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003196 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003197 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003198
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003199 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003200
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003201 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003202 goto done;
3203
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003204 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003205 case L2CAP_MODE_STREAMING:
3206 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003207 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003208 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003209
Marcel Holtmann848566b2013-10-01 22:59:22 -07003210 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003211 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3212
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003213 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003214 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003215 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003216 break;
3217 }
3218
3219done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003220 if (chan->imtu != L2CAP_DEFAULT_MTU)
3221 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003222
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003223 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003224 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003225 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003226 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003227 break;
3228
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003229 rfc.mode = L2CAP_MODE_BASIC;
3230 rfc.txwin_size = 0;
3231 rfc.max_transmit = 0;
3232 rfc.retrans_timeout = 0;
3233 rfc.monitor_timeout = 0;
3234 rfc.max_pdu_size = 0;
3235
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003236 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003237 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003238 break;
3239
3240 case L2CAP_MODE_ERTM:
3241 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003242 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003243
3244 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003245
3246 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003247 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3248 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003249 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003250
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003251 l2cap_txwin_setup(chan);
3252
3253 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003254 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003255
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003256 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003257 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003258
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003259 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3260 l2cap_add_opt_efs(&ptr, chan);
3261
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003262 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3263 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003264 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003265
3266 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3267 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003268 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003269 chan->fcs = L2CAP_FCS_NONE;
3270 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3271 chan->fcs);
3272 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003273 break;
3274
3275 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003276 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003277 rfc.mode = L2CAP_MODE_STREAMING;
3278 rfc.txwin_size = 0;
3279 rfc.max_transmit = 0;
3280 rfc.retrans_timeout = 0;
3281 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003282
3283 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003284 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3285 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003286 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003287
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003288 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003289 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003290
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003291 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3292 l2cap_add_opt_efs(&ptr, chan);
3293
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003294 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3295 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003296 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003297 chan->fcs = L2CAP_FCS_NONE;
3298 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3299 chan->fcs);
3300 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003301 break;
3302 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003303
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003304 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003305 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003306
3307 return ptr - data;
3308}
3309
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003310static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003311{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003312 struct l2cap_conf_rsp *rsp = data;
3313 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003314 void *req = chan->conf_req;
3315 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003316 int type, hint, olen;
3317 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003318 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003319 struct l2cap_conf_efs efs;
3320 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003321 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003322 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003323 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003324
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003325 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003326
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003327 while (len >= L2CAP_CONF_OPT_SIZE) {
3328 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003329
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003330 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003331 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003332
3333 switch (type) {
3334 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003335 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003336 break;
3337
3338 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003339 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003340 break;
3341
3342 case L2CAP_CONF_QOS:
3343 break;
3344
Marcel Holtmann6464f352007-10-20 13:39:51 +02003345 case L2CAP_CONF_RFC:
3346 if (olen == sizeof(rfc))
3347 memcpy(&rfc, (void *) val, olen);
3348 break;
3349
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003350 case L2CAP_CONF_FCS:
3351 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003352 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003353 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003354
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003355 case L2CAP_CONF_EFS:
3356 remote_efs = 1;
3357 if (olen == sizeof(efs))
3358 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003359 break;
3360
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003361 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003362 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003363 return -ECONNREFUSED;
3364
3365 set_bit(FLAG_EXT_CTRL, &chan->flags);
3366 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003367 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003368 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003369 break;
3370
3371 default:
3372 if (hint)
3373 break;
3374
3375 result = L2CAP_CONF_UNKNOWN;
3376 *((u8 *) ptr++) = type;
3377 break;
3378 }
3379 }
3380
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003381 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003382 goto done;
3383
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003384 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003385 case L2CAP_MODE_STREAMING:
3386 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003387 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003388 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003389 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003390 break;
3391 }
3392
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003393 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003394 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003395 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3396 else
3397 return -ECONNREFUSED;
3398 }
3399
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003400 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003401 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003402
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003403 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003404 }
3405
3406done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003407 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003408 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003409 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003410
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003411 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003412 return -ECONNREFUSED;
3413
Gustavo Padovan2d792812012-10-06 10:07:01 +01003414 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3415 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003416 }
3417
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003418 if (result == L2CAP_CONF_SUCCESS) {
3419 /* Configure output options and let the other side know
3420 * which ones we don't like. */
3421
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003422 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3423 result = L2CAP_CONF_UNACCEPT;
3424 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003425 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003426 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003427 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003428 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003429
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003430 if (remote_efs) {
3431 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003432 efs.stype != L2CAP_SERV_NOTRAFIC &&
3433 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003434
3435 result = L2CAP_CONF_UNACCEPT;
3436
3437 if (chan->num_conf_req >= 1)
3438 return -ECONNREFUSED;
3439
3440 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003441 sizeof(efs),
3442 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003443 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003444 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003445 result = L2CAP_CONF_PENDING;
3446 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003447 }
3448 }
3449
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003450 switch (rfc.mode) {
3451 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003452 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003453 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003454 break;
3455
3456 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003457 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3458 chan->remote_tx_win = rfc.txwin_size;
3459 else
3460 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3461
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003462 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003463
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003464 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003465 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3466 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003467 rfc.max_pdu_size = cpu_to_le16(size);
3468 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003469
Mat Martineau36c86c82012-10-23 15:24:20 -07003470 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003471
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003472 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003473
3474 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003475 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003476
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003477 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3478 chan->remote_id = efs.id;
3479 chan->remote_stype = efs.stype;
3480 chan->remote_msdu = le16_to_cpu(efs.msdu);
3481 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003482 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003483 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003484 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003485 chan->remote_sdu_itime =
3486 le32_to_cpu(efs.sdu_itime);
3487 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003488 sizeof(efs),
3489 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003490 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003491 break;
3492
3493 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003494 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003495 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3496 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003497 rfc.max_pdu_size = cpu_to_le16(size);
3498 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003499
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003500 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003501
Gustavo Padovan2d792812012-10-06 10:07:01 +01003502 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3503 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003504
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003505 break;
3506
3507 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003508 result = L2CAP_CONF_UNACCEPT;
3509
3510 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003511 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003512 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003513
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003514 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003515 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003516 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003517 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003518 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003519 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003520
3521 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003522}
3523
Gustavo Padovan2d792812012-10-06 10:07:01 +01003524static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3525 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003526{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003527 struct l2cap_conf_req *req = data;
3528 void *ptr = req->data;
3529 int type, olen;
3530 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003531 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003532 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003533
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003534 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003535
3536 while (len >= L2CAP_CONF_OPT_SIZE) {
3537 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3538
3539 switch (type) {
3540 case L2CAP_CONF_MTU:
3541 if (val < L2CAP_DEFAULT_MIN_MTU) {
3542 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003543 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003544 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003545 chan->imtu = val;
3546 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003547 break;
3548
3549 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003550 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003551 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003552 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003553 break;
3554
3555 case L2CAP_CONF_RFC:
3556 if (olen == sizeof(rfc))
3557 memcpy(&rfc, (void *)val, olen);
3558
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003559 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003560 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003561 return -ECONNREFUSED;
3562
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003563 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003564
3565 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003566 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003567 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003568
3569 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003570 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003571 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003572 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003573 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003574
3575 case L2CAP_CONF_EFS:
3576 if (olen == sizeof(efs))
3577 memcpy(&efs, (void *)val, olen);
3578
3579 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003580 efs.stype != L2CAP_SERV_NOTRAFIC &&
3581 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003582 return -ECONNREFUSED;
3583
Gustavo Padovan2d792812012-10-06 10:07:01 +01003584 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3585 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003586 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003587
3588 case L2CAP_CONF_FCS:
3589 if (*result == L2CAP_CONF_PENDING)
3590 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003591 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003592 &chan->conf_state);
3593 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003594 }
3595 }
3596
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003597 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003598 return -ECONNREFUSED;
3599
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003600 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003601
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003602 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003603 switch (rfc.mode) {
3604 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003605 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3606 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3607 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003608 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3609 chan->ack_win = min_t(u16, chan->ack_win,
3610 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003611
3612 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3613 chan->local_msdu = le16_to_cpu(efs.msdu);
3614 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003615 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003616 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3617 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003618 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003619 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003620 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003621
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003622 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003623 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003624 }
3625 }
3626
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003627 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003628 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003629
3630 return ptr - data;
3631}
3632
Gustavo Padovan2d792812012-10-06 10:07:01 +01003633static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3634 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003635{
3636 struct l2cap_conf_rsp *rsp = data;
3637 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003638
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003639 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003640
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003641 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003642 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003643 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003644
3645 return ptr - data;
3646}
3647
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003648void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003649{
3650 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003651 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003652 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003653 u8 rsp_code;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003654
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003655 rsp.scid = cpu_to_le16(chan->dcid);
3656 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003657 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3658 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003659
3660 if (chan->hs_hcon)
3661 rsp_code = L2CAP_CREATE_CHAN_RSP;
3662 else
3663 rsp_code = L2CAP_CONN_RSP;
3664
3665 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3666
3667 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003668
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003669 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003670 return;
3671
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003672 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003673 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003674 chan->num_conf_req++;
3675}
3676
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003677static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003678{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003679 int type, olen;
3680 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003681 /* Use sane default values in case a misbehaving remote device
3682 * did not send an RFC or extended window size option.
3683 */
3684 u16 txwin_ext = chan->ack_win;
3685 struct l2cap_conf_rfc rfc = {
3686 .mode = chan->mode,
3687 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3688 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3689 .max_pdu_size = cpu_to_le16(chan->imtu),
3690 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3691 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003692
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003693 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003694
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003695 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003696 return;
3697
3698 while (len >= L2CAP_CONF_OPT_SIZE) {
3699 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3700
Mat Martineauc20f8e32012-07-10 05:47:07 -07003701 switch (type) {
3702 case L2CAP_CONF_RFC:
3703 if (olen == sizeof(rfc))
3704 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003705 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003706 case L2CAP_CONF_EWS:
3707 txwin_ext = val;
3708 break;
3709 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003710 }
3711
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003712 switch (rfc.mode) {
3713 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003714 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3715 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003716 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3717 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3718 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3719 else
3720 chan->ack_win = min_t(u16, chan->ack_win,
3721 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003722 break;
3723 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003724 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003725 }
3726}
3727
Gustavo Padovan2d792812012-10-06 10:07:01 +01003728static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003729 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3730 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003731{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003732 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003733
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003734 if (cmd_len < sizeof(*rej))
3735 return -EPROTO;
3736
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003737 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003738 return 0;
3739
3740 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003741 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003742 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003743
3744 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003745 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003746
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003747 l2cap_conn_start(conn);
3748 }
3749
3750 return 0;
3751}
3752
Mat Martineau17009152012-10-23 15:24:07 -07003753static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3754 struct l2cap_cmd_hdr *cmd,
3755 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003756{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003757 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3758 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003759 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003760 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003761 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003762
3763 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003764 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003765
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003766 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003767
3768 /* Check if we have socket listening on psm */
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003769 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07003770 &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003771 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003772 result = L2CAP_CR_BAD_PSM;
3773 goto sendresp;
3774 }
3775
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003776 parent = pchan->sk;
3777
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003778 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003779 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003780
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003781 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003782 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003783 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003784 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003785 result = L2CAP_CR_SEC_BLOCK;
3786 goto response;
3787 }
3788
Linus Torvalds1da177e2005-04-16 15:20:36 -07003789 result = L2CAP_CR_NO_MEM;
3790
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003791 /* Check if we already have channel with that dcid */
3792 if (__l2cap_get_chan_by_dcid(conn, scid))
3793 goto response;
3794
Gustavo Padovan80b98022012-05-27 22:27:51 -03003795 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003796 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003797 goto response;
3798
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003799 sk = chan->sk;
3800
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09003801 /* For certain devices (ex: HID mouse), support for authentication,
3802 * pairing and bonding is optional. For such devices, inorder to avoid
3803 * the ACL alive for too long after L2CAP disconnection, reset the ACL
3804 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
3805 */
3806 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3807
Marcel Holtmann7eafc592013-10-13 08:12:47 -07003808 bacpy(&chan->src, &conn->hcon->src);
3809 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07003810 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
3811 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003812 chan->psm = psm;
3813 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003814 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003815
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003816 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003817
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003818 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003819
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003820 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003821
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003822 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003823
Marcel Holtmann984947d2009-02-06 23:35:19 +01003824 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003825 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003826 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003827 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003828 result = L2CAP_CR_PEND;
3829 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003830 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003831 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003832 /* Force pending result for AMP controllers.
3833 * The connection will succeed after the
3834 * physical link is up.
3835 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003836 if (amp_id == AMP_ID_BREDR) {
Mat Martineau17009152012-10-23 15:24:07 -07003837 __l2cap_state_change(chan, BT_CONFIG);
3838 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003839 } else {
3840 __l2cap_state_change(chan, BT_CONNECT2);
3841 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07003842 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003843 status = L2CAP_CS_NO_INFO;
3844 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003845 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003846 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003847 result = L2CAP_CR_PEND;
3848 status = L2CAP_CS_AUTHEN_PEND;
3849 }
3850 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003851 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003852 result = L2CAP_CR_PEND;
3853 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003854 }
3855
Linus Torvalds1da177e2005-04-16 15:20:36 -07003856response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003857 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003858 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003859
3860sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003861 rsp.scid = cpu_to_le16(scid);
3862 rsp.dcid = cpu_to_le16(dcid);
3863 rsp.result = cpu_to_le16(result);
3864 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003865 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003866
3867 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3868 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003869 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003870
3871 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3872 conn->info_ident = l2cap_get_ident(conn);
3873
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003874 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003875
Gustavo Padovan2d792812012-10-06 10:07:01 +01003876 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3877 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003878 }
3879
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003880 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003881 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003882 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003883 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003884 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003885 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003886 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003887 }
Mat Martineau17009152012-10-23 15:24:07 -07003888
3889 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003890}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003891
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003892static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003893 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003894{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303895 struct hci_dev *hdev = conn->hcon->hdev;
3896 struct hci_conn *hcon = conn->hcon;
3897
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003898 if (cmd_len < sizeof(struct l2cap_conn_req))
3899 return -EPROTO;
3900
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303901 hci_dev_lock(hdev);
3902 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3903 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3904 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3905 hcon->dst_type, 0, NULL, 0,
3906 hcon->dev_class);
3907 hci_dev_unlock(hdev);
3908
Gustavo Padovan300229f2012-10-12 19:40:40 +08003909 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003910 return 0;
3911}
3912
Mat Martineau5909cf32012-10-23 15:24:08 -07003913static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003914 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3915 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003916{
3917 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3918 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003919 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003920 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003921 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003922
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003923 if (cmd_len < sizeof(*rsp))
3924 return -EPROTO;
3925
Linus Torvalds1da177e2005-04-16 15:20:36 -07003926 scid = __le16_to_cpu(rsp->scid);
3927 dcid = __le16_to_cpu(rsp->dcid);
3928 result = __le16_to_cpu(rsp->result);
3929 status = __le16_to_cpu(rsp->status);
3930
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003931 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 +01003932 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003933
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003934 mutex_lock(&conn->chan_lock);
3935
Linus Torvalds1da177e2005-04-16 15:20:36 -07003936 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003937 chan = __l2cap_get_chan_by_scid(conn, scid);
3938 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003939 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003940 goto unlock;
3941 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003942 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003943 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3944 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003945 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003946 goto unlock;
3947 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003948 }
3949
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003950 err = 0;
3951
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003952 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003953
Linus Torvalds1da177e2005-04-16 15:20:36 -07003954 switch (result) {
3955 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03003956 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003957 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003958 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003959 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003960
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003961 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003962 break;
3963
Linus Torvalds1da177e2005-04-16 15:20:36 -07003964 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003965 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003966 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003967 break;
3968
3969 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003970 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003971 break;
3972
3973 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003974 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003975 break;
3976 }
3977
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003978 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003979
3980unlock:
3981 mutex_unlock(&conn->chan_lock);
3982
3983 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003984}
3985
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003986static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003987{
3988 /* FCS is enabled only in ERTM or streaming mode, if one or both
3989 * sides request it.
3990 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003991 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003992 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003993 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003994 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003995}
3996
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003997static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3998 u8 ident, u16 flags)
3999{
4000 struct l2cap_conn *conn = chan->conn;
4001
4002 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
4003 flags);
4004
4005 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
4006 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
4007
4008 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
4009 l2cap_build_conf_rsp(chan, data,
4010 L2CAP_CONF_SUCCESS, flags), data);
4011}
4012
Gustavo Padovan2d792812012-10-06 10:07:01 +01004013static inline int l2cap_config_req(struct l2cap_conn *conn,
4014 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4015 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004016{
4017 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
4018 u16 dcid, flags;
4019 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004020 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07004021 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004022
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004023 if (cmd_len < sizeof(*req))
4024 return -EPROTO;
4025
Linus Torvalds1da177e2005-04-16 15:20:36 -07004026 dcid = __le16_to_cpu(req->dcid);
4027 flags = __le16_to_cpu(req->flags);
4028
4029 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
4030
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004031 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004032 if (!chan)
Johan Hedberg21870b52013-09-16 13:05:14 +03004033 return -EBADSLT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004034
David S. Miller033b1142011-07-21 13:38:42 -07004035 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004036 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004037
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004038 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004039 rej.scid = cpu_to_le16(chan->scid);
4040 rej.dcid = cpu_to_le16(chan->dcid);
4041
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004042 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004043 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004044 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004045 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004046
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004047 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004048 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004049 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004050 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004051 l2cap_build_conf_rsp(chan, rsp,
4052 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004053 goto unlock;
4054 }
4055
4056 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004057 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4058 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004059
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004060 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004061 /* Incomplete config. Send empty response. */
4062 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004063 l2cap_build_conf_rsp(chan, rsp,
4064 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004065 goto unlock;
4066 }
4067
4068 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004069 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004070 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004071 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004072 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004073 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004074
Mat Martineau1500109b2012-10-23 15:24:15 -07004075 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004076 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004077 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004078
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004079 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004080 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004081
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004082 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004083 goto unlock;
4084
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004085 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004086 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004087
Mat Martineau105bdf92012-04-27 16:50:48 -07004088 if (chan->mode == L2CAP_MODE_ERTM ||
4089 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004090 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004091
Mat Martineau3c588192012-04-11 10:48:42 -07004092 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004093 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004094 else
4095 l2cap_chan_ready(chan);
4096
Marcel Holtmann876d9482007-10-20 13:35:42 +02004097 goto unlock;
4098 }
4099
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004100 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004101 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004102 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004103 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004104 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004105 }
4106
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004107 /* Got Conf Rsp PENDING from remote side and asume we sent
4108 Conf Rsp PENDING in the code above */
4109 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004110 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004111
4112 /* check compatibility */
4113
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004114 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004115 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004116 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4117 else
4118 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004119 }
4120
Linus Torvalds1da177e2005-04-16 15:20:36 -07004121unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004122 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004123 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004124}
4125
Gustavo Padovan2d792812012-10-06 10:07:01 +01004126static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004127 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4128 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004129{
4130 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4131 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004132 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004133 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004134 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004135
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004136 if (cmd_len < sizeof(*rsp))
4137 return -EPROTO;
4138
Linus Torvalds1da177e2005-04-16 15:20:36 -07004139 scid = __le16_to_cpu(rsp->scid);
4140 flags = __le16_to_cpu(rsp->flags);
4141 result = __le16_to_cpu(rsp->result);
4142
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004143 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4144 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004145
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004146 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004147 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004148 return 0;
4149
4150 switch (result) {
4151 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004152 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004153 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004154 break;
4155
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004156 case L2CAP_CONF_PENDING:
4157 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4158
4159 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4160 char buf[64];
4161
4162 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004163 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004164 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004165 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004166 goto done;
4167 }
4168
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004169 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004170 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4171 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004172 } else {
4173 if (l2cap_check_efs(chan)) {
4174 amp_create_logical_link(chan);
4175 chan->ident = cmd->ident;
4176 }
4177 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004178 }
4179 goto done;
4180
Linus Torvalds1da177e2005-04-16 15:20:36 -07004181 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004182 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004183 char req[64];
4184
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004185 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004186 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004187 goto done;
4188 }
4189
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004190 /* throw out any old stored conf requests */
4191 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004192 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004193 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004194 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004195 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004196 goto done;
4197 }
4198
4199 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004200 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004201 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004202 if (result != L2CAP_CONF_SUCCESS)
4203 goto done;
4204 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004205 }
4206
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004207 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004208 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004209
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004210 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004211 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004212 goto done;
4213 }
4214
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004215 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004216 goto done;
4217
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004218 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004219
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004220 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004221 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004222
Mat Martineau105bdf92012-04-27 16:50:48 -07004223 if (chan->mode == L2CAP_MODE_ERTM ||
4224 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004225 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004226
Mat Martineau3c588192012-04-11 10:48:42 -07004227 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004228 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004229 else
4230 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004231 }
4232
4233done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004234 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004235 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004236}
4237
Gustavo Padovan2d792812012-10-06 10:07:01 +01004238static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004239 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4240 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004241{
4242 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4243 struct l2cap_disconn_rsp rsp;
4244 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004245 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004246 struct sock *sk;
4247
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004248 if (cmd_len != sizeof(*req))
4249 return -EPROTO;
4250
Linus Torvalds1da177e2005-04-16 15:20:36 -07004251 scid = __le16_to_cpu(req->scid);
4252 dcid = __le16_to_cpu(req->dcid);
4253
4254 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4255
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004256 mutex_lock(&conn->chan_lock);
4257
4258 chan = __l2cap_get_chan_by_scid(conn, dcid);
4259 if (!chan) {
4260 mutex_unlock(&conn->chan_lock);
Johan Hedbergc4ea2492013-09-16 13:05:15 +03004261 return -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004262 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004263
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004264 l2cap_chan_lock(chan);
4265
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004266 sk = chan->sk;
4267
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004268 rsp.dcid = cpu_to_le16(chan->scid);
4269 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004270 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4271
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004272 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004273 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004274 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004275
Mat Martineau61d6ef32012-04-27 16:50:50 -07004276 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004277 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004278
4279 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004280
Gustavo Padovan80b98022012-05-27 22:27:51 -03004281 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004282 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004283
4284 mutex_unlock(&conn->chan_lock);
4285
Linus Torvalds1da177e2005-04-16 15:20:36 -07004286 return 0;
4287}
4288
Gustavo Padovan2d792812012-10-06 10:07:01 +01004289static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004290 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4291 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004292{
4293 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4294 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004295 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004296
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004297 if (cmd_len != sizeof(*rsp))
4298 return -EPROTO;
4299
Linus Torvalds1da177e2005-04-16 15:20:36 -07004300 scid = __le16_to_cpu(rsp->scid);
4301 dcid = __le16_to_cpu(rsp->dcid);
4302
4303 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4304
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004305 mutex_lock(&conn->chan_lock);
4306
4307 chan = __l2cap_get_chan_by_scid(conn, scid);
4308 if (!chan) {
4309 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004310 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004311 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004312
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004313 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004314
Mat Martineau61d6ef32012-04-27 16:50:50 -07004315 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004316 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004317
4318 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004319
Gustavo Padovan80b98022012-05-27 22:27:51 -03004320 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004321 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004322
4323 mutex_unlock(&conn->chan_lock);
4324
Linus Torvalds1da177e2005-04-16 15:20:36 -07004325 return 0;
4326}
4327
Gustavo Padovan2d792812012-10-06 10:07:01 +01004328static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004329 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4330 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004331{
4332 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004333 u16 type;
4334
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004335 if (cmd_len != sizeof(*req))
4336 return -EPROTO;
4337
Linus Torvalds1da177e2005-04-16 15:20:36 -07004338 type = __le16_to_cpu(req->type);
4339
4340 BT_DBG("type 0x%4.4x", type);
4341
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004342 if (type == L2CAP_IT_FEAT_MASK) {
4343 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004344 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004345 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004346 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4347 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004348 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004349 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004350 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004351 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004352 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004353 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004354
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004355 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004356 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4357 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004358 } else if (type == L2CAP_IT_FIXED_CHAN) {
4359 u8 buf[12];
4360 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004361
Marcel Holtmann848566b2013-10-01 22:59:22 -07004362 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004363 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4364 else
4365 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4366
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004367 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4368 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004369 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004370 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4371 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004372 } else {
4373 struct l2cap_info_rsp rsp;
4374 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004375 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004376 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4377 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004378 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004379
4380 return 0;
4381}
4382
Gustavo Padovan2d792812012-10-06 10:07:01 +01004383static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004384 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4385 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004386{
4387 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4388 u16 type, result;
4389
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304390 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004391 return -EPROTO;
4392
Linus Torvalds1da177e2005-04-16 15:20:36 -07004393 type = __le16_to_cpu(rsp->type);
4394 result = __le16_to_cpu(rsp->result);
4395
4396 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4397
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004398 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4399 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004400 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004401 return 0;
4402
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004403 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004404
Ville Tervoadb08ed2010-08-04 09:43:33 +03004405 if (result != L2CAP_IR_SUCCESS) {
4406 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4407 conn->info_ident = 0;
4408
4409 l2cap_conn_start(conn);
4410
4411 return 0;
4412 }
4413
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004414 switch (type) {
4415 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004416 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004417
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004418 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004419 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004420 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004421
4422 conn->info_ident = l2cap_get_ident(conn);
4423
4424 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004425 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004426 } else {
4427 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4428 conn->info_ident = 0;
4429
4430 l2cap_conn_start(conn);
4431 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004432 break;
4433
4434 case L2CAP_IT_FIXED_CHAN:
4435 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004436 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004437 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004438
4439 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004440 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004441 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004442
Linus Torvalds1da177e2005-04-16 15:20:36 -07004443 return 0;
4444}
4445
Mat Martineau17009152012-10-23 15:24:07 -07004446static int l2cap_create_channel_req(struct l2cap_conn *conn,
4447 struct l2cap_cmd_hdr *cmd,
4448 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004449{
4450 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004451 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004452 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004453 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004454 u16 psm, scid;
4455
4456 if (cmd_len != sizeof(*req))
4457 return -EPROTO;
4458
Marcel Holtmann848566b2013-10-01 22:59:22 -07004459 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004460 return -EINVAL;
4461
4462 psm = le16_to_cpu(req->psm);
4463 scid = le16_to_cpu(req->scid);
4464
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004465 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 -07004466
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004467 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004468 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004469 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4470 req->amp_id);
4471 return 0;
4472 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004473
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004474 /* Validate AMP controller id */
4475 hdev = hci_dev_get(req->amp_id);
4476 if (!hdev)
4477 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004478
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004479 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004480 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004481 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004482 }
4483
4484 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4485 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004486 if (chan) {
4487 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4488 struct hci_conn *hs_hcon;
4489
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004490 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4491 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004492 if (!hs_hcon) {
4493 hci_dev_put(hdev);
Johan Hedberg21870b52013-09-16 13:05:14 +03004494 return -EBADSLT;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004495 }
4496
4497 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4498
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004499 mgr->bredr_chan = chan;
4500 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004501 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004502 conn->mtu = hdev->block_mtu;
4503 }
4504
4505 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004506
4507 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004508
4509error:
4510 rsp.dcid = 0;
4511 rsp.scid = cpu_to_le16(scid);
4512 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4513 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4514
4515 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4516 sizeof(rsp), &rsp);
4517
Johan Hedbergdc280802013-09-16 13:05:13 +03004518 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004519}
4520
Mat Martineau8eb200b2012-10-23 15:24:17 -07004521static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4522{
4523 struct l2cap_move_chan_req req;
4524 u8 ident;
4525
4526 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4527
4528 ident = l2cap_get_ident(chan->conn);
4529 chan->ident = ident;
4530
4531 req.icid = cpu_to_le16(chan->scid);
4532 req.dest_amp_id = dest_amp_id;
4533
4534 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4535 &req);
4536
4537 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4538}
4539
Mat Martineau1500109b2012-10-23 15:24:15 -07004540static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004541{
4542 struct l2cap_move_chan_rsp rsp;
4543
Mat Martineau1500109b2012-10-23 15:24:15 -07004544 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004545
Mat Martineau1500109b2012-10-23 15:24:15 -07004546 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004547 rsp.result = cpu_to_le16(result);
4548
Mat Martineau1500109b2012-10-23 15:24:15 -07004549 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4550 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004551}
4552
Mat Martineau5b155ef2012-10-23 15:24:14 -07004553static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004554{
4555 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004556
Mat Martineau5b155ef2012-10-23 15:24:14 -07004557 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004558
Mat Martineau5b155ef2012-10-23 15:24:14 -07004559 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004560
Mat Martineau5b155ef2012-10-23 15:24:14 -07004561 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004562 cfm.result = cpu_to_le16(result);
4563
Mat Martineau5b155ef2012-10-23 15:24:14 -07004564 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4565 sizeof(cfm), &cfm);
4566
4567 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4568}
4569
4570static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4571{
4572 struct l2cap_move_chan_cfm cfm;
4573
4574 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4575
4576 cfm.icid = cpu_to_le16(icid);
4577 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4578
4579 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4580 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004581}
4582
4583static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004584 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004585{
4586 struct l2cap_move_chan_cfm_rsp rsp;
4587
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004588 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004589
4590 rsp.icid = cpu_to_le16(icid);
4591 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4592}
4593
Mat Martineau5f3847a2012-10-23 15:24:12 -07004594static void __release_logical_link(struct l2cap_chan *chan)
4595{
4596 chan->hs_hchan = NULL;
4597 chan->hs_hcon = NULL;
4598
4599 /* Placeholder - release the logical link */
4600}
4601
Mat Martineau1500109b2012-10-23 15:24:15 -07004602static void l2cap_logical_fail(struct l2cap_chan *chan)
4603{
4604 /* Logical link setup failed */
4605 if (chan->state != BT_CONNECTED) {
4606 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004607 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004608 return;
4609 }
4610
4611 switch (chan->move_role) {
4612 case L2CAP_MOVE_ROLE_RESPONDER:
4613 l2cap_move_done(chan);
4614 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4615 break;
4616 case L2CAP_MOVE_ROLE_INITIATOR:
4617 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4618 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4619 /* Remote has only sent pending or
4620 * success responses, clean up
4621 */
4622 l2cap_move_done(chan);
4623 }
4624
4625 /* Other amp move states imply that the move
4626 * has already aborted
4627 */
4628 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4629 break;
4630 }
4631}
4632
4633static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4634 struct hci_chan *hchan)
4635{
4636 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004637
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004638 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004639 chan->hs_hcon->l2cap_data = chan->conn;
4640
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004641 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004642
4643 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004644 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004645
4646 set_default_fcs(chan);
4647
4648 err = l2cap_ertm_init(chan);
4649 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004650 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004651 else
4652 l2cap_chan_ready(chan);
4653 }
4654}
4655
4656static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4657 struct hci_chan *hchan)
4658{
4659 chan->hs_hcon = hchan->conn;
4660 chan->hs_hcon->l2cap_data = chan->conn;
4661
4662 BT_DBG("move_state %d", chan->move_state);
4663
4664 switch (chan->move_state) {
4665 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4666 /* Move confirm will be sent after a success
4667 * response is received
4668 */
4669 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4670 break;
4671 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4672 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4673 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4674 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4675 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4676 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4677 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4678 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4679 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4680 }
4681 break;
4682 default:
4683 /* Move was not in expected state, free the channel */
4684 __release_logical_link(chan);
4685
4686 chan->move_state = L2CAP_MOVE_STABLE;
4687 }
4688}
4689
4690/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004691void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4692 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004693{
Mat Martineau1500109b2012-10-23 15:24:15 -07004694 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4695
4696 if (status) {
4697 l2cap_logical_fail(chan);
4698 __release_logical_link(chan);
4699 return;
4700 }
4701
4702 if (chan->state != BT_CONNECTED) {
4703 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004704 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004705 l2cap_logical_finish_create(chan, hchan);
4706 } else {
4707 l2cap_logical_finish_move(chan, hchan);
4708 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004709}
4710
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004711void l2cap_move_start(struct l2cap_chan *chan)
4712{
4713 BT_DBG("chan %p", chan);
4714
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004715 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004716 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4717 return;
4718 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4719 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4720 /* Placeholder - start physical link setup */
4721 } else {
4722 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4723 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4724 chan->move_id = 0;
4725 l2cap_move_setup(chan);
4726 l2cap_send_move_chan_req(chan, 0);
4727 }
4728}
4729
Mat Martineau8eb200b2012-10-23 15:24:17 -07004730static void l2cap_do_create(struct l2cap_chan *chan, int result,
4731 u8 local_amp_id, u8 remote_amp_id)
4732{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004733 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4734 local_amp_id, remote_amp_id);
4735
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004736 chan->fcs = L2CAP_FCS_NONE;
4737
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004738 /* Outgoing channel on AMP */
4739 if (chan->state == BT_CONNECT) {
4740 if (result == L2CAP_CR_SUCCESS) {
4741 chan->local_amp_id = local_amp_id;
4742 l2cap_send_create_chan_req(chan, remote_amp_id);
4743 } else {
4744 /* Revert to BR/EDR connect */
4745 l2cap_send_conn_req(chan);
4746 }
4747
4748 return;
4749 }
4750
4751 /* Incoming channel on AMP */
4752 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004753 struct l2cap_conn_rsp rsp;
4754 char buf[128];
4755 rsp.scid = cpu_to_le16(chan->dcid);
4756 rsp.dcid = cpu_to_le16(chan->scid);
4757
Mat Martineau8eb200b2012-10-23 15:24:17 -07004758 if (result == L2CAP_CR_SUCCESS) {
4759 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004760 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4761 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004762 } else {
4763 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004764 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4765 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004766 }
4767
4768 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4769 sizeof(rsp), &rsp);
4770
4771 if (result == L2CAP_CR_SUCCESS) {
4772 __l2cap_state_change(chan, BT_CONFIG);
4773 set_bit(CONF_REQ_SENT, &chan->conf_state);
4774 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4775 L2CAP_CONF_REQ,
4776 l2cap_build_conf_req(chan, buf), buf);
4777 chan->num_conf_req++;
4778 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004779 }
4780}
4781
4782static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4783 u8 remote_amp_id)
4784{
4785 l2cap_move_setup(chan);
4786 chan->move_id = local_amp_id;
4787 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4788
4789 l2cap_send_move_chan_req(chan, remote_amp_id);
4790}
4791
4792static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4793{
4794 struct hci_chan *hchan = NULL;
4795
4796 /* Placeholder - get hci_chan for logical link */
4797
4798 if (hchan) {
4799 if (hchan->state == BT_CONNECTED) {
4800 /* Logical link is ready to go */
4801 chan->hs_hcon = hchan->conn;
4802 chan->hs_hcon->l2cap_data = chan->conn;
4803 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4804 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4805
4806 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4807 } else {
4808 /* Wait for logical link to be ready */
4809 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4810 }
4811 } else {
4812 /* Logical link not available */
4813 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4814 }
4815}
4816
4817static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4818{
4819 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4820 u8 rsp_result;
4821 if (result == -EINVAL)
4822 rsp_result = L2CAP_MR_BAD_ID;
4823 else
4824 rsp_result = L2CAP_MR_NOT_ALLOWED;
4825
4826 l2cap_send_move_chan_rsp(chan, rsp_result);
4827 }
4828
4829 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4830 chan->move_state = L2CAP_MOVE_STABLE;
4831
4832 /* Restart data transmission */
4833 l2cap_ertm_send(chan);
4834}
4835
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004836/* Invoke with locked chan */
4837void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004838{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004839 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004840 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004841
Mat Martineau8eb200b2012-10-23 15:24:17 -07004842 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4843 chan, result, local_amp_id, remote_amp_id);
4844
Mat Martineau8eb200b2012-10-23 15:24:17 -07004845 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4846 l2cap_chan_unlock(chan);
4847 return;
4848 }
4849
4850 if (chan->state != BT_CONNECTED) {
4851 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4852 } else if (result != L2CAP_MR_SUCCESS) {
4853 l2cap_do_move_cancel(chan, result);
4854 } else {
4855 switch (chan->move_role) {
4856 case L2CAP_MOVE_ROLE_INITIATOR:
4857 l2cap_do_move_initiate(chan, local_amp_id,
4858 remote_amp_id);
4859 break;
4860 case L2CAP_MOVE_ROLE_RESPONDER:
4861 l2cap_do_move_respond(chan, result);
4862 break;
4863 default:
4864 l2cap_do_move_cancel(chan, result);
4865 break;
4866 }
4867 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004868}
4869
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004870static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004871 struct l2cap_cmd_hdr *cmd,
4872 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004873{
4874 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004875 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004876 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004877 u16 icid = 0;
4878 u16 result = L2CAP_MR_NOT_ALLOWED;
4879
4880 if (cmd_len != sizeof(*req))
4881 return -EPROTO;
4882
4883 icid = le16_to_cpu(req->icid);
4884
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004885 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004886
Marcel Holtmann848566b2013-10-01 22:59:22 -07004887 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004888 return -EINVAL;
4889
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004890 chan = l2cap_get_chan_by_dcid(conn, icid);
4891 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004892 rsp.icid = cpu_to_le16(icid);
4893 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4894 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4895 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004896 return 0;
4897 }
4898
Mat Martineau1500109b2012-10-23 15:24:15 -07004899 chan->ident = cmd->ident;
4900
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004901 if (chan->scid < L2CAP_CID_DYN_START ||
4902 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4903 (chan->mode != L2CAP_MODE_ERTM &&
4904 chan->mode != L2CAP_MODE_STREAMING)) {
4905 result = L2CAP_MR_NOT_ALLOWED;
4906 goto send_move_response;
4907 }
4908
4909 if (chan->local_amp_id == req->dest_amp_id) {
4910 result = L2CAP_MR_SAME_ID;
4911 goto send_move_response;
4912 }
4913
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004914 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004915 struct hci_dev *hdev;
4916 hdev = hci_dev_get(req->dest_amp_id);
4917 if (!hdev || hdev->dev_type != HCI_AMP ||
4918 !test_bit(HCI_UP, &hdev->flags)) {
4919 if (hdev)
4920 hci_dev_put(hdev);
4921
4922 result = L2CAP_MR_BAD_ID;
4923 goto send_move_response;
4924 }
4925 hci_dev_put(hdev);
4926 }
4927
4928 /* Detect a move collision. Only send a collision response
4929 * if this side has "lost", otherwise proceed with the move.
4930 * The winner has the larger bd_addr.
4931 */
4932 if ((__chan_is_moving(chan) ||
4933 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07004934 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004935 result = L2CAP_MR_COLLISION;
4936 goto send_move_response;
4937 }
4938
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004939 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4940 l2cap_move_setup(chan);
4941 chan->move_id = req->dest_amp_id;
4942 icid = chan->dcid;
4943
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004944 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004945 /* Moving to BR/EDR */
4946 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4947 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4948 result = L2CAP_MR_PEND;
4949 } else {
4950 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4951 result = L2CAP_MR_SUCCESS;
4952 }
4953 } else {
4954 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4955 /* Placeholder - uncomment when amp functions are available */
4956 /*amp_accept_physical(chan, req->dest_amp_id);*/
4957 result = L2CAP_MR_PEND;
4958 }
4959
4960send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004961 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004962
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004963 l2cap_chan_unlock(chan);
4964
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004965 return 0;
4966}
4967
Mat Martineau5b155ef2012-10-23 15:24:14 -07004968static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4969{
4970 struct l2cap_chan *chan;
4971 struct hci_chan *hchan = NULL;
4972
4973 chan = l2cap_get_chan_by_scid(conn, icid);
4974 if (!chan) {
4975 l2cap_send_move_chan_cfm_icid(conn, icid);
4976 return;
4977 }
4978
4979 __clear_chan_timer(chan);
4980 if (result == L2CAP_MR_PEND)
4981 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4982
4983 switch (chan->move_state) {
4984 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4985 /* Move confirm will be sent when logical link
4986 * is complete.
4987 */
4988 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4989 break;
4990 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4991 if (result == L2CAP_MR_PEND) {
4992 break;
4993 } else if (test_bit(CONN_LOCAL_BUSY,
4994 &chan->conn_state)) {
4995 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4996 } else {
4997 /* Logical link is up or moving to BR/EDR,
4998 * proceed with move
4999 */
5000 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
5001 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5002 }
5003 break;
5004 case L2CAP_MOVE_WAIT_RSP:
5005 /* Moving to AMP */
5006 if (result == L2CAP_MR_SUCCESS) {
5007 /* Remote is ready, send confirm immediately
5008 * after logical link is ready
5009 */
5010 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5011 } else {
5012 /* Both logical link and move success
5013 * are required to confirm
5014 */
5015 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
5016 }
5017
5018 /* Placeholder - get hci_chan for logical link */
5019 if (!hchan) {
5020 /* Logical link not available */
5021 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5022 break;
5023 }
5024
5025 /* If the logical link is not yet connected, do not
5026 * send confirmation.
5027 */
5028 if (hchan->state != BT_CONNECTED)
5029 break;
5030
5031 /* Logical link is already ready to go */
5032
5033 chan->hs_hcon = hchan->conn;
5034 chan->hs_hcon->l2cap_data = chan->conn;
5035
5036 if (result == L2CAP_MR_SUCCESS) {
5037 /* Can confirm now */
5038 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5039 } else {
5040 /* Now only need move success
5041 * to confirm
5042 */
5043 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
5044 }
5045
5046 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5047 break;
5048 default:
5049 /* Any other amp move state means the move failed. */
5050 chan->move_id = chan->local_amp_id;
5051 l2cap_move_done(chan);
5052 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5053 }
5054
5055 l2cap_chan_unlock(chan);
5056}
5057
5058static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5059 u16 result)
5060{
5061 struct l2cap_chan *chan;
5062
5063 chan = l2cap_get_chan_by_ident(conn, ident);
5064 if (!chan) {
5065 /* Could not locate channel, icid is best guess */
5066 l2cap_send_move_chan_cfm_icid(conn, icid);
5067 return;
5068 }
5069
5070 __clear_chan_timer(chan);
5071
5072 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5073 if (result == L2CAP_MR_COLLISION) {
5074 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5075 } else {
5076 /* Cleanup - cancel move */
5077 chan->move_id = chan->local_amp_id;
5078 l2cap_move_done(chan);
5079 }
5080 }
5081
5082 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5083
5084 l2cap_chan_unlock(chan);
5085}
5086
5087static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5088 struct l2cap_cmd_hdr *cmd,
5089 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005090{
5091 struct l2cap_move_chan_rsp *rsp = data;
5092 u16 icid, result;
5093
5094 if (cmd_len != sizeof(*rsp))
5095 return -EPROTO;
5096
5097 icid = le16_to_cpu(rsp->icid);
5098 result = le16_to_cpu(rsp->result);
5099
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005100 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005101
Mat Martineau5b155ef2012-10-23 15:24:14 -07005102 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5103 l2cap_move_continue(conn, icid, result);
5104 else
5105 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005106
5107 return 0;
5108}
5109
Mat Martineau5f3847a2012-10-23 15:24:12 -07005110static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5111 struct l2cap_cmd_hdr *cmd,
5112 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005113{
5114 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005115 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005116 u16 icid, result;
5117
5118 if (cmd_len != sizeof(*cfm))
5119 return -EPROTO;
5120
5121 icid = le16_to_cpu(cfm->icid);
5122 result = le16_to_cpu(cfm->result);
5123
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005124 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005125
Mat Martineau5f3847a2012-10-23 15:24:12 -07005126 chan = l2cap_get_chan_by_dcid(conn, icid);
5127 if (!chan) {
5128 /* Spec requires a response even if the icid was not found */
5129 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5130 return 0;
5131 }
5132
5133 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5134 if (result == L2CAP_MC_CONFIRMED) {
5135 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005136 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005137 __release_logical_link(chan);
5138 } else {
5139 chan->move_id = chan->local_amp_id;
5140 }
5141
5142 l2cap_move_done(chan);
5143 }
5144
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005145 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5146
Mat Martineau5f3847a2012-10-23 15:24:12 -07005147 l2cap_chan_unlock(chan);
5148
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005149 return 0;
5150}
5151
5152static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005153 struct l2cap_cmd_hdr *cmd,
5154 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005155{
5156 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005157 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005158 u16 icid;
5159
5160 if (cmd_len != sizeof(*rsp))
5161 return -EPROTO;
5162
5163 icid = le16_to_cpu(rsp->icid);
5164
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005165 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005166
Mat Martineau3fd71a02012-10-23 15:24:16 -07005167 chan = l2cap_get_chan_by_scid(conn, icid);
5168 if (!chan)
5169 return 0;
5170
5171 __clear_chan_timer(chan);
5172
5173 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5174 chan->local_amp_id = chan->move_id;
5175
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005176 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005177 __release_logical_link(chan);
5178
5179 l2cap_move_done(chan);
5180 }
5181
5182 l2cap_chan_unlock(chan);
5183
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005184 return 0;
5185}
5186
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005187static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005188 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005189{
5190 u16 max_latency;
5191
5192 if (min > max || min < 6 || max > 3200)
5193 return -EINVAL;
5194
5195 if (to_multiplier < 10 || to_multiplier > 3200)
5196 return -EINVAL;
5197
5198 if (max >= to_multiplier * 8)
5199 return -EINVAL;
5200
5201 max_latency = (to_multiplier * 8 / max) - 1;
5202 if (latency > 499 || latency > max_latency)
5203 return -EINVAL;
5204
5205 return 0;
5206}
5207
5208static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005209 struct l2cap_cmd_hdr *cmd,
5210 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005211{
5212 struct hci_conn *hcon = conn->hcon;
5213 struct l2cap_conn_param_update_req *req;
5214 struct l2cap_conn_param_update_rsp rsp;
5215 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005216 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005217
5218 if (!(hcon->link_mode & HCI_LM_MASTER))
5219 return -EINVAL;
5220
5221 cmd_len = __le16_to_cpu(cmd->len);
5222 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5223 return -EPROTO;
5224
5225 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005226 min = __le16_to_cpu(req->min);
5227 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005228 latency = __le16_to_cpu(req->latency);
5229 to_multiplier = __le16_to_cpu(req->to_multiplier);
5230
5231 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 +01005232 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005233
5234 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005235
5236 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5237 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005238 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005239 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005240 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005241
5242 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005243 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005244
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005245 if (!err)
5246 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5247
Claudio Takahaside731152011-02-11 19:28:55 -02005248 return 0;
5249}
5250
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005251static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005252 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5253 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005254{
5255 int err = 0;
5256
5257 switch (cmd->code) {
5258 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005259 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005260 break;
5261
5262 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005263 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005264 break;
5265
5266 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005267 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005268 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005269 break;
5270
5271 case L2CAP_CONF_REQ:
5272 err = l2cap_config_req(conn, cmd, cmd_len, data);
5273 break;
5274
5275 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005276 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005277 break;
5278
5279 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005280 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005281 break;
5282
5283 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005284 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005285 break;
5286
5287 case L2CAP_ECHO_REQ:
5288 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5289 break;
5290
5291 case L2CAP_ECHO_RSP:
5292 break;
5293
5294 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005295 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005296 break;
5297
5298 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005299 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005300 break;
5301
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005302 case L2CAP_CREATE_CHAN_REQ:
5303 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5304 break;
5305
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005306 case L2CAP_MOVE_CHAN_REQ:
5307 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5308 break;
5309
5310 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005311 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005312 break;
5313
5314 case L2CAP_MOVE_CHAN_CFM:
5315 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5316 break;
5317
5318 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005319 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005320 break;
5321
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005322 default:
5323 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5324 err = -EINVAL;
5325 break;
5326 }
5327
5328 return err;
5329}
5330
5331static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005332 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005333{
5334 switch (cmd->code) {
5335 case L2CAP_COMMAND_REJ:
5336 return 0;
5337
5338 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005339 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005340
5341 case L2CAP_CONN_PARAM_UPDATE_RSP:
5342 return 0;
5343
5344 default:
5345 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5346 return -EINVAL;
5347 }
5348}
5349
Johan Hedberg7c2005d2013-09-16 13:05:16 +03005350static __le16 l2cap_err_to_reason(int err)
5351{
5352 switch (err) {
5353 case -EBADSLT:
5354 return __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
5355 case -EMSGSIZE:
5356 return __constant_cpu_to_le16(L2CAP_REJ_MTU_EXCEEDED);
5357 case -EINVAL:
5358 case -EPROTO:
5359 default:
5360 return __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
5361 }
5362}
5363
Johan Hedbergc5623552013-04-29 19:35:33 +03005364static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5365 struct sk_buff *skb)
5366{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005367 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005368 struct l2cap_cmd_hdr *cmd;
5369 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005370 int err;
5371
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005372 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005373 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005374
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005375 if (skb->len < L2CAP_CMD_HDR_SIZE)
5376 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005377
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005378 cmd = (void *) skb->data;
5379 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005380
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005381 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005382
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005383 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005384
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005385 if (len != skb->len || !cmd->ident) {
5386 BT_DBG("corrupted command");
5387 goto drop;
5388 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005389
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005390 err = l2cap_le_sig_cmd(conn, cmd, skb->data);
5391 if (err) {
5392 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005393
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005394 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005395
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005396 rej.reason = l2cap_err_to_reason(err);
5397 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5398 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005399 }
5400
Marcel Holtmann3b166292013-10-02 08:28:21 -07005401drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005402 kfree_skb(skb);
5403}
5404
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005405static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005406 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005407{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005408 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005409 u8 *data = skb->data;
5410 int len = skb->len;
5411 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005412 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005413
5414 l2cap_raw_recv(conn, skb);
5415
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005416 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005417 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005418
Linus Torvalds1da177e2005-04-16 15:20:36 -07005419 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005420 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005421 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5422 data += L2CAP_CMD_HDR_SIZE;
5423 len -= L2CAP_CMD_HDR_SIZE;
5424
Al Viro88219a02007-07-29 00:17:25 -07005425 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005426
Gustavo Padovan2d792812012-10-06 10:07:01 +01005427 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5428 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005429
Al Viro88219a02007-07-29 00:17:25 -07005430 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005431 BT_DBG("corrupted command");
5432 break;
5433 }
5434
Johan Hedbergc5623552013-04-29 19:35:33 +03005435 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005436 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005437 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005438
5439 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005440
Johan Hedberg7c2005d2013-09-16 13:05:16 +03005441 rej.reason = l2cap_err_to_reason(err);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005442 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5443 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005444 }
5445
Al Viro88219a02007-07-29 00:17:25 -07005446 data += cmd_len;
5447 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005448 }
5449
Marcel Holtmann3b166292013-10-02 08:28:21 -07005450drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005451 kfree_skb(skb);
5452}
5453
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005454static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005455{
5456 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005457 int hdr_size;
5458
5459 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5460 hdr_size = L2CAP_EXT_HDR_SIZE;
5461 else
5462 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005463
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005464 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005465 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005466 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5467 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5468
5469 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005470 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005471 }
5472 return 0;
5473}
5474
Mat Martineau6ea00482012-05-17 20:53:52 -07005475static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005476{
Mat Martineaue31f7632012-05-17 20:53:41 -07005477 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005478
Mat Martineaue31f7632012-05-17 20:53:41 -07005479 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005480
Mat Martineaue31f7632012-05-17 20:53:41 -07005481 memset(&control, 0, sizeof(control));
5482 control.sframe = 1;
5483 control.final = 1;
5484 control.reqseq = chan->buffer_seq;
5485 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005486
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005487 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005488 control.super = L2CAP_SUPER_RNR;
5489 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005490 }
5491
Mat Martineaue31f7632012-05-17 20:53:41 -07005492 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5493 chan->unacked_frames > 0)
5494 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005495
Mat Martineaue31f7632012-05-17 20:53:41 -07005496 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005497 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005498
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005499 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005500 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5501 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5502 * send it now.
5503 */
5504 control.super = L2CAP_SUPER_RR;
5505 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005506 }
5507}
5508
Gustavo Padovan2d792812012-10-06 10:07:01 +01005509static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5510 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005511{
Mat Martineau84084a32011-07-22 14:54:00 -07005512 /* skb->len reflects data in skb as well as all fragments
5513 * skb->data_len reflects only data in fragments
5514 */
5515 if (!skb_has_frag_list(skb))
5516 skb_shinfo(skb)->frag_list = new_frag;
5517
5518 new_frag->next = NULL;
5519
5520 (*last_frag)->next = new_frag;
5521 *last_frag = new_frag;
5522
5523 skb->len += new_frag->len;
5524 skb->data_len += new_frag->len;
5525 skb->truesize += new_frag->truesize;
5526}
5527
Mat Martineau4b51dae92012-05-17 20:53:37 -07005528static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5529 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005530{
5531 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005532
Mat Martineau4b51dae92012-05-17 20:53:37 -07005533 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005534 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005535 if (chan->sdu)
5536 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005537
Gustavo Padovan80b98022012-05-27 22:27:51 -03005538 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005539 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005540
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005541 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005542 if (chan->sdu)
5543 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005544
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005545 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005546 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005547
Mat Martineau84084a32011-07-22 14:54:00 -07005548 if (chan->sdu_len > chan->imtu) {
5549 err = -EMSGSIZE;
5550 break;
5551 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005552
Mat Martineau84084a32011-07-22 14:54:00 -07005553 if (skb->len >= chan->sdu_len)
5554 break;
5555
5556 chan->sdu = skb;
5557 chan->sdu_last_frag = skb;
5558
5559 skb = NULL;
5560 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005561 break;
5562
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005563 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005564 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005565 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005566
Mat Martineau84084a32011-07-22 14:54:00 -07005567 append_skb_frag(chan->sdu, skb,
5568 &chan->sdu_last_frag);
5569 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005570
Mat Martineau84084a32011-07-22 14:54:00 -07005571 if (chan->sdu->len >= chan->sdu_len)
5572 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005573
Mat Martineau84084a32011-07-22 14:54:00 -07005574 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005575 break;
5576
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005577 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005578 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005579 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005580
Mat Martineau84084a32011-07-22 14:54:00 -07005581 append_skb_frag(chan->sdu, skb,
5582 &chan->sdu_last_frag);
5583 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005584
Mat Martineau84084a32011-07-22 14:54:00 -07005585 if (chan->sdu->len != chan->sdu_len)
5586 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005587
Gustavo Padovan80b98022012-05-27 22:27:51 -03005588 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005589
Mat Martineau84084a32011-07-22 14:54:00 -07005590 if (!err) {
5591 /* Reassembly complete */
5592 chan->sdu = NULL;
5593 chan->sdu_last_frag = NULL;
5594 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005595 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005596 break;
5597 }
5598
Mat Martineau84084a32011-07-22 14:54:00 -07005599 if (err) {
5600 kfree_skb(skb);
5601 kfree_skb(chan->sdu);
5602 chan->sdu = NULL;
5603 chan->sdu_last_frag = NULL;
5604 chan->sdu_len = 0;
5605 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005606
Mat Martineau84084a32011-07-22 14:54:00 -07005607 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005608}
5609
Mat Martineau32b32732012-10-23 15:24:11 -07005610static int l2cap_resegment(struct l2cap_chan *chan)
5611{
5612 /* Placeholder */
5613 return 0;
5614}
5615
Mat Martineaue3281402011-07-07 09:39:02 -07005616void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132eb2010-06-21 19:39:50 -03005617{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005618 u8 event;
5619
5620 if (chan->mode != L2CAP_MODE_ERTM)
5621 return;
5622
5623 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005624 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005625}
5626
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005627static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5628{
Mat Martineau63838722012-05-17 20:53:45 -07005629 int err = 0;
5630 /* Pass sequential frames to l2cap_reassemble_sdu()
5631 * until a gap is encountered.
5632 */
5633
5634 BT_DBG("chan %p", chan);
5635
5636 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5637 struct sk_buff *skb;
5638 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5639 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5640
5641 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5642
5643 if (!skb)
5644 break;
5645
5646 skb_unlink(skb, &chan->srej_q);
5647 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5648 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5649 if (err)
5650 break;
5651 }
5652
5653 if (skb_queue_empty(&chan->srej_q)) {
5654 chan->rx_state = L2CAP_RX_STATE_RECV;
5655 l2cap_send_ack(chan);
5656 }
5657
5658 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005659}
5660
5661static void l2cap_handle_srej(struct l2cap_chan *chan,
5662 struct l2cap_ctrl *control)
5663{
Mat Martineauf80842a2012-05-17 20:53:46 -07005664 struct sk_buff *skb;
5665
5666 BT_DBG("chan %p, control %p", chan, control);
5667
5668 if (control->reqseq == chan->next_tx_seq) {
5669 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005670 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005671 return;
5672 }
5673
5674 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5675
5676 if (skb == NULL) {
5677 BT_DBG("Seq %d not available for retransmission",
5678 control->reqseq);
5679 return;
5680 }
5681
5682 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5683 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005684 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005685 return;
5686 }
5687
5688 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5689
5690 if (control->poll) {
5691 l2cap_pass_to_tx(chan, control);
5692
5693 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5694 l2cap_retransmit(chan, control);
5695 l2cap_ertm_send(chan);
5696
5697 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5698 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5699 chan->srej_save_reqseq = control->reqseq;
5700 }
5701 } else {
5702 l2cap_pass_to_tx_fbit(chan, control);
5703
5704 if (control->final) {
5705 if (chan->srej_save_reqseq != control->reqseq ||
5706 !test_and_clear_bit(CONN_SREJ_ACT,
5707 &chan->conn_state))
5708 l2cap_retransmit(chan, control);
5709 } else {
5710 l2cap_retransmit(chan, control);
5711 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5712 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5713 chan->srej_save_reqseq = control->reqseq;
5714 }
5715 }
5716 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005717}
5718
5719static void l2cap_handle_rej(struct l2cap_chan *chan,
5720 struct l2cap_ctrl *control)
5721{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005722 struct sk_buff *skb;
5723
5724 BT_DBG("chan %p, control %p", chan, control);
5725
5726 if (control->reqseq == chan->next_tx_seq) {
5727 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005728 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005729 return;
5730 }
5731
5732 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5733
5734 if (chan->max_tx && skb &&
5735 bt_cb(skb)->control.retries >= chan->max_tx) {
5736 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005737 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005738 return;
5739 }
5740
5741 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5742
5743 l2cap_pass_to_tx(chan, control);
5744
5745 if (control->final) {
5746 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5747 l2cap_retransmit_all(chan, control);
5748 } else {
5749 l2cap_retransmit_all(chan, control);
5750 l2cap_ertm_send(chan);
5751 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5752 set_bit(CONN_REJ_ACT, &chan->conn_state);
5753 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005754}
5755
Mat Martineau4b51dae92012-05-17 20:53:37 -07005756static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5757{
5758 BT_DBG("chan %p, txseq %d", chan, txseq);
5759
5760 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5761 chan->expected_tx_seq);
5762
5763 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5764 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005765 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005766 /* See notes below regarding "double poll" and
5767 * invalid packets.
5768 */
5769 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5770 BT_DBG("Invalid/Ignore - after SREJ");
5771 return L2CAP_TXSEQ_INVALID_IGNORE;
5772 } else {
5773 BT_DBG("Invalid - in window after SREJ sent");
5774 return L2CAP_TXSEQ_INVALID;
5775 }
5776 }
5777
5778 if (chan->srej_list.head == txseq) {
5779 BT_DBG("Expected SREJ");
5780 return L2CAP_TXSEQ_EXPECTED_SREJ;
5781 }
5782
5783 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5784 BT_DBG("Duplicate SREJ - txseq already stored");
5785 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5786 }
5787
5788 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5789 BT_DBG("Unexpected SREJ - not requested");
5790 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5791 }
5792 }
5793
5794 if (chan->expected_tx_seq == txseq) {
5795 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5796 chan->tx_win) {
5797 BT_DBG("Invalid - txseq outside tx window");
5798 return L2CAP_TXSEQ_INVALID;
5799 } else {
5800 BT_DBG("Expected");
5801 return L2CAP_TXSEQ_EXPECTED;
5802 }
5803 }
5804
5805 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005806 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005807 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5808 return L2CAP_TXSEQ_DUPLICATE;
5809 }
5810
5811 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5812 /* A source of invalid packets is a "double poll" condition,
5813 * where delays cause us to send multiple poll packets. If
5814 * the remote stack receives and processes both polls,
5815 * sequence numbers can wrap around in such a way that a
5816 * resent frame has a sequence number that looks like new data
5817 * with a sequence gap. This would trigger an erroneous SREJ
5818 * request.
5819 *
5820 * Fortunately, this is impossible with a tx window that's
5821 * less than half of the maximum sequence number, which allows
5822 * invalid frames to be safely ignored.
5823 *
5824 * With tx window sizes greater than half of the tx window
5825 * maximum, the frame is invalid and cannot be ignored. This
5826 * causes a disconnect.
5827 */
5828
5829 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5830 BT_DBG("Invalid/Ignore - txseq outside tx window");
5831 return L2CAP_TXSEQ_INVALID_IGNORE;
5832 } else {
5833 BT_DBG("Invalid - txseq outside tx window");
5834 return L2CAP_TXSEQ_INVALID;
5835 }
5836 } else {
5837 BT_DBG("Unexpected - txseq indicates missing frames");
5838 return L2CAP_TXSEQ_UNEXPECTED;
5839 }
5840}
5841
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005842static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5843 struct l2cap_ctrl *control,
5844 struct sk_buff *skb, u8 event)
5845{
5846 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005847 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005848
5849 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5850 event);
5851
5852 switch (event) {
5853 case L2CAP_EV_RECV_IFRAME:
5854 switch (l2cap_classify_txseq(chan, control->txseq)) {
5855 case L2CAP_TXSEQ_EXPECTED:
5856 l2cap_pass_to_tx(chan, control);
5857
5858 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5859 BT_DBG("Busy, discarding expected seq %d",
5860 control->txseq);
5861 break;
5862 }
5863
5864 chan->expected_tx_seq = __next_seq(chan,
5865 control->txseq);
5866
5867 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005868 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005869
5870 err = l2cap_reassemble_sdu(chan, skb, control);
5871 if (err)
5872 break;
5873
5874 if (control->final) {
5875 if (!test_and_clear_bit(CONN_REJ_ACT,
5876 &chan->conn_state)) {
5877 control->final = 0;
5878 l2cap_retransmit_all(chan, control);
5879 l2cap_ertm_send(chan);
5880 }
5881 }
5882
5883 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5884 l2cap_send_ack(chan);
5885 break;
5886 case L2CAP_TXSEQ_UNEXPECTED:
5887 l2cap_pass_to_tx(chan, control);
5888
5889 /* Can't issue SREJ frames in the local busy state.
5890 * Drop this frame, it will be seen as missing
5891 * when local busy is exited.
5892 */
5893 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5894 BT_DBG("Busy, discarding unexpected seq %d",
5895 control->txseq);
5896 break;
5897 }
5898
5899 /* There was a gap in the sequence, so an SREJ
5900 * must be sent for each missing frame. The
5901 * current frame is stored for later use.
5902 */
5903 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005904 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005905 BT_DBG("Queued %p (queue len %d)", skb,
5906 skb_queue_len(&chan->srej_q));
5907
5908 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5909 l2cap_seq_list_clear(&chan->srej_list);
5910 l2cap_send_srej(chan, control->txseq);
5911
5912 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5913 break;
5914 case L2CAP_TXSEQ_DUPLICATE:
5915 l2cap_pass_to_tx(chan, control);
5916 break;
5917 case L2CAP_TXSEQ_INVALID_IGNORE:
5918 break;
5919 case L2CAP_TXSEQ_INVALID:
5920 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005921 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005922 break;
5923 }
5924 break;
5925 case L2CAP_EV_RECV_RR:
5926 l2cap_pass_to_tx(chan, control);
5927 if (control->final) {
5928 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5929
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005930 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5931 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005932 control->final = 0;
5933 l2cap_retransmit_all(chan, control);
5934 }
5935
5936 l2cap_ertm_send(chan);
5937 } else if (control->poll) {
5938 l2cap_send_i_or_rr_or_rnr(chan);
5939 } else {
5940 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5941 &chan->conn_state) &&
5942 chan->unacked_frames)
5943 __set_retrans_timer(chan);
5944
5945 l2cap_ertm_send(chan);
5946 }
5947 break;
5948 case L2CAP_EV_RECV_RNR:
5949 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5950 l2cap_pass_to_tx(chan, control);
5951 if (control && control->poll) {
5952 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5953 l2cap_send_rr_or_rnr(chan, 0);
5954 }
5955 __clear_retrans_timer(chan);
5956 l2cap_seq_list_clear(&chan->retrans_list);
5957 break;
5958 case L2CAP_EV_RECV_REJ:
5959 l2cap_handle_rej(chan, control);
5960 break;
5961 case L2CAP_EV_RECV_SREJ:
5962 l2cap_handle_srej(chan, control);
5963 break;
5964 default:
5965 break;
5966 }
5967
5968 if (skb && !skb_in_use) {
5969 BT_DBG("Freeing %p", skb);
5970 kfree_skb(skb);
5971 }
5972
5973 return err;
5974}
5975
5976static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5977 struct l2cap_ctrl *control,
5978 struct sk_buff *skb, u8 event)
5979{
5980 int err = 0;
5981 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005982 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005983
5984 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5985 event);
5986
5987 switch (event) {
5988 case L2CAP_EV_RECV_IFRAME:
5989 switch (l2cap_classify_txseq(chan, txseq)) {
5990 case L2CAP_TXSEQ_EXPECTED:
5991 /* Keep frame for reassembly later */
5992 l2cap_pass_to_tx(chan, control);
5993 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005994 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005995 BT_DBG("Queued %p (queue len %d)", skb,
5996 skb_queue_len(&chan->srej_q));
5997
5998 chan->expected_tx_seq = __next_seq(chan, txseq);
5999 break;
6000 case L2CAP_TXSEQ_EXPECTED_SREJ:
6001 l2cap_seq_list_pop(&chan->srej_list);
6002
6003 l2cap_pass_to_tx(chan, control);
6004 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006005 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006006 BT_DBG("Queued %p (queue len %d)", skb,
6007 skb_queue_len(&chan->srej_q));
6008
6009 err = l2cap_rx_queued_iframes(chan);
6010 if (err)
6011 break;
6012
6013 break;
6014 case L2CAP_TXSEQ_UNEXPECTED:
6015 /* Got a frame that can't be reassembled yet.
6016 * Save it for later, and send SREJs to cover
6017 * the missing frames.
6018 */
6019 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006020 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006021 BT_DBG("Queued %p (queue len %d)", skb,
6022 skb_queue_len(&chan->srej_q));
6023
6024 l2cap_pass_to_tx(chan, control);
6025 l2cap_send_srej(chan, control->txseq);
6026 break;
6027 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
6028 /* This frame was requested with an SREJ, but
6029 * some expected retransmitted frames are
6030 * missing. Request retransmission of missing
6031 * SREJ'd frames.
6032 */
6033 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006034 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006035 BT_DBG("Queued %p (queue len %d)", skb,
6036 skb_queue_len(&chan->srej_q));
6037
6038 l2cap_pass_to_tx(chan, control);
6039 l2cap_send_srej_list(chan, control->txseq);
6040 break;
6041 case L2CAP_TXSEQ_DUPLICATE_SREJ:
6042 /* We've already queued this frame. Drop this copy. */
6043 l2cap_pass_to_tx(chan, control);
6044 break;
6045 case L2CAP_TXSEQ_DUPLICATE:
6046 /* Expecting a later sequence number, so this frame
6047 * was already received. Ignore it completely.
6048 */
6049 break;
6050 case L2CAP_TXSEQ_INVALID_IGNORE:
6051 break;
6052 case L2CAP_TXSEQ_INVALID:
6053 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006054 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006055 break;
6056 }
6057 break;
6058 case L2CAP_EV_RECV_RR:
6059 l2cap_pass_to_tx(chan, control);
6060 if (control->final) {
6061 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6062
6063 if (!test_and_clear_bit(CONN_REJ_ACT,
6064 &chan->conn_state)) {
6065 control->final = 0;
6066 l2cap_retransmit_all(chan, control);
6067 }
6068
6069 l2cap_ertm_send(chan);
6070 } else if (control->poll) {
6071 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6072 &chan->conn_state) &&
6073 chan->unacked_frames) {
6074 __set_retrans_timer(chan);
6075 }
6076
6077 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6078 l2cap_send_srej_tail(chan);
6079 } else {
6080 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6081 &chan->conn_state) &&
6082 chan->unacked_frames)
6083 __set_retrans_timer(chan);
6084
6085 l2cap_send_ack(chan);
6086 }
6087 break;
6088 case L2CAP_EV_RECV_RNR:
6089 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6090 l2cap_pass_to_tx(chan, control);
6091 if (control->poll) {
6092 l2cap_send_srej_tail(chan);
6093 } else {
6094 struct l2cap_ctrl rr_control;
6095 memset(&rr_control, 0, sizeof(rr_control));
6096 rr_control.sframe = 1;
6097 rr_control.super = L2CAP_SUPER_RR;
6098 rr_control.reqseq = chan->buffer_seq;
6099 l2cap_send_sframe(chan, &rr_control);
6100 }
6101
6102 break;
6103 case L2CAP_EV_RECV_REJ:
6104 l2cap_handle_rej(chan, control);
6105 break;
6106 case L2CAP_EV_RECV_SREJ:
6107 l2cap_handle_srej(chan, control);
6108 break;
6109 }
6110
6111 if (skb && !skb_in_use) {
6112 BT_DBG("Freeing %p", skb);
6113 kfree_skb(skb);
6114 }
6115
6116 return err;
6117}
6118
Mat Martineau32b32732012-10-23 15:24:11 -07006119static int l2cap_finish_move(struct l2cap_chan *chan)
6120{
6121 BT_DBG("chan %p", chan);
6122
6123 chan->rx_state = L2CAP_RX_STATE_RECV;
6124
6125 if (chan->hs_hcon)
6126 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6127 else
6128 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6129
6130 return l2cap_resegment(chan);
6131}
6132
6133static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6134 struct l2cap_ctrl *control,
6135 struct sk_buff *skb, u8 event)
6136{
6137 int err;
6138
6139 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6140 event);
6141
6142 if (!control->poll)
6143 return -EPROTO;
6144
6145 l2cap_process_reqseq(chan, control->reqseq);
6146
6147 if (!skb_queue_empty(&chan->tx_q))
6148 chan->tx_send_head = skb_peek(&chan->tx_q);
6149 else
6150 chan->tx_send_head = NULL;
6151
6152 /* Rewind next_tx_seq to the point expected
6153 * by the receiver.
6154 */
6155 chan->next_tx_seq = control->reqseq;
6156 chan->unacked_frames = 0;
6157
6158 err = l2cap_finish_move(chan);
6159 if (err)
6160 return err;
6161
6162 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6163 l2cap_send_i_or_rr_or_rnr(chan);
6164
6165 if (event == L2CAP_EV_RECV_IFRAME)
6166 return -EPROTO;
6167
6168 return l2cap_rx_state_recv(chan, control, NULL, event);
6169}
6170
6171static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6172 struct l2cap_ctrl *control,
6173 struct sk_buff *skb, u8 event)
6174{
6175 int err;
6176
6177 if (!control->final)
6178 return -EPROTO;
6179
6180 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6181
6182 chan->rx_state = L2CAP_RX_STATE_RECV;
6183 l2cap_process_reqseq(chan, control->reqseq);
6184
6185 if (!skb_queue_empty(&chan->tx_q))
6186 chan->tx_send_head = skb_peek(&chan->tx_q);
6187 else
6188 chan->tx_send_head = NULL;
6189
6190 /* Rewind next_tx_seq to the point expected
6191 * by the receiver.
6192 */
6193 chan->next_tx_seq = control->reqseq;
6194 chan->unacked_frames = 0;
6195
6196 if (chan->hs_hcon)
6197 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6198 else
6199 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6200
6201 err = l2cap_resegment(chan);
6202
6203 if (!err)
6204 err = l2cap_rx_state_recv(chan, control, skb, event);
6205
6206 return err;
6207}
6208
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006209static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6210{
6211 /* Make sure reqseq is for a packet that has been sent but not acked */
6212 u16 unacked;
6213
6214 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6215 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6216}
6217
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006218static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6219 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006220{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006221 int err = 0;
6222
6223 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6224 control, skb, event, chan->rx_state);
6225
6226 if (__valid_reqseq(chan, control->reqseq)) {
6227 switch (chan->rx_state) {
6228 case L2CAP_RX_STATE_RECV:
6229 err = l2cap_rx_state_recv(chan, control, skb, event);
6230 break;
6231 case L2CAP_RX_STATE_SREJ_SENT:
6232 err = l2cap_rx_state_srej_sent(chan, control, skb,
6233 event);
6234 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006235 case L2CAP_RX_STATE_WAIT_P:
6236 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6237 break;
6238 case L2CAP_RX_STATE_WAIT_F:
6239 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6240 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006241 default:
6242 /* shut it down */
6243 break;
6244 }
6245 } else {
6246 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6247 control->reqseq, chan->next_tx_seq,
6248 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006249 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006250 }
6251
6252 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006253}
6254
6255static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6256 struct sk_buff *skb)
6257{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006258 int err = 0;
6259
6260 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6261 chan->rx_state);
6262
6263 if (l2cap_classify_txseq(chan, control->txseq) ==
6264 L2CAP_TXSEQ_EXPECTED) {
6265 l2cap_pass_to_tx(chan, control);
6266
6267 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6268 __next_seq(chan, chan->buffer_seq));
6269
6270 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6271
6272 l2cap_reassemble_sdu(chan, skb, control);
6273 } else {
6274 if (chan->sdu) {
6275 kfree_skb(chan->sdu);
6276 chan->sdu = NULL;
6277 }
6278 chan->sdu_last_frag = NULL;
6279 chan->sdu_len = 0;
6280
6281 if (skb) {
6282 BT_DBG("Freeing %p", skb);
6283 kfree_skb(skb);
6284 }
6285 }
6286
6287 chan->last_acked_seq = control->txseq;
6288 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6289
6290 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006291}
6292
6293static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6294{
6295 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6296 u16 len;
6297 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006298
Mat Martineaub76bbd62012-04-11 10:48:43 -07006299 __unpack_control(chan, skb);
6300
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006301 len = skb->len;
6302
6303 /*
6304 * We can just drop the corrupted I-frame here.
6305 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006306 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006307 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006308 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006309 goto drop;
6310
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006311 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006312 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006313
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006314 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006315 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006316
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006317 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006318 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006319 goto drop;
6320 }
6321
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006322 if (!control->sframe) {
6323 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006324
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006325 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6326 control->sar, control->reqseq, control->final,
6327 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006328
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006329 /* Validate F-bit - F=0 always valid, F=1 only
6330 * valid in TX WAIT_F
6331 */
6332 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006333 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006334
6335 if (chan->mode != L2CAP_MODE_STREAMING) {
6336 event = L2CAP_EV_RECV_IFRAME;
6337 err = l2cap_rx(chan, control, skb, event);
6338 } else {
6339 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006340 }
6341
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006342 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006343 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006344 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006345 const u8 rx_func_to_event[4] = {
6346 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6347 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6348 };
6349
6350 /* Only I-frames are expected in streaming mode */
6351 if (chan->mode == L2CAP_MODE_STREAMING)
6352 goto drop;
6353
6354 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6355 control->reqseq, control->final, control->poll,
6356 control->super);
6357
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006358 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006359 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006360 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006361 goto drop;
6362 }
6363
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006364 /* Validate F and P bits */
6365 if (control->final && (control->poll ||
6366 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6367 goto drop;
6368
6369 event = rx_func_to_event[control->super];
6370 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006371 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006372 }
6373
6374 return 0;
6375
6376drop:
6377 kfree_skb(skb);
6378 return 0;
6379}
6380
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006381static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6382 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006383{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006384 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006385
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006386 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006387 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006388 if (cid == L2CAP_CID_A2MP) {
6389 chan = a2mp_channel_create(conn, skb);
6390 if (!chan) {
6391 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006392 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006393 }
6394
6395 l2cap_chan_lock(chan);
6396 } else {
6397 BT_DBG("unknown cid 0x%4.4x", cid);
6398 /* Drop packet and return */
6399 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006400 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006401 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006402 }
6403
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006404 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006405
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006406 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006407 goto drop;
6408
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006409 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006410 case L2CAP_MODE_BASIC:
6411 /* If socket recv buffers overflows we drop data here
6412 * which is *bad* because L2CAP has to be reliable.
6413 * But we don't have any other choice. L2CAP doesn't
6414 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006415
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006416 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006417 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006418
Gustavo Padovan80b98022012-05-27 22:27:51 -03006419 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006420 goto done;
6421 break;
6422
6423 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006424 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006425 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006426 goto done;
6427
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006428 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006429 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006430 break;
6431 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006432
6433drop:
6434 kfree_skb(skb);
6435
6436done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006437 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006438}
6439
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006440static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6441 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006442{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006443 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006444 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006445
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006446 if (hcon->type != ACL_LINK)
6447 goto drop;
6448
Marcel Holtmann6f59b902013-10-13 05:24:01 -07006449 chan = l2cap_global_chan_by_psm(0, psm, &conn->hcon->src,
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07006450 &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006451 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006452 goto drop;
6453
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006454 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006455
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006456 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006457 goto drop;
6458
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006459 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006460 goto drop;
6461
Gustavo Padovan80b98022012-05-27 22:27:51 -03006462 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006463 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006464
6465drop:
6466 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006467}
6468
Marcel Holtmann72f78352013-04-23 00:59:00 -07006469static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006470 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006471{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006472 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006473 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006474
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006475 if (hcon->type != LE_LINK)
6476 goto drop;
6477
Johan Hedbergaf1c0132013-04-29 19:35:42 +03006478 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann6f59b902013-10-13 05:24:01 -07006479 &conn->hcon->src, &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006480 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006481 goto drop;
6482
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006483 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006484
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006485 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006486 goto drop;
6487
Gustavo Padovan80b98022012-05-27 22:27:51 -03006488 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006489 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006490
6491drop:
6492 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006493}
6494
Linus Torvalds1da177e2005-04-16 15:20:36 -07006495static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6496{
6497 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006498 u16 cid, len;
6499 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006500
6501 skb_pull(skb, L2CAP_HDR_SIZE);
6502 cid = __le16_to_cpu(lh->cid);
6503 len = __le16_to_cpu(lh->len);
6504
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006505 if (len != skb->len) {
6506 kfree_skb(skb);
6507 return;
6508 }
6509
Linus Torvalds1da177e2005-04-16 15:20:36 -07006510 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6511
6512 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006513 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006514 l2cap_sig_channel(conn, skb);
6515 break;
6516
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006517 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006518 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006519 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006520 l2cap_conless_channel(conn, psm, skb);
6521 break;
6522
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006523 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006524 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006525 break;
6526
Marcel Holtmanna2877622013-10-02 23:46:54 -07006527 case L2CAP_CID_LE_SIGNALING:
6528 l2cap_le_sig_channel(conn, skb);
6529 break;
6530
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006531 case L2CAP_CID_SMP:
6532 if (smp_sig_channel(conn, skb))
6533 l2cap_conn_del(conn->hcon, EACCES);
6534 break;
6535
Linus Torvalds1da177e2005-04-16 15:20:36 -07006536 default:
6537 l2cap_data_channel(conn, cid, skb);
6538 break;
6539 }
6540}
6541
6542/* ---- L2CAP interface with lower layer (HCI) ---- */
6543
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006544int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006545{
6546 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006547 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006548
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006549 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006550
6551 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006552 read_lock(&chan_list_lock);
6553 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006554 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006555 continue;
6556
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006557 if (!bacmp(&c->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006558 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006559 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006560 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006561 exact++;
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006562 } else if (!bacmp(&c->src, BDADDR_ANY)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006563 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006564 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006565 lm2 |= HCI_LM_MASTER;
6566 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006567 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006568 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006569
6570 return exact ? lm1 : lm2;
6571}
6572
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006573void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006574{
Marcel Holtmann01394182006-07-03 10:02:46 +02006575 struct l2cap_conn *conn;
6576
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006577 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006578
Linus Torvalds1da177e2005-04-16 15:20:36 -07006579 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006580 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006581 if (conn)
6582 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006583 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006584 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006585 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006586}
6587
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006588int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006589{
6590 struct l2cap_conn *conn = hcon->l2cap_data;
6591
6592 BT_DBG("hcon %p", hcon);
6593
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006594 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006595 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006596 return conn->disc_reason;
6597}
6598
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006599void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006600{
6601 BT_DBG("hcon %p reason %d", hcon, reason);
6602
Joe Perchese1750722011-06-29 18:18:29 -07006603 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006604}
6605
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006606static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006607{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006608 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006609 return;
6610
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006611 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006612 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006613 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006614 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006615 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006616 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006617 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006618 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006619 }
6620}
6621
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006622int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006623{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006624 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006625 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006626
Marcel Holtmann01394182006-07-03 10:02:46 +02006627 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006628 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006629
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006630 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006631
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006632 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306633 if (!status && encrypt)
6634 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006635 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006636 }
6637
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006638 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006639
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006640 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006641 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006642
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006643 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6644 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006645
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006646 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6647 l2cap_chan_unlock(chan);
6648 continue;
6649 }
6650
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006651 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006652 if (!status && encrypt) {
6653 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006654 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006655 }
6656
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006657 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006658 continue;
6659 }
6660
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006661 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006662 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006663 continue;
6664 }
6665
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006666 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006667 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03006668 struct sock *sk = chan->sk;
6669
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006670 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03006671 sk->sk_state_change(sk);
6672
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006673 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006674 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006675 continue;
6676 }
6677
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006678 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006679 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006680 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006681 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006682 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006683 }
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006684 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006685 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006686 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006687 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006688
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006689 lock_sock(sk);
6690
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006691 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006692 if (test_bit(BT_SK_DEFER_SETUP,
6693 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006694 res = L2CAP_CR_PEND;
6695 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006696 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006697 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006698 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006699 res = L2CAP_CR_SUCCESS;
6700 stat = L2CAP_CS_NO_INFO;
6701 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006702 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006703 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006704 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006705 res = L2CAP_CR_SEC_BLOCK;
6706 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006707 }
6708
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006709 release_sock(sk);
6710
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006711 rsp.scid = cpu_to_le16(chan->dcid);
6712 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006713 rsp.result = cpu_to_le16(res);
6714 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006715 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006716 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006717
6718 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6719 res == L2CAP_CR_SUCCESS) {
6720 char buf[128];
6721 set_bit(CONF_REQ_SENT, &chan->conf_state);
6722 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6723 L2CAP_CONF_REQ,
6724 l2cap_build_conf_req(chan, buf),
6725 buf);
6726 chan->num_conf_req++;
6727 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006728 }
6729
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006730 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006731 }
6732
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006733 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006734
Linus Torvalds1da177e2005-04-16 15:20:36 -07006735 return 0;
6736}
6737
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006738int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006739{
6740 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006741 struct l2cap_hdr *hdr;
6742 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006743
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006744 /* For AMP controller do not create l2cap conn */
6745 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6746 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006747
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006748 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006749 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006750
6751 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006752 goto drop;
6753
6754 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6755
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006756 switch (flags) {
6757 case ACL_START:
6758 case ACL_START_NO_FLUSH:
6759 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006760 if (conn->rx_len) {
6761 BT_ERR("Unexpected start frame (len %d)", skb->len);
6762 kfree_skb(conn->rx_skb);
6763 conn->rx_skb = NULL;
6764 conn->rx_len = 0;
6765 l2cap_conn_unreliable(conn, ECOMM);
6766 }
6767
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006768 /* Start fragment always begin with Basic L2CAP header */
6769 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006770 BT_ERR("Frame is too short (len %d)", skb->len);
6771 l2cap_conn_unreliable(conn, ECOMM);
6772 goto drop;
6773 }
6774
6775 hdr = (struct l2cap_hdr *) skb->data;
6776 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6777
6778 if (len == skb->len) {
6779 /* Complete frame received */
6780 l2cap_recv_frame(conn, skb);
6781 return 0;
6782 }
6783
6784 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6785
6786 if (skb->len > len) {
6787 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006788 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006789 l2cap_conn_unreliable(conn, ECOMM);
6790 goto drop;
6791 }
6792
6793 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006794 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006795 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006796 goto drop;
6797
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006798 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006799 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006800 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006801 break;
6802
6803 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006804 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6805
6806 if (!conn->rx_len) {
6807 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6808 l2cap_conn_unreliable(conn, ECOMM);
6809 goto drop;
6810 }
6811
6812 if (skb->len > conn->rx_len) {
6813 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006814 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006815 kfree_skb(conn->rx_skb);
6816 conn->rx_skb = NULL;
6817 conn->rx_len = 0;
6818 l2cap_conn_unreliable(conn, ECOMM);
6819 goto drop;
6820 }
6821
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006822 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006823 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006824 conn->rx_len -= skb->len;
6825
6826 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006827 /* Complete frame received. l2cap_recv_frame
6828 * takes ownership of the skb so set the global
6829 * rx_skb pointer to NULL first.
6830 */
6831 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006832 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006833 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006834 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006835 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006836 }
6837
6838drop:
6839 kfree_skb(skb);
6840 return 0;
6841}
6842
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006843static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006844{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006845 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006846
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006847 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006848
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006849 list_for_each_entry(c, &chan_list, global_l) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006850 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 -07006851 &c->src, &c->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006852 c->state, __le16_to_cpu(c->psm),
6853 c->scid, c->dcid, c->imtu, c->omtu,
6854 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006855 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006856
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006857 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006858
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006859 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006860}
6861
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006862static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6863{
6864 return single_open(file, l2cap_debugfs_show, inode->i_private);
6865}
6866
6867static const struct file_operations l2cap_debugfs_fops = {
6868 .open = l2cap_debugfs_open,
6869 .read = seq_read,
6870 .llseek = seq_lseek,
6871 .release = single_release,
6872};
6873
6874static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006875
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006876int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006877{
6878 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006879
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006880 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006881 if (err < 0)
6882 return err;
6883
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006884 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006885 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6886 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006887 if (!l2cap_debugfs)
6888 BT_ERR("Failed to create L2CAP debug file");
6889 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006890
Linus Torvalds1da177e2005-04-16 15:20:36 -07006891 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006892}
6893
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006894void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006895{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006896 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006897 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006898}
6899
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006900module_param(disable_ertm, bool, 0644);
6901MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");