blob: 6e6f308af036da34bffc7298d007eb718e9644f3 [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
Johan Hedbergf15b8ec2013-12-03 15:08:25 +020052static u16 le_max_credits = L2CAP_LE_MAX_CREDITS;
53static u16 le_default_mps = L2CAP_LE_DEFAULT_MPS;
54
Linus Torvalds1da177e2005-04-16 15:20:36 -070055static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010056 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030057static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010058 void *data);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -030059static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +020060static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070061
Gustavo Padovand6603662012-05-21 13:58:22 -030062static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010063 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070064
Marcel Holtmann4f1654e2013-10-13 08:50:41 -070065static inline __u8 bdaddr_type(struct hci_conn *hcon, __u8 type)
66{
67 if (hcon->type == LE_LINK) {
68 if (type == ADDR_LE_DEV_PUBLIC)
69 return BDADDR_LE_PUBLIC;
70 else
71 return BDADDR_LE_RANDOM;
72 }
73
74 return BDADDR_BREDR;
75}
76
Marcel Holtmann01394182006-07-03 10:02:46 +020077/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030078
Gustavo Padovan2d792812012-10-06 10:07:01 +010079static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
80 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020081{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020082 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030083
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020084 list_for_each_entry(c, &conn->chan_l, list) {
85 if (c->dcid == cid)
86 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020087 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020088 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020089}
90
Gustavo Padovan2d792812012-10-06 10:07:01 +010091static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
92 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020093{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020094 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030095
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020096 list_for_each_entry(c, &conn->chan_l, list) {
97 if (c->scid == cid)
98 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020099 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200100 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200101}
102
103/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -0700104 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +0100105static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
106 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +0200107{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300108 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300109
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200110 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300111 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -0700112 if (c)
113 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200114 mutex_unlock(&conn->chan_lock);
115
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300116 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200117}
118
Mat Martineaub1a130b2012-10-23 15:24:09 -0700119/* Find channel with given DCID.
120 * Returns locked channel.
121 */
122static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
123 u16 cid)
124{
125 struct l2cap_chan *c;
126
127 mutex_lock(&conn->chan_lock);
128 c = __l2cap_get_chan_by_dcid(conn, cid);
129 if (c)
130 l2cap_chan_lock(c);
131 mutex_unlock(&conn->chan_lock);
132
133 return c;
134}
135
Gustavo Padovan2d792812012-10-06 10:07:01 +0100136static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
137 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200138{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200139 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300140
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200141 list_for_each_entry(c, &conn->chan_l, list) {
142 if (c->ident == ident)
143 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200144 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200145 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200146}
147
Mat Martineau5b155ef2012-10-23 15:24:14 -0700148static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
149 u8 ident)
150{
151 struct l2cap_chan *c;
152
153 mutex_lock(&conn->chan_lock);
154 c = __l2cap_get_chan_by_ident(conn, ident);
155 if (c)
156 l2cap_chan_lock(c);
157 mutex_unlock(&conn->chan_lock);
158
159 return c;
160}
161
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300162static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300163{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300164 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300165
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300166 list_for_each_entry(c, &chan_list, global_l) {
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700167 if (c->sport == psm && !bacmp(&c->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100168 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300169 }
Szymon Janc250938c2011-11-16 09:32:22 +0100170 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300171}
172
173int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
174{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300175 int err;
176
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200177 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300178
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300179 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300180 err = -EADDRINUSE;
181 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300182 }
183
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300184 if (psm) {
185 chan->psm = psm;
186 chan->sport = psm;
187 err = 0;
188 } else {
189 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300190
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300191 err = -EINVAL;
192 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300193 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300194 chan->psm = cpu_to_le16(p);
195 chan->sport = cpu_to_le16(p);
196 err = 0;
197 break;
198 }
199 }
200
201done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200202 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300203 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300204}
205
206int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
207{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200208 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300209
210 chan->scid = scid;
211
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200212 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300213
214 return 0;
215}
216
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300217static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200218{
Johan Hedberge77af752013-10-08 10:31:00 +0200219 u16 cid, dyn_end;
Marcel Holtmann01394182006-07-03 10:02:46 +0200220
Johan Hedberge77af752013-10-08 10:31:00 +0200221 if (conn->hcon->type == LE_LINK)
222 dyn_end = L2CAP_CID_LE_DYN_END;
223 else
224 dyn_end = L2CAP_CID_DYN_END;
225
226 for (cid = L2CAP_CID_DYN_START; cid < dyn_end; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300227 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200228 return cid;
229 }
230
231 return 0;
232}
233
Gustavo Padovanf93fa272013-10-21 14:21:40 -0200234static void l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300235{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200236 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100237 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200238
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300239 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300240 chan->ops->state_change(chan, state, 0);
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300241}
242
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300243static inline void l2cap_state_change_and_error(struct l2cap_chan *chan,
244 int state, int err)
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200245{
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300246 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300247 chan->ops->state_change(chan, chan->state, err);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200248}
249
250static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
251{
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300252 chan->ops->state_change(chan, chan->state, err);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200253}
254
Mat Martineau4239d162012-05-17 20:53:49 -0700255static void __set_retrans_timer(struct l2cap_chan *chan)
256{
257 if (!delayed_work_pending(&chan->monitor_timer) &&
258 chan->retrans_timeout) {
259 l2cap_set_timer(chan, &chan->retrans_timer,
260 msecs_to_jiffies(chan->retrans_timeout));
261 }
262}
263
264static void __set_monitor_timer(struct l2cap_chan *chan)
265{
266 __clear_retrans_timer(chan);
267 if (chan->monitor_timeout) {
268 l2cap_set_timer(chan, &chan->monitor_timer,
269 msecs_to_jiffies(chan->monitor_timeout));
270 }
271}
272
Mat Martineau608bcc62012-05-17 20:53:32 -0700273static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
274 u16 seq)
275{
276 struct sk_buff *skb;
277
278 skb_queue_walk(head, skb) {
279 if (bt_cb(skb)->control.txseq == seq)
280 return skb;
281 }
282
283 return NULL;
284}
285
Mat Martineau3c588192012-04-11 10:48:42 -0700286/* ---- L2CAP sequence number lists ---- */
287
288/* For ERTM, ordered lists of sequence numbers must be tracked for
289 * SREJ requests that are received and for frames that are to be
290 * retransmitted. These seq_list functions implement a singly-linked
291 * list in an array, where membership in the list can also be checked
292 * in constant time. Items can also be added to the tail of the list
293 * and removed from the head in constant time, without further memory
294 * allocs or frees.
295 */
296
297static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
298{
299 size_t alloc_size, i;
300
301 /* Allocated size is a power of 2 to map sequence numbers
302 * (which may be up to 14 bits) in to a smaller array that is
303 * sized for the negotiated ERTM transmit windows.
304 */
305 alloc_size = roundup_pow_of_two(size);
306
307 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
308 if (!seq_list->list)
309 return -ENOMEM;
310
311 seq_list->mask = alloc_size - 1;
312 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
313 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
314 for (i = 0; i < alloc_size; i++)
315 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
316
317 return 0;
318}
319
320static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
321{
322 kfree(seq_list->list);
323}
324
325static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
326 u16 seq)
327{
328 /* Constant-time check for list membership */
329 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
330}
331
332static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
333{
334 u16 mask = seq_list->mask;
335
336 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
337 /* In case someone tries to pop the head of an empty list */
338 return L2CAP_SEQ_LIST_CLEAR;
339 } else if (seq_list->head == seq) {
340 /* Head can be removed in constant time */
341 seq_list->head = seq_list->list[seq & mask];
342 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
343
344 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
345 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
346 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
347 }
348 } else {
349 /* Walk the list to find the sequence number */
350 u16 prev = seq_list->head;
351 while (seq_list->list[prev & mask] != seq) {
352 prev = seq_list->list[prev & mask];
353 if (prev == L2CAP_SEQ_LIST_TAIL)
354 return L2CAP_SEQ_LIST_CLEAR;
355 }
356
357 /* Unlink the number from the list and clear it */
358 seq_list->list[prev & mask] = seq_list->list[seq & mask];
359 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
360 if (seq_list->tail == seq)
361 seq_list->tail = prev;
362 }
363 return seq;
364}
365
366static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
367{
368 /* Remove the head in constant time */
369 return l2cap_seq_list_remove(seq_list, seq_list->head);
370}
371
372static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
373{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300374 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700375
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300376 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
377 return;
378
379 for (i = 0; i <= seq_list->mask; i++)
380 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
381
382 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
383 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700384}
385
386static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
387{
388 u16 mask = seq_list->mask;
389
390 /* All appends happen in constant time */
391
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300392 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
393 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700394
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300395 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
396 seq_list->head = seq;
397 else
398 seq_list->list[seq_list->tail & mask] = seq;
399
400 seq_list->tail = seq;
401 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700402}
403
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300404static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300405{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300406 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100407 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200408 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300409 int reason;
410
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200411 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300412
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200413 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200414 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300415
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300416 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300417 reason = ECONNREFUSED;
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300418 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100419 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300420 reason = ECONNREFUSED;
421 else
422 reason = ETIMEDOUT;
423
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300424 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300425
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200426 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300427
Gustavo Padovan80b98022012-05-27 22:27:51 -0300428 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200429 mutex_unlock(&conn->chan_lock);
430
Ulisses Furquim371fd832011-12-21 20:02:36 -0200431 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300432}
433
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300434struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200435{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300436 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200437
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300438 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
439 if (!chan)
440 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200441
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200442 mutex_init(&chan->lock);
443
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200444 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300445 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200446 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300447
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300448 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300449
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300450 chan->state = BT_OPEN;
451
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530452 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300453
Mat Martineau28270112012-05-17 21:14:09 -0700454 /* This flag is cleared in l2cap_chan_ready() */
455 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
456
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300457 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100458
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300459 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200460}
461
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530462static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300463{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530464 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
465
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530466 BT_DBG("chan %p", chan);
467
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200468 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300469 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200470 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300471
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530472 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300473}
474
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530475void l2cap_chan_hold(struct l2cap_chan *c)
476{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530477 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530478
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530479 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530480}
481
482void l2cap_chan_put(struct l2cap_chan *c)
483{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530484 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530485
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530486 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530487}
488
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300489void l2cap_chan_set_defaults(struct l2cap_chan *chan)
490{
491 chan->fcs = L2CAP_FCS_CRC16;
492 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
493 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
494 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700495 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300496 chan->sec_level = BT_SECURITY_LOW;
497
498 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
499}
500
Johan Hedberg0ce43ce2013-12-05 14:55:33 +0200501static void l2cap_le_flowctl_init(struct l2cap_chan *chan)
Johan Hedberg38319712013-05-17 12:49:23 +0300502{
Johan Hedberg0ce43ce2013-12-05 14:55:33 +0200503 chan->sdu = NULL;
504 chan->sdu_last_frag = NULL;
505 chan->sdu_len = 0;
Johan Hedberg0cd75f72013-05-17 13:09:05 +0300506 chan->tx_credits = 0;
Johan Hedbergf15b8ec2013-12-03 15:08:25 +0200507 chan->rx_credits = le_max_credits;
Johan Hedberg3916aed2013-10-07 15:35:26 +0200508
509 if (chan->imtu < L2CAP_LE_DEFAULT_MPS)
510 chan->mps = chan->imtu;
511 else
512 chan->mps = L2CAP_LE_DEFAULT_MPS;
Johan Hedberg0ce43ce2013-12-05 14:55:33 +0200513
514 skb_queue_head_init(&chan->tx_q);
Johan Hedberg38319712013-05-17 12:49:23 +0300515}
516
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300517void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200518{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300519 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200520 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200521
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200522 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100523
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300524 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200525
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200526 switch (chan->chan_type) {
527 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300528 if (conn->hcon->type == LE_LINK) {
Johan Hedbergaeddd072013-10-07 16:15:25 +0200529 if (chan->dcid == L2CAP_CID_ATT) {
530 chan->omtu = L2CAP_DEFAULT_MTU;
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300531 chan->scid = L2CAP_CID_ATT;
Johan Hedbergaeddd072013-10-07 16:15:25 +0200532 } else {
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300533 chan->scid = l2cap_alloc_cid(conn);
Johan Hedbergaeddd072013-10-07 16:15:25 +0200534 }
Ville Tervob62f3282011-02-10 22:38:50 -0300535 } else {
536 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300537 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300538 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300539 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200540 break;
541
542 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200543 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300544 chan->scid = L2CAP_CID_CONN_LESS;
545 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300546 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200547 break;
548
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300549 case L2CAP_CHAN_CONN_FIX_A2MP:
550 chan->scid = L2CAP_CID_A2MP;
551 chan->dcid = L2CAP_CID_A2MP;
552 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
553 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
554 break;
555
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200556 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200557 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300558 chan->scid = L2CAP_CID_SIGNALING;
559 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300560 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200561 }
562
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300563 chan->local_id = L2CAP_BESTEFFORT_ID;
564 chan->local_stype = L2CAP_SERV_BESTEFFORT;
565 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
566 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
567 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300568 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300569
Ulisses Furquim371fd832011-12-21 20:02:36 -0200570 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300571
Johan Hedberg5ee98912013-04-29 19:35:43 +0300572 hci_conn_hold(conn->hcon);
573
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200574 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200575}
576
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300577void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200578{
579 mutex_lock(&conn->chan_lock);
580 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200581 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200582}
583
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300584void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200585{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300586 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200587
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300588 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200589
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300590 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200591
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900592 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300593 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300594 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200595 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200596
Ulisses Furquim371fd832011-12-21 20:02:36 -0200597 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300598
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300599 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300600
601 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200602 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300603
604 if (mgr && mgr->bredr_chan == chan)
605 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200606 }
607
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200608 if (chan->hs_hchan) {
609 struct hci_chan *hs_hchan = chan->hs_hchan;
610
611 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
612 amp_disconnect_logical_link(hs_hchan);
613 }
614
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100615 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200616
Mat Martineau28270112012-05-17 21:14:09 -0700617 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300618 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300619
Gustavo Padovanee556f62012-05-18 20:22:38 -0300620 switch(chan->mode) {
621 case L2CAP_MODE_BASIC:
622 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300623
Johan Hedberg38319712013-05-17 12:49:23 +0300624 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedberg177f8f22013-05-31 17:54:51 +0300625 skb_queue_purge(&chan->tx_q);
Johan Hedberg38319712013-05-17 12:49:23 +0300626 break;
627
Gustavo Padovanee556f62012-05-18 20:22:38 -0300628 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300629 __clear_retrans_timer(chan);
630 __clear_monitor_timer(chan);
631 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300632
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300633 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300634
Mat Martineau3c588192012-04-11 10:48:42 -0700635 l2cap_seq_list_free(&chan->srej_list);
636 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300637
638 /* fall through */
639
640 case L2CAP_MODE_STREAMING:
641 skb_queue_purge(&chan->tx_q);
642 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300643 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300644
645 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200646}
647
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300648static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
649{
650 struct l2cap_conn *conn = chan->conn;
651 struct l2cap_le_conn_rsp rsp;
652 u16 result;
653
654 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
655 result = L2CAP_CR_AUTHORIZATION;
656 else
657 result = L2CAP_CR_BAD_PSM;
658
659 l2cap_state_change(chan, BT_DISCONN);
660
661 rsp.dcid = cpu_to_le16(chan->scid);
662 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +0200663 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +0300664 rsp.credits = cpu_to_le16(chan->rx_credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300665 rsp.result = cpu_to_le16(result);
666
667 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
668 &rsp);
669}
670
Johan Hedberg791d60f2013-05-14 22:24:44 +0300671static void l2cap_chan_connect_reject(struct l2cap_chan *chan)
672{
673 struct l2cap_conn *conn = chan->conn;
674 struct l2cap_conn_rsp rsp;
675 u16 result;
676
677 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
678 result = L2CAP_CR_SEC_BLOCK;
679 else
680 result = L2CAP_CR_BAD_PSM;
681
682 l2cap_state_change(chan, BT_DISCONN);
683
684 rsp.scid = cpu_to_le16(chan->dcid);
685 rsp.dcid = cpu_to_le16(chan->scid);
686 rsp.result = cpu_to_le16(result);
687 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
688
689 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
690}
691
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300692void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300693{
694 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300695
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700696 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300697
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300698 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300699 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100700 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300701 break;
702
703 case BT_CONNECTED:
704 case BT_CONFIG:
Johan Hedbergcea04ce32013-05-14 22:46:01 +0300705 /* ATT uses L2CAP_CHAN_CONN_ORIENTED so we must also
706 * check for chan->psm.
707 */
708 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && chan->psm) {
Gustavo Padovan8d836d72013-10-15 19:24:47 -0300709 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200710 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300711 } else
712 l2cap_chan_del(chan, reason);
713 break;
714
715 case BT_CONNECT2:
Johan Hedberg791d60f2013-05-14 22:24:44 +0300716 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) {
717 if (conn->hcon->type == ACL_LINK)
718 l2cap_chan_connect_reject(chan);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300719 else if (conn->hcon->type == LE_LINK)
720 l2cap_chan_le_connect_reject(chan);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300721 }
722
723 l2cap_chan_del(chan, reason);
724 break;
725
726 case BT_CONNECT:
727 case BT_DISCONN:
728 l2cap_chan_del(chan, reason);
729 break;
730
731 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100732 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300733 break;
734 }
735}
736
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300737static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530738{
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700739 switch (chan->chan_type) {
740 case L2CAP_CHAN_RAW:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300741 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530742 case BT_SECURITY_HIGH:
743 return HCI_AT_DEDICATED_BONDING_MITM;
744 case BT_SECURITY_MEDIUM:
745 return HCI_AT_DEDICATED_BONDING;
746 default:
747 return HCI_AT_NO_BONDING;
748 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700749 break;
Marcel Holtmann3124b842013-10-12 07:19:32 -0700750 case L2CAP_CHAN_CONN_LESS:
751 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_3DSP)) {
752 if (chan->sec_level == BT_SECURITY_LOW)
753 chan->sec_level = BT_SECURITY_SDP;
754 }
755 if (chan->sec_level == BT_SECURITY_HIGH)
756 return HCI_AT_NO_BONDING_MITM;
757 else
758 return HCI_AT_NO_BONDING;
759 break;
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700760 case L2CAP_CHAN_CONN_ORIENTED:
761 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
762 if (chan->sec_level == BT_SECURITY_LOW)
763 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530764
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700765 if (chan->sec_level == BT_SECURITY_HIGH)
766 return HCI_AT_NO_BONDING_MITM;
767 else
768 return HCI_AT_NO_BONDING;
769 }
770 /* fall through */
771 default:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300772 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530773 case BT_SECURITY_HIGH:
774 return HCI_AT_GENERAL_BONDING_MITM;
775 case BT_SECURITY_MEDIUM:
776 return HCI_AT_GENERAL_BONDING;
777 default:
778 return HCI_AT_NO_BONDING;
779 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700780 break;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530781 }
782}
783
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200784/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200785int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200786{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300787 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100788 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200789
Johan Hedberga17de2f2013-05-14 13:25:37 +0300790 if (conn->hcon->type == LE_LINK)
791 return smp_conn_security(conn->hcon, chan->sec_level);
792
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300793 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100794
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300795 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200796}
797
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200798static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200799{
800 u8 id;
801
802 /* Get next available identificator.
803 * 1 - 128 are used by kernel.
804 * 129 - 199 are reserved.
805 * 200 - 254 are used by utilities like l2ping, etc.
806 */
807
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200808 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200809
810 if (++conn->tx_ident > 128)
811 conn->tx_ident = 1;
812
813 id = conn->tx_ident;
814
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200815 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200816
817 return id;
818}
819
Gustavo Padovan2d792812012-10-06 10:07:01 +0100820static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
821 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200822{
823 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200824 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200825
826 BT_DBG("code 0x%2.2x", code);
827
828 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300829 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200830
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200831 if (lmp_no_flush_capable(conn->hcon->hdev))
832 flags = ACL_START_NO_FLUSH;
833 else
834 flags = ACL_START;
835
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700836 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200837 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700838
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200839 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200840}
841
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700842static bool __chan_is_moving(struct l2cap_chan *chan)
843{
844 return chan->move_state != L2CAP_MOVE_STABLE &&
845 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
846}
847
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200848static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
849{
850 struct hci_conn *hcon = chan->conn->hcon;
851 u16 flags;
852
853 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100854 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200855
Mat Martineaud5f8a752012-10-23 15:24:18 -0700856 if (chan->hs_hcon && !__chan_is_moving(chan)) {
857 if (chan->hs_hchan)
858 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
859 else
860 kfree_skb(skb);
861
862 return;
863 }
864
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200865 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100866 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200867 flags = ACL_START_NO_FLUSH;
868 else
869 flags = ACL_START;
870
871 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
872 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873}
874
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700875static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
876{
877 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
878 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
879
880 if (enh & L2CAP_CTRL_FRAME_TYPE) {
881 /* S-Frame */
882 control->sframe = 1;
883 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
884 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
885
886 control->sar = 0;
887 control->txseq = 0;
888 } else {
889 /* I-Frame */
890 control->sframe = 0;
891 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
892 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
893
894 control->poll = 0;
895 control->super = 0;
896 }
897}
898
899static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
900{
901 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
902 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
903
904 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
905 /* S-Frame */
906 control->sframe = 1;
907 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
908 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
909
910 control->sar = 0;
911 control->txseq = 0;
912 } else {
913 /* I-Frame */
914 control->sframe = 0;
915 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
916 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
917
918 control->poll = 0;
919 control->super = 0;
920 }
921}
922
923static inline void __unpack_control(struct l2cap_chan *chan,
924 struct sk_buff *skb)
925{
926 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
927 __unpack_extended_control(get_unaligned_le32(skb->data),
928 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700929 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700930 } else {
931 __unpack_enhanced_control(get_unaligned_le16(skb->data),
932 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700933 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700934 }
935}
936
937static u32 __pack_extended_control(struct l2cap_ctrl *control)
938{
939 u32 packed;
940
941 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
942 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
943
944 if (control->sframe) {
945 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
946 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
947 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
948 } else {
949 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
950 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
951 }
952
953 return packed;
954}
955
956static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
957{
958 u16 packed;
959
960 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
961 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
962
963 if (control->sframe) {
964 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
965 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
966 packed |= L2CAP_CTRL_FRAME_TYPE;
967 } else {
968 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
969 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
970 }
971
972 return packed;
973}
974
975static inline void __pack_control(struct l2cap_chan *chan,
976 struct l2cap_ctrl *control,
977 struct sk_buff *skb)
978{
979 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
980 put_unaligned_le32(__pack_extended_control(control),
981 skb->data + L2CAP_HDR_SIZE);
982 } else {
983 put_unaligned_le16(__pack_enhanced_control(control),
984 skb->data + L2CAP_HDR_SIZE);
985 }
986}
987
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300988static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
989{
990 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
991 return L2CAP_EXT_HDR_SIZE;
992 else
993 return L2CAP_ENH_HDR_SIZE;
994}
995
Mat Martineaua67d7f62012-05-17 20:53:35 -0700996static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
997 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300998{
999 struct sk_buff *skb;
1000 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -03001001 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001002
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001003 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03001004 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001005
Mat Martineaua67d7f62012-05-17 20:53:35 -07001006 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001007
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001008 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -07001009 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001010
1011 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001012 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001013 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03001014
Mat Martineaua67d7f62012-05-17 20:53:35 -07001015 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1016 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
1017 else
1018 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001019
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001020 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -07001021 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03001022 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001023 }
1024
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001025 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -07001026 return skb;
1027}
1028
1029static void l2cap_send_sframe(struct l2cap_chan *chan,
1030 struct l2cap_ctrl *control)
1031{
1032 struct sk_buff *skb;
1033 u32 control_field;
1034
1035 BT_DBG("chan %p, control %p", chan, control);
1036
1037 if (!control->sframe)
1038 return;
1039
Mat Martineaub99e13a2012-10-23 15:24:19 -07001040 if (__chan_is_moving(chan))
1041 return;
1042
Mat Martineaua67d7f62012-05-17 20:53:35 -07001043 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
1044 !control->poll)
1045 control->final = 1;
1046
1047 if (control->super == L2CAP_SUPER_RR)
1048 clear_bit(CONN_RNR_SENT, &chan->conn_state);
1049 else if (control->super == L2CAP_SUPER_RNR)
1050 set_bit(CONN_RNR_SENT, &chan->conn_state);
1051
1052 if (control->super != L2CAP_SUPER_SREJ) {
1053 chan->last_acked_seq = control->reqseq;
1054 __clear_ack_timer(chan);
1055 }
1056
1057 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
1058 control->final, control->poll, control->super);
1059
1060 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1061 control_field = __pack_extended_control(control);
1062 else
1063 control_field = __pack_enhanced_control(control);
1064
1065 skb = l2cap_create_sframe_pdu(chan, control_field);
1066 if (!IS_ERR(skb))
1067 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001068}
1069
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001070static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001071{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001072 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001073
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001074 BT_DBG("chan %p, poll %d", chan, poll);
1075
1076 memset(&control, 0, sizeof(control));
1077 control.sframe = 1;
1078 control.poll = poll;
1079
1080 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1081 control.super = L2CAP_SUPER_RNR;
1082 else
1083 control.super = L2CAP_SUPER_RR;
1084
1085 control.reqseq = chan->buffer_seq;
1086 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001087}
1088
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001089static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001090{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001091 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001092}
1093
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001094static bool __amp_capable(struct l2cap_chan *chan)
1095{
1096 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001097 struct hci_dev *hdev;
1098 bool amp_available = false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001099
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001100 if (!conn->hs_enabled)
1101 return false;
1102
1103 if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
1104 return false;
1105
1106 read_lock(&hci_dev_list_lock);
1107 list_for_each_entry(hdev, &hci_dev_list, list) {
1108 if (hdev->amp_type != AMP_TYPE_BREDR &&
1109 test_bit(HCI_UP, &hdev->flags)) {
1110 amp_available = true;
1111 break;
1112 }
1113 }
1114 read_unlock(&hci_dev_list_lock);
1115
1116 if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED)
1117 return amp_available;
Marcel Holtmann848566b2013-10-01 22:59:22 -07001118
1119 return false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001120}
1121
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001122static bool l2cap_check_efs(struct l2cap_chan *chan)
1123{
1124 /* Check EFS parameters */
1125 return true;
1126}
1127
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001128void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001129{
1130 struct l2cap_conn *conn = chan->conn;
1131 struct l2cap_conn_req req;
1132
1133 req.scid = cpu_to_le16(chan->scid);
1134 req.psm = chan->psm;
1135
1136 chan->ident = l2cap_get_ident(conn);
1137
1138 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1139
1140 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1141}
1142
Mat Martineau8eb200b2012-10-23 15:24:17 -07001143static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1144{
1145 struct l2cap_create_chan_req req;
1146 req.scid = cpu_to_le16(chan->scid);
1147 req.psm = chan->psm;
1148 req.amp_id = amp_id;
1149
1150 chan->ident = l2cap_get_ident(chan->conn);
1151
1152 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1153 sizeof(req), &req);
1154}
1155
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001156static void l2cap_move_setup(struct l2cap_chan *chan)
1157{
1158 struct sk_buff *skb;
1159
1160 BT_DBG("chan %p", chan);
1161
1162 if (chan->mode != L2CAP_MODE_ERTM)
1163 return;
1164
1165 __clear_retrans_timer(chan);
1166 __clear_monitor_timer(chan);
1167 __clear_ack_timer(chan);
1168
1169 chan->retry_count = 0;
1170 skb_queue_walk(&chan->tx_q, skb) {
1171 if (bt_cb(skb)->control.retries)
1172 bt_cb(skb)->control.retries = 1;
1173 else
1174 break;
1175 }
1176
1177 chan->expected_tx_seq = chan->buffer_seq;
1178
1179 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1180 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1181 l2cap_seq_list_clear(&chan->retrans_list);
1182 l2cap_seq_list_clear(&chan->srej_list);
1183 skb_queue_purge(&chan->srej_q);
1184
1185 chan->tx_state = L2CAP_TX_STATE_XMIT;
1186 chan->rx_state = L2CAP_RX_STATE_MOVE;
1187
1188 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1189}
1190
Mat Martineau5f3847a2012-10-23 15:24:12 -07001191static void l2cap_move_done(struct l2cap_chan *chan)
1192{
1193 u8 move_role = chan->move_role;
1194 BT_DBG("chan %p", chan);
1195
1196 chan->move_state = L2CAP_MOVE_STABLE;
1197 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1198
1199 if (chan->mode != L2CAP_MODE_ERTM)
1200 return;
1201
1202 switch (move_role) {
1203 case L2CAP_MOVE_ROLE_INITIATOR:
1204 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1205 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1206 break;
1207 case L2CAP_MOVE_ROLE_RESPONDER:
1208 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1209 break;
1210 }
1211}
1212
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001213static void l2cap_chan_ready(struct l2cap_chan *chan)
1214{
Mat Martineau28270112012-05-17 21:14:09 -07001215 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001216 chan->conf_state = 0;
1217 __clear_chan_timer(chan);
1218
Johan Hedberg0ce43ce2013-12-05 14:55:33 +02001219 if (chan->mode == L2CAP_MODE_LE_FLOWCTL && !chan->tx_credits)
1220 chan->ops->suspend(chan);
Johan Hedberg177f8f22013-05-31 17:54:51 +03001221
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001222 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001223
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001224 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001225}
1226
Johan Hedbergf1496de2013-05-13 14:15:56 +03001227static void l2cap_le_connect(struct l2cap_chan *chan)
1228{
1229 struct l2cap_conn *conn = chan->conn;
1230 struct l2cap_le_conn_req req;
1231
Johan Hedberg595177f2013-12-02 22:12:22 +02001232 if (test_and_set_bit(FLAG_LE_CONN_REQ_SENT, &chan->flags))
1233 return;
1234
Johan Hedbergf1496de2013-05-13 14:15:56 +03001235 req.psm = chan->psm;
1236 req.scid = cpu_to_le16(chan->scid);
1237 req.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02001238 req.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03001239 req.credits = cpu_to_le16(chan->rx_credits);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001240
1241 chan->ident = l2cap_get_ident(conn);
1242
1243 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_REQ,
1244 sizeof(req), &req);
1245}
1246
1247static void l2cap_le_start(struct l2cap_chan *chan)
1248{
1249 struct l2cap_conn *conn = chan->conn;
1250
1251 if (!smp_conn_security(conn->hcon, chan->sec_level))
1252 return;
1253
1254 if (!chan->psm) {
1255 l2cap_chan_ready(chan);
1256 return;
1257 }
1258
1259 if (chan->state == BT_CONNECT)
1260 l2cap_le_connect(chan);
1261}
1262
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001263static void l2cap_start_connection(struct l2cap_chan *chan)
1264{
1265 if (__amp_capable(chan)) {
1266 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1267 a2mp_discover_amp(chan);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001268 } else if (chan->conn->hcon->type == LE_LINK) {
1269 l2cap_le_start(chan);
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001270 } else {
1271 l2cap_send_conn_req(chan);
1272 }
1273}
1274
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001275static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001276{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001277 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001278
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001279 if (conn->hcon->type == LE_LINK) {
Johan Hedberg96ac34f2013-05-13 11:15:07 +03001280 l2cap_le_start(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001281 return;
1282 }
1283
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001284 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001285 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1286 return;
1287
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001288 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001289 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001290 l2cap_start_connection(chan);
1291 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001292 } else {
1293 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001294 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001295
1296 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1297 conn->info_ident = l2cap_get_ident(conn);
1298
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001299 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001300
Gustavo Padovan2d792812012-10-06 10:07:01 +01001301 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1302 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001303 }
1304}
1305
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001306static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1307{
1308 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001309 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001310 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1311
1312 switch (mode) {
1313 case L2CAP_MODE_ERTM:
1314 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1315 case L2CAP_MODE_STREAMING:
1316 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1317 default:
1318 return 0x00;
1319 }
1320}
1321
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001322static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001323{
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001324 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001325 struct l2cap_disconn_req req;
1326
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001327 if (!conn)
1328 return;
1329
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001330 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001331 __clear_retrans_timer(chan);
1332 __clear_monitor_timer(chan);
1333 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001334 }
1335
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001336 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001337 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001338 return;
1339 }
1340
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001341 req.dcid = cpu_to_le16(chan->dcid);
1342 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001343 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1344 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001345
Gustavo Padovanf8e73012013-10-15 19:24:46 -03001346 l2cap_state_change_and_error(chan, BT_DISCONN, err);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001347}
1348
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001350static void l2cap_conn_start(struct l2cap_conn *conn)
1351{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001352 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001353
1354 BT_DBG("conn %p", conn);
1355
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001356 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001357
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001358 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001359 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001360
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001361 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001362 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001363 continue;
1364 }
1365
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001366 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001367 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001368 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001369 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001370 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001371 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001372
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001373 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001374 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001375 &chan->conf_state)) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001376 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001377 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001378 continue;
1379 }
1380
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001381 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001382
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001383 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001384 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001385 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001386 rsp.scid = cpu_to_le16(chan->dcid);
1387 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001388
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001389 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07001390 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001391 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1392 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001393 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001394
1395 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02001396 l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001397 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1398 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001399 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001400 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001401 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1402 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001403 }
1404
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001405 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001406 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001407
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001408 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001409 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001410 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001411 continue;
1412 }
1413
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001414 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001415 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001416 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001417 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001418 }
1419
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001420 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001421 }
1422
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001423 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001424}
1425
Ido Yarivc2287682012-04-20 15:46:07 -03001426/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001427 * Returns closest match, locked.
1428 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001429static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001430 bdaddr_t *src,
1431 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001432{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001433 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001434
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001435 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001436
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001437 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001438 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001439 continue;
1440
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001441 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001442 int src_match, dst_match;
1443 int src_any, dst_any;
1444
Ville Tervob62f3282011-02-10 22:38:50 -03001445 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001446 src_match = !bacmp(&c->src, src);
1447 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001448 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001449 read_unlock(&chan_list_lock);
1450 return c;
1451 }
Ville Tervob62f3282011-02-10 22:38:50 -03001452
1453 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001454 src_any = !bacmp(&c->src, BDADDR_ANY);
1455 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001456 if ((src_match && dst_any) || (src_any && dst_match) ||
1457 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001458 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001459 }
1460 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001461
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001462 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001463
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001464 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001465}
1466
1467static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1468{
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001469 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001470 struct l2cap_chan *chan, *pchan;
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001471 u8 dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001472
1473 BT_DBG("");
1474
1475 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001476 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001477 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001478 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001479 return;
1480
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001481 /* Client ATT sockets should override the server one */
1482 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1483 return;
1484
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001485 dst_type = bdaddr_type(hcon, hcon->dst_type);
1486
1487 /* If device is blocked, do not create a channel for it */
1488 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, dst_type))
1489 return;
1490
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001491 l2cap_chan_lock(pchan);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001492
Gustavo Padovan80b98022012-05-27 22:27:51 -03001493 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001494 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001495 goto clean;
1496
Johan Hedberg9f22398c2013-04-29 19:35:38 +03001497 chan->dcid = L2CAP_CID_ATT;
1498
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001499 bacpy(&chan->src, &hcon->src);
1500 bacpy(&chan->dst, &hcon->dst);
1501 chan->src_type = bdaddr_type(hcon, hcon->src_type);
1502 chan->dst_type = dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001503
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001504 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001505
Ville Tervob62f3282011-02-10 22:38:50 -03001506clean:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001507 l2cap_chan_unlock(pchan);
Ville Tervob62f3282011-02-10 22:38:50 -03001508}
1509
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001510static void l2cap_conn_ready(struct l2cap_conn *conn)
1511{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001512 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001513 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001514
1515 BT_DBG("conn %p", conn);
1516
Johan Hedbergd8729922013-04-29 19:35:39 +03001517 /* For outgoing pairing which doesn't necessarily have an
1518 * associated socket (e.g. mgmt_pair_device).
1519 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001520 if (hcon->out && hcon->type == LE_LINK)
1521 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001522
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001523 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001524
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001525 if (hcon->type == LE_LINK)
1526 l2cap_le_conn_ready(conn);
1527
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001528 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001529
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001530 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001531
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001532 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1533 l2cap_chan_unlock(chan);
1534 continue;
1535 }
1536
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001537 if (hcon->type == LE_LINK) {
Johan Hedbergf1496de2013-05-13 14:15:56 +03001538 l2cap_le_start(chan);
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001539 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo Padovan74e75742013-10-15 19:24:51 -03001540 l2cap_chan_ready(chan);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001541
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001542 } else if (chan->state == BT_CONNECT) {
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001543 l2cap_do_start(chan);
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001544 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001545
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001546 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001547 }
1548
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001549 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001550}
1551
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001552/* Notify sockets that we cannot guaranty reliability anymore */
1553static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1554{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001555 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001556
1557 BT_DBG("conn %p", conn);
1558
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001559 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001560
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001561 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001562 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001563 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001564 }
1565
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001566 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001567}
1568
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001569static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001570{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001571 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001572 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001573
Marcel Holtmann984947d2009-02-06 23:35:19 +01001574 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001575 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001576
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001577 l2cap_conn_start(conn);
1578}
1579
David Herrmann2c8e1412013-04-06 20:28:45 +02001580/*
1581 * l2cap_user
1582 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1583 * callback is called during registration. The ->remove callback is called
1584 * during unregistration.
1585 * An l2cap_user object can either be explicitly unregistered or when the
1586 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1587 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1588 * External modules must own a reference to the l2cap_conn object if they intend
1589 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1590 * any time if they don't.
1591 */
1592
1593int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1594{
1595 struct hci_dev *hdev = conn->hcon->hdev;
1596 int ret;
1597
1598 /* We need to check whether l2cap_conn is registered. If it is not, we
1599 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1600 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1601 * relies on the parent hci_conn object to be locked. This itself relies
1602 * on the hci_dev object to be locked. So we must lock the hci device
1603 * here, too. */
1604
1605 hci_dev_lock(hdev);
1606
1607 if (user->list.next || user->list.prev) {
1608 ret = -EINVAL;
1609 goto out_unlock;
1610 }
1611
1612 /* conn->hchan is NULL after l2cap_conn_del() was called */
1613 if (!conn->hchan) {
1614 ret = -ENODEV;
1615 goto out_unlock;
1616 }
1617
1618 ret = user->probe(conn, user);
1619 if (ret)
1620 goto out_unlock;
1621
1622 list_add(&user->list, &conn->users);
1623 ret = 0;
1624
1625out_unlock:
1626 hci_dev_unlock(hdev);
1627 return ret;
1628}
1629EXPORT_SYMBOL(l2cap_register_user);
1630
1631void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1632{
1633 struct hci_dev *hdev = conn->hcon->hdev;
1634
1635 hci_dev_lock(hdev);
1636
1637 if (!user->list.next || !user->list.prev)
1638 goto out_unlock;
1639
1640 list_del(&user->list);
1641 user->list.next = NULL;
1642 user->list.prev = NULL;
1643 user->remove(conn, user);
1644
1645out_unlock:
1646 hci_dev_unlock(hdev);
1647}
1648EXPORT_SYMBOL(l2cap_unregister_user);
1649
1650static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1651{
1652 struct l2cap_user *user;
1653
1654 while (!list_empty(&conn->users)) {
1655 user = list_first_entry(&conn->users, struct l2cap_user, list);
1656 list_del(&user->list);
1657 user->list.next = NULL;
1658 user->list.prev = NULL;
1659 user->remove(conn, user);
1660 }
1661}
1662
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001663static void l2cap_conn_del(struct hci_conn *hcon, int err)
1664{
1665 struct l2cap_conn *conn = hcon->l2cap_data;
1666 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001667
1668 if (!conn)
1669 return;
1670
1671 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1672
1673 kfree_skb(conn->rx_skb);
1674
David Herrmann2c8e1412013-04-06 20:28:45 +02001675 l2cap_unregister_all_users(conn);
1676
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001677 mutex_lock(&conn->chan_lock);
1678
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001679 /* Kill channels */
1680 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001681 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001682 l2cap_chan_lock(chan);
1683
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001684 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001685
1686 l2cap_chan_unlock(chan);
1687
Gustavo Padovan80b98022012-05-27 22:27:51 -03001688 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001689 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001690 }
1691
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001692 mutex_unlock(&conn->chan_lock);
1693
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001694 hci_chan_del(conn->hchan);
1695
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001696 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001697 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001698
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001699 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001700 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001701 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001702 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001703
1704 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001705 conn->hchan = NULL;
1706 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001707}
1708
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001709static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001710{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001711 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001712 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001713
Johan Hedbergd06cc412012-06-06 18:44:11 +08001714 BT_DBG("conn %p", conn);
1715
1716 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1717 smp_chan_destroy(conn);
1718 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1719 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001720}
1721
Claudio Takahasibaf43252013-04-11 13:55:50 -03001722static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723{
Marcel Holtmann01394182006-07-03 10:02:46 +02001724 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001725 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726
Claudio Takahasibaf43252013-04-11 13:55:50 -03001727 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728 return conn;
1729
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001730 hchan = hci_chan_create(hcon);
1731 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001734 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001735 if (!conn) {
1736 hci_chan_del(hchan);
1737 return NULL;
1738 }
1739
David Herrmann9c903e32013-04-06 20:28:44 +02001740 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 hcon->l2cap_data = conn;
1742 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001743 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001744 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001746 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001747
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001748 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001749 case LE_LINK:
1750 if (hcon->hdev->le_mtu) {
1751 conn->mtu = hcon->hdev->le_mtu;
1752 break;
1753 }
1754 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001755 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001756 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001757 break;
1758 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001759
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001760 conn->feat_mask = 0;
1761
Marcel Holtmann848566b2013-10-01 22:59:22 -07001762 if (hcon->type == ACL_LINK)
1763 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
1764 &hcon->hdev->dev_flags);
1765
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001767 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001768
1769 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001770 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001772 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001773 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001774 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001775 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001776
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001777 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001778
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 return conn;
1780}
1781
David Herrmann9c903e32013-04-06 20:28:44 +02001782static void l2cap_conn_free(struct kref *ref)
1783{
1784 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1785
1786 hci_conn_put(conn->hcon);
1787 kfree(conn);
1788}
1789
1790void l2cap_conn_get(struct l2cap_conn *conn)
1791{
1792 kref_get(&conn->ref);
1793}
1794EXPORT_SYMBOL(l2cap_conn_get);
1795
1796void l2cap_conn_put(struct l2cap_conn *conn)
1797{
1798 kref_put(&conn->ref, l2cap_conn_free);
1799}
1800EXPORT_SYMBOL(l2cap_conn_put);
1801
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803
Ido Yarivc2287682012-04-20 15:46:07 -03001804/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 * Returns closest match.
1806 */
Ido Yarivc2287682012-04-20 15:46:07 -03001807static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1808 bdaddr_t *src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001809 bdaddr_t *dst,
1810 u8 link_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001812 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001814 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001815
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001816 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001817 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818 continue;
1819
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001820 if (link_type == ACL_LINK && c->src_type != BDADDR_BREDR)
1821 continue;
1822
1823 if (link_type == LE_LINK && c->src_type == BDADDR_BREDR)
1824 continue;
1825
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001826 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001827 int src_match, dst_match;
1828 int src_any, dst_any;
1829
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001831 src_match = !bacmp(&c->src, src);
1832 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001833 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001834 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001835 return c;
1836 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837
1838 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001839 src_any = !bacmp(&c->src, BDADDR_ANY);
1840 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001841 if ((src_match && dst_any) || (src_any && dst_match) ||
1842 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001843 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844 }
1845 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001847 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001848
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001849 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850}
1851
Johan Hedberg49460962013-10-08 13:55:46 +02001852static bool is_valid_psm(u16 psm, u8 dst_type)
1853{
1854 if (!psm)
1855 return false;
1856
1857 if (bdaddr_type_is_le(dst_type))
1858 return (psm < 0x00ff);
1859
1860 /* PSM must be odd and lsb of upper byte must be 0 */
1861 return ((psm & 0x0101) == 0x0001);
1862}
1863
Andre Guedes8e9f9892012-04-24 21:02:55 -03001864int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1865 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 struct l2cap_conn *conn;
1868 struct hci_conn *hcon;
1869 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001870 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001871 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001872
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001873 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301874 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001876 hdev = hci_get_route(dst, &chan->src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001877 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878 return -EHOSTUNREACH;
1879
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001880 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001882 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001883
Johan Hedberg49460962013-10-08 13:55:46 +02001884 if (!is_valid_psm(__le16_to_cpu(psm), dst_type) && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001885 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001886 err = -EINVAL;
1887 goto done;
1888 }
1889
1890 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1891 err = -EINVAL;
1892 goto done;
1893 }
1894
1895 switch (chan->mode) {
1896 case L2CAP_MODE_BASIC:
Johan Hedberg0ce43ce2013-12-05 14:55:33 +02001897 break;
Johan Hedberg38319712013-05-17 12:49:23 +03001898 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedberg0ce43ce2013-12-05 14:55:33 +02001899 l2cap_le_flowctl_init(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001900 break;
1901 case L2CAP_MODE_ERTM:
1902 case L2CAP_MODE_STREAMING:
1903 if (!disable_ertm)
1904 break;
1905 /* fall through */
1906 default:
1907 err = -ENOTSUPP;
1908 goto done;
1909 }
1910
Gustavo Padovan0797e012012-05-27 22:27:54 -03001911 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001912 case BT_CONNECT:
1913 case BT_CONNECT2:
1914 case BT_CONFIG:
1915 /* Already connecting */
1916 err = 0;
1917 goto done;
1918
1919 case BT_CONNECTED:
1920 /* Already connected */
1921 err = -EISCONN;
1922 goto done;
1923
1924 case BT_OPEN:
1925 case BT_BOUND:
1926 /* Can connect */
1927 break;
1928
1929 default:
1930 err = -EBADFD;
1931 goto done;
1932 }
1933
1934 /* Set destination address and psm */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001935 bacpy(&chan->dst, dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001936 chan->dst_type = dst_type;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001937
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001938 chan->psm = psm;
1939 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001941 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001942
Johan Hedbergf224ca52013-04-29 19:35:36 +03001943 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001944 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001945 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001946 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001947 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001948 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001949
Ville Tervo30e76272011-02-22 16:10:53 -03001950 if (IS_ERR(hcon)) {
1951 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001952 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001953 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001954
Claudio Takahasibaf43252013-04-11 13:55:50 -03001955 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001957 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001958 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959 goto done;
1960 }
1961
Johan Hedberg141d5702013-04-29 19:35:37 +03001962 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1963 hci_conn_drop(hcon);
1964 err = -EBUSY;
1965 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001966 }
1967
Linus Torvalds1da177e2005-04-16 15:20:36 -07001968 /* Update source addr of the socket */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001969 bacpy(&chan->src, &hcon->src);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001970 chan->src_type = bdaddr_type(hcon, hcon->src_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001971
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001972 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001973 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001974 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001975
Johan Hedberg5ee98912013-04-29 19:35:43 +03001976 /* l2cap_chan_add takes its own ref so we can drop this one */
1977 hci_conn_drop(hcon);
1978
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001979 l2cap_state_change(chan, BT_CONNECT);
Gustavo Padovan8d836d72013-10-15 19:24:47 -03001980 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981
1982 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001983 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001984 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001985 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001986 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001987 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001988 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001989 }
1990
Ville Tervo30e76272011-02-22 16:10:53 -03001991 err = 0;
1992
Linus Torvalds1da177e2005-04-16 15:20:36 -07001993done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001994 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001995 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001996 hci_dev_put(hdev);
1997 return err;
1998}
1999
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002000static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002001{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002002 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07002003 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002004
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03002005 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002006
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002007 l2cap_chan_lock(chan);
2008
Mat Martineau80909e02012-05-17 20:53:50 -07002009 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002010 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02002011 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002012 return;
2013 }
2014
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002015 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002016
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002017 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02002018 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002019}
2020
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002021static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002022{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002023 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07002024 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002025
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03002026 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002027
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002028 l2cap_chan_lock(chan);
2029
Mat Martineau80909e02012-05-17 20:53:50 -07002030 if (!chan->conn) {
2031 l2cap_chan_unlock(chan);
2032 l2cap_chan_put(chan);
2033 return;
2034 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002035
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002036 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002037 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02002038 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002039}
2040
Gustavo Padovand6603662012-05-21 13:58:22 -03002041static void l2cap_streaming_send(struct l2cap_chan *chan,
2042 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002043{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03002044 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07002045 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002046
Mat Martineau37339372012-05-17 20:53:33 -07002047 BT_DBG("chan %p, skbs %p", chan, skbs);
2048
Mat Martineaub99e13a2012-10-23 15:24:19 -07002049 if (__chan_is_moving(chan))
2050 return;
2051
Mat Martineau37339372012-05-17 20:53:33 -07002052 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2053
2054 while (!skb_queue_empty(&chan->tx_q)) {
2055
2056 skb = skb_dequeue(&chan->tx_q);
2057
2058 bt_cb(skb)->control.retries = 1;
2059 control = &bt_cb(skb)->control;
2060
2061 control->reqseq = 0;
2062 control->txseq = chan->next_tx_seq;
2063
2064 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002065
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002066 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07002067 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2068 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002069 }
2070
Gustavo F. Padovan43434782011-04-12 18:31:57 -03002071 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002072
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002073 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07002074
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002075 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07002076 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002077 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002078}
2079
Szymon Janc67c9e842011-07-28 16:24:33 +02002080static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002081{
2082 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07002083 struct l2cap_ctrl *control;
2084 int sent = 0;
2085
2086 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002087
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03002088 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03002089 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002090
Mat Martineau94122bb2012-05-02 09:42:02 -07002091 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2092 return 0;
2093
Mat Martineaub99e13a2012-10-23 15:24:19 -07002094 if (__chan_is_moving(chan))
2095 return 0;
2096
Mat Martineau18a48e72012-05-17 20:53:34 -07002097 while (chan->tx_send_head &&
2098 chan->unacked_frames < chan->remote_tx_win &&
2099 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002100
Mat Martineau18a48e72012-05-17 20:53:34 -07002101 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002102
Mat Martineau18a48e72012-05-17 20:53:34 -07002103 bt_cb(skb)->control.retries = 1;
2104 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03002105
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002106 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07002107 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002108
Mat Martineau18a48e72012-05-17 20:53:34 -07002109 control->reqseq = chan->buffer_seq;
2110 chan->last_acked_seq = chan->buffer_seq;
2111 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002112
Mat Martineau18a48e72012-05-17 20:53:34 -07002113 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002114
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002115 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002116 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2117 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002118 }
2119
Mat Martineau18a48e72012-05-17 20:53:34 -07002120 /* Clone after data has been modified. Data is assumed to be
2121 read-only (for locking purposes) on cloned sk_buffs.
2122 */
2123 tx_skb = skb_clone(skb, GFP_KERNEL);
2124
2125 if (!tx_skb)
2126 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002127
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002128 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002129
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002130 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002131 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002132 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002133 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002134
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002135 if (skb_queue_is_last(&chan->tx_q, skb))
2136 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002137 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002138 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002139
2140 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002141 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002142 }
2143
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002144 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2145 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002146
2147 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002148}
2149
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002150static void l2cap_ertm_resend(struct l2cap_chan *chan)
2151{
2152 struct l2cap_ctrl control;
2153 struct sk_buff *skb;
2154 struct sk_buff *tx_skb;
2155 u16 seq;
2156
2157 BT_DBG("chan %p", chan);
2158
2159 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2160 return;
2161
Mat Martineaub99e13a2012-10-23 15:24:19 -07002162 if (__chan_is_moving(chan))
2163 return;
2164
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002165 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2166 seq = l2cap_seq_list_pop(&chan->retrans_list);
2167
2168 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2169 if (!skb) {
2170 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002171 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002172 continue;
2173 }
2174
2175 bt_cb(skb)->control.retries++;
2176 control = bt_cb(skb)->control;
2177
2178 if (chan->max_tx != 0 &&
2179 bt_cb(skb)->control.retries > chan->max_tx) {
2180 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002181 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002182 l2cap_seq_list_clear(&chan->retrans_list);
2183 break;
2184 }
2185
2186 control.reqseq = chan->buffer_seq;
2187 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2188 control.final = 1;
2189 else
2190 control.final = 0;
2191
2192 if (skb_cloned(skb)) {
2193 /* Cloned sk_buffs are read-only, so we need a
2194 * writeable copy
2195 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002196 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002197 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002198 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002199 }
2200
2201 if (!tx_skb) {
2202 l2cap_seq_list_clear(&chan->retrans_list);
2203 break;
2204 }
2205
2206 /* Update skb contents */
2207 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2208 put_unaligned_le32(__pack_extended_control(&control),
2209 tx_skb->data + L2CAP_HDR_SIZE);
2210 } else {
2211 put_unaligned_le16(__pack_enhanced_control(&control),
2212 tx_skb->data + L2CAP_HDR_SIZE);
2213 }
2214
2215 if (chan->fcs == L2CAP_FCS_CRC16) {
2216 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2217 put_unaligned_le16(fcs, skb_put(tx_skb,
2218 L2CAP_FCS_SIZE));
2219 }
2220
2221 l2cap_do_send(chan, tx_skb);
2222
2223 BT_DBG("Resent txseq %d", control.txseq);
2224
2225 chan->last_acked_seq = chan->buffer_seq;
2226 }
2227}
2228
Mat Martineauf80842a2012-05-17 20:53:46 -07002229static void l2cap_retransmit(struct l2cap_chan *chan,
2230 struct l2cap_ctrl *control)
2231{
2232 BT_DBG("chan %p, control %p", chan, control);
2233
2234 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2235 l2cap_ertm_resend(chan);
2236}
2237
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002238static void l2cap_retransmit_all(struct l2cap_chan *chan,
2239 struct l2cap_ctrl *control)
2240{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002241 struct sk_buff *skb;
2242
2243 BT_DBG("chan %p, control %p", chan, control);
2244
2245 if (control->poll)
2246 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2247
2248 l2cap_seq_list_clear(&chan->retrans_list);
2249
2250 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2251 return;
2252
2253 if (chan->unacked_frames) {
2254 skb_queue_walk(&chan->tx_q, skb) {
2255 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002256 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002257 break;
2258 }
2259
2260 skb_queue_walk_from(&chan->tx_q, skb) {
2261 if (skb == chan->tx_send_head)
2262 break;
2263
2264 l2cap_seq_list_append(&chan->retrans_list,
2265 bt_cb(skb)->control.txseq);
2266 }
2267
2268 l2cap_ertm_resend(chan);
2269 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002270}
2271
Szymon Jancb17e73b2012-01-11 10:59:47 +01002272static void l2cap_send_ack(struct l2cap_chan *chan)
2273{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002274 struct l2cap_ctrl control;
2275 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2276 chan->last_acked_seq);
2277 int threshold;
2278
2279 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2280 chan, chan->last_acked_seq, chan->buffer_seq);
2281
2282 memset(&control, 0, sizeof(control));
2283 control.sframe = 1;
2284
2285 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2286 chan->rx_state == L2CAP_RX_STATE_RECV) {
2287 __clear_ack_timer(chan);
2288 control.super = L2CAP_SUPER_RNR;
2289 control.reqseq = chan->buffer_seq;
2290 l2cap_send_sframe(chan, &control);
2291 } else {
2292 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2293 l2cap_ertm_send(chan);
2294 /* If any i-frames were sent, they included an ack */
2295 if (chan->buffer_seq == chan->last_acked_seq)
2296 frames_to_ack = 0;
2297 }
2298
Mat Martineauc20f8e32012-07-10 05:47:07 -07002299 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002300 * Calculate without mul or div
2301 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002302 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002303 threshold += threshold << 1;
2304 threshold >>= 2;
2305
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002306 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002307 threshold);
2308
2309 if (frames_to_ack >= threshold) {
2310 __clear_ack_timer(chan);
2311 control.super = L2CAP_SUPER_RR;
2312 control.reqseq = chan->buffer_seq;
2313 l2cap_send_sframe(chan, &control);
2314 frames_to_ack = 0;
2315 }
2316
2317 if (frames_to_ack)
2318 __set_ack_timer(chan);
2319 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002320}
2321
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002322static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2323 struct msghdr *msg, int len,
2324 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002325{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002326 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002327 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002328 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002330 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002331 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002332
2333 sent += count;
2334 len -= count;
2335
2336 /* Continuation fragments (no L2CAP header) */
2337 frag = &skb_shinfo(skb)->frag_list;
2338 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002339 struct sk_buff *tmp;
2340
Linus Torvalds1da177e2005-04-16 15:20:36 -07002341 count = min_t(unsigned int, conn->mtu, len);
2342
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002343 tmp = chan->ops->alloc_skb(chan, count,
2344 msg->msg_flags & MSG_DONTWAIT);
2345 if (IS_ERR(tmp))
2346 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002347
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002348 *frag = tmp;
2349
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002350 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2351 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002352
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002353 (*frag)->priority = skb->priority;
2354
Linus Torvalds1da177e2005-04-16 15:20:36 -07002355 sent += count;
2356 len -= count;
2357
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002358 skb->len += (*frag)->len;
2359 skb->data_len += (*frag)->len;
2360
Linus Torvalds1da177e2005-04-16 15:20:36 -07002361 frag = &(*frag)->next;
2362 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002363
2364 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002365}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002366
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002367static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002368 struct msghdr *msg, size_t len,
2369 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002370{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002371 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002372 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002373 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002374 struct l2cap_hdr *lh;
2375
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002376 BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
2377 __le16_to_cpu(chan->psm), len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002378
2379 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002380
2381 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002382 msg->msg_flags & MSG_DONTWAIT);
2383 if (IS_ERR(skb))
2384 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002385
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002386 skb->priority = priority;
2387
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002388 /* Create L2CAP header */
2389 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002390 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002391 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002392 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002393
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002394 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002395 if (unlikely(err < 0)) {
2396 kfree_skb(skb);
2397 return ERR_PTR(err);
2398 }
2399 return skb;
2400}
2401
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002402static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002403 struct msghdr *msg, size_t len,
2404 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002405{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002406 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002407 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002408 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002409 struct l2cap_hdr *lh;
2410
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002411 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002412
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002413 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002414
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002415 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002416 msg->msg_flags & MSG_DONTWAIT);
2417 if (IS_ERR(skb))
2418 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002419
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002420 skb->priority = priority;
2421
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002422 /* Create L2CAP header */
2423 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002424 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002425 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002426
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002427 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002428 if (unlikely(err < 0)) {
2429 kfree_skb(skb);
2430 return ERR_PTR(err);
2431 }
2432 return skb;
2433}
2434
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002435static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002436 struct msghdr *msg, size_t len,
2437 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002438{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002439 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002440 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002441 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002442 struct l2cap_hdr *lh;
2443
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002444 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002445
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002446 if (!conn)
2447 return ERR_PTR(-ENOTCONN);
2448
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002449 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002450
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002451 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002452 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002453
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002454 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002455 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002456
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002457 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002458
2459 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002460 msg->msg_flags & MSG_DONTWAIT);
2461 if (IS_ERR(skb))
2462 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002463
2464 /* Create L2CAP header */
2465 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002466 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002467 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002468
Mat Martineau18a48e72012-05-17 20:53:34 -07002469 /* Control header is populated later */
2470 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2471 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2472 else
2473 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002474
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002475 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002476 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002477
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002478 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002479 if (unlikely(err < 0)) {
2480 kfree_skb(skb);
2481 return ERR_PTR(err);
2482 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002483
Mat Martineau18a48e72012-05-17 20:53:34 -07002484 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002485 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002486 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002487}
2488
Mat Martineau94122bb2012-05-02 09:42:02 -07002489static int l2cap_segment_sdu(struct l2cap_chan *chan,
2490 struct sk_buff_head *seg_queue,
2491 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002492{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002493 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002494 u16 sdu_len;
2495 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002496 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002497
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002498 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002499
Mat Martineau94122bb2012-05-02 09:42:02 -07002500 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2501 * so fragmented skbs are not used. The HCI layer's handling
2502 * of fragmented skbs is not compatible with ERTM's queueing.
2503 */
2504
2505 /* PDU size is derived from the HCI MTU */
2506 pdu_len = chan->conn->mtu;
2507
Mat Martineaua5495742012-10-23 15:24:21 -07002508 /* Constrain PDU size for BR/EDR connections */
2509 if (!chan->hs_hcon)
2510 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002511
2512 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002513 if (chan->fcs)
2514 pdu_len -= L2CAP_FCS_SIZE;
2515
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002516 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002517
2518 /* Remote device may have requested smaller PDUs */
2519 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2520
2521 if (len <= pdu_len) {
2522 sar = L2CAP_SAR_UNSEGMENTED;
2523 sdu_len = 0;
2524 pdu_len = len;
2525 } else {
2526 sar = L2CAP_SAR_START;
2527 sdu_len = len;
2528 pdu_len -= L2CAP_SDULEN_SIZE;
2529 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002530
2531 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002532 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002533
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002534 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002535 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002536 return PTR_ERR(skb);
2537 }
2538
Mat Martineau94122bb2012-05-02 09:42:02 -07002539 bt_cb(skb)->control.sar = sar;
2540 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002541
Mat Martineau94122bb2012-05-02 09:42:02 -07002542 len -= pdu_len;
2543 if (sdu_len) {
2544 sdu_len = 0;
2545 pdu_len += L2CAP_SDULEN_SIZE;
2546 }
2547
2548 if (len <= pdu_len) {
2549 sar = L2CAP_SAR_END;
2550 pdu_len = len;
2551 } else {
2552 sar = L2CAP_SAR_CONTINUE;
2553 }
2554 }
2555
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002556 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002557}
2558
Johan Hedberg177f8f22013-05-31 17:54:51 +03002559static struct sk_buff *l2cap_create_le_flowctl_pdu(struct l2cap_chan *chan,
2560 struct msghdr *msg,
2561 size_t len, u16 sdulen)
2562{
2563 struct l2cap_conn *conn = chan->conn;
2564 struct sk_buff *skb;
2565 int err, count, hlen;
2566 struct l2cap_hdr *lh;
2567
2568 BT_DBG("chan %p len %zu", chan, len);
2569
2570 if (!conn)
2571 return ERR_PTR(-ENOTCONN);
2572
2573 hlen = L2CAP_HDR_SIZE;
2574
2575 if (sdulen)
2576 hlen += L2CAP_SDULEN_SIZE;
2577
2578 count = min_t(unsigned int, (conn->mtu - hlen), len);
2579
2580 skb = chan->ops->alloc_skb(chan, count + hlen,
2581 msg->msg_flags & MSG_DONTWAIT);
2582 if (IS_ERR(skb))
2583 return skb;
2584
2585 /* Create L2CAP header */
2586 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
2587 lh->cid = cpu_to_le16(chan->dcid);
2588 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
2589
2590 if (sdulen)
2591 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
2592
2593 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
2594 if (unlikely(err < 0)) {
2595 kfree_skb(skb);
2596 return ERR_PTR(err);
2597 }
2598
2599 return skb;
2600}
2601
2602static int l2cap_segment_le_sdu(struct l2cap_chan *chan,
2603 struct sk_buff_head *seg_queue,
2604 struct msghdr *msg, size_t len)
2605{
2606 struct sk_buff *skb;
2607 size_t pdu_len;
2608 u16 sdu_len;
2609
2610 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
2611
2612 pdu_len = chan->conn->mtu - L2CAP_HDR_SIZE;
2613
2614 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2615
2616 sdu_len = len;
2617 pdu_len -= L2CAP_SDULEN_SIZE;
2618
2619 while (len > 0) {
2620 if (len <= pdu_len)
2621 pdu_len = len;
2622
2623 skb = l2cap_create_le_flowctl_pdu(chan, msg, pdu_len, sdu_len);
2624 if (IS_ERR(skb)) {
2625 __skb_queue_purge(seg_queue);
2626 return PTR_ERR(skb);
2627 }
2628
2629 __skb_queue_tail(seg_queue, skb);
2630
2631 len -= pdu_len;
2632
2633 if (sdu_len) {
2634 sdu_len = 0;
2635 pdu_len += L2CAP_SDULEN_SIZE;
2636 }
2637 }
2638
2639 return 0;
2640}
2641
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002642int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002643 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002644{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002645 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002646 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002647 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002648
Seung-Woo Kim31e8ce82013-11-05 18:46:33 +09002649 if (!chan->conn)
2650 return -ENOTCONN;
2651
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002652 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002653 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002654 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002655 if (IS_ERR(skb))
2656 return PTR_ERR(skb);
2657
2658 l2cap_do_send(chan, skb);
2659 return len;
2660 }
2661
2662 switch (chan->mode) {
Johan Hedberg38319712013-05-17 12:49:23 +03002663 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedberg177f8f22013-05-31 17:54:51 +03002664 /* Check outgoing MTU */
2665 if (len > chan->omtu)
2666 return -EMSGSIZE;
2667
Johan Hedbergfad5fc82013-12-05 09:45:01 +02002668 if (!chan->tx_credits)
2669 return -EAGAIN;
2670
Johan Hedberg177f8f22013-05-31 17:54:51 +03002671 __skb_queue_head_init(&seg_queue);
2672
2673 err = l2cap_segment_le_sdu(chan, &seg_queue, msg, len);
2674
2675 if (chan->state != BT_CONNECTED) {
2676 __skb_queue_purge(&seg_queue);
2677 err = -ENOTCONN;
2678 }
2679
2680 if (err)
2681 return err;
2682
2683 skb_queue_splice_tail_init(&seg_queue, &chan->tx_q);
2684
2685 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
2686 l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
2687 chan->tx_credits--;
2688 }
2689
2690 if (!chan->tx_credits)
2691 chan->ops->suspend(chan);
2692
2693 err = len;
2694
2695 break;
2696
Johan Hedbergfad5fc82013-12-05 09:45:01 +02002697 case L2CAP_MODE_BASIC:
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002698 /* Check outgoing MTU */
2699 if (len > chan->omtu)
2700 return -EMSGSIZE;
2701
2702 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002703 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002704 if (IS_ERR(skb))
2705 return PTR_ERR(skb);
2706
2707 l2cap_do_send(chan, skb);
2708 err = len;
2709 break;
2710
2711 case L2CAP_MODE_ERTM:
2712 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002713 /* Check outgoing MTU */
2714 if (len > chan->omtu) {
2715 err = -EMSGSIZE;
2716 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002717 }
2718
Mat Martineau94122bb2012-05-02 09:42:02 -07002719 __skb_queue_head_init(&seg_queue);
2720
2721 /* Do segmentation before calling in to the state machine,
2722 * since it's possible to block while waiting for memory
2723 * allocation.
2724 */
2725 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2726
2727 /* The channel could have been closed while segmenting,
2728 * check that it is still connected.
2729 */
2730 if (chan->state != BT_CONNECTED) {
2731 __skb_queue_purge(&seg_queue);
2732 err = -ENOTCONN;
2733 }
2734
2735 if (err)
2736 break;
2737
Mat Martineau37339372012-05-17 20:53:33 -07002738 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002739 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002740 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002741 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002742
Gustavo Padovand6603662012-05-21 13:58:22 -03002743 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002744
Mat Martineau94122bb2012-05-02 09:42:02 -07002745 /* If the skbs were not queued for sending, they'll still be in
2746 * seg_queue and need to be purged.
2747 */
2748 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002749 break;
2750
2751 default:
2752 BT_DBG("bad state %1.1x", chan->mode);
2753 err = -EBADFD;
2754 }
2755
2756 return err;
2757}
2758
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002759static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2760{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002761 struct l2cap_ctrl control;
2762 u16 seq;
2763
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002764 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002765
2766 memset(&control, 0, sizeof(control));
2767 control.sframe = 1;
2768 control.super = L2CAP_SUPER_SREJ;
2769
2770 for (seq = chan->expected_tx_seq; seq != txseq;
2771 seq = __next_seq(chan, seq)) {
2772 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2773 control.reqseq = seq;
2774 l2cap_send_sframe(chan, &control);
2775 l2cap_seq_list_append(&chan->srej_list, seq);
2776 }
2777 }
2778
2779 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002780}
2781
2782static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2783{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002784 struct l2cap_ctrl control;
2785
2786 BT_DBG("chan %p", chan);
2787
2788 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2789 return;
2790
2791 memset(&control, 0, sizeof(control));
2792 control.sframe = 1;
2793 control.super = L2CAP_SUPER_SREJ;
2794 control.reqseq = chan->srej_list.tail;
2795 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002796}
2797
2798static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2799{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002800 struct l2cap_ctrl control;
2801 u16 initial_head;
2802 u16 seq;
2803
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002804 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002805
2806 memset(&control, 0, sizeof(control));
2807 control.sframe = 1;
2808 control.super = L2CAP_SUPER_SREJ;
2809
2810 /* Capture initial list head to allow only one pass through the list. */
2811 initial_head = chan->srej_list.head;
2812
2813 do {
2814 seq = l2cap_seq_list_pop(&chan->srej_list);
2815 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2816 break;
2817
2818 control.reqseq = seq;
2819 l2cap_send_sframe(chan, &control);
2820 l2cap_seq_list_append(&chan->srej_list, seq);
2821 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002822}
2823
Mat Martineau608bcc62012-05-17 20:53:32 -07002824static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2825{
2826 struct sk_buff *acked_skb;
2827 u16 ackseq;
2828
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002829 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002830
2831 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2832 return;
2833
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002834 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002835 chan->expected_ack_seq, chan->unacked_frames);
2836
2837 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2838 ackseq = __next_seq(chan, ackseq)) {
2839
2840 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2841 if (acked_skb) {
2842 skb_unlink(acked_skb, &chan->tx_q);
2843 kfree_skb(acked_skb);
2844 chan->unacked_frames--;
2845 }
2846 }
2847
2848 chan->expected_ack_seq = reqseq;
2849
2850 if (chan->unacked_frames == 0)
2851 __clear_retrans_timer(chan);
2852
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002853 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002854}
2855
2856static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2857{
2858 BT_DBG("chan %p", chan);
2859
2860 chan->expected_tx_seq = chan->buffer_seq;
2861 l2cap_seq_list_clear(&chan->srej_list);
2862 skb_queue_purge(&chan->srej_q);
2863 chan->rx_state = L2CAP_RX_STATE_RECV;
2864}
2865
Gustavo Padovand6603662012-05-21 13:58:22 -03002866static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2867 struct l2cap_ctrl *control,
2868 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002869{
Mat Martineau608bcc62012-05-17 20:53:32 -07002870 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2871 event);
2872
2873 switch (event) {
2874 case L2CAP_EV_DATA_REQUEST:
2875 if (chan->tx_send_head == NULL)
2876 chan->tx_send_head = skb_peek(skbs);
2877
2878 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2879 l2cap_ertm_send(chan);
2880 break;
2881 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2882 BT_DBG("Enter LOCAL_BUSY");
2883 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2884
2885 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2886 /* The SREJ_SENT state must be aborted if we are to
2887 * enter the LOCAL_BUSY state.
2888 */
2889 l2cap_abort_rx_srej_sent(chan);
2890 }
2891
2892 l2cap_send_ack(chan);
2893
2894 break;
2895 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2896 BT_DBG("Exit LOCAL_BUSY");
2897 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2898
2899 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2900 struct l2cap_ctrl local_control;
2901
2902 memset(&local_control, 0, sizeof(local_control));
2903 local_control.sframe = 1;
2904 local_control.super = L2CAP_SUPER_RR;
2905 local_control.poll = 1;
2906 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002907 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002908
2909 chan->retry_count = 1;
2910 __set_monitor_timer(chan);
2911 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2912 }
2913 break;
2914 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2915 l2cap_process_reqseq(chan, control->reqseq);
2916 break;
2917 case L2CAP_EV_EXPLICIT_POLL:
2918 l2cap_send_rr_or_rnr(chan, 1);
2919 chan->retry_count = 1;
2920 __set_monitor_timer(chan);
2921 __clear_ack_timer(chan);
2922 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2923 break;
2924 case L2CAP_EV_RETRANS_TO:
2925 l2cap_send_rr_or_rnr(chan, 1);
2926 chan->retry_count = 1;
2927 __set_monitor_timer(chan);
2928 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2929 break;
2930 case L2CAP_EV_RECV_FBIT:
2931 /* Nothing to process */
2932 break;
2933 default:
2934 break;
2935 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002936}
2937
Gustavo Padovand6603662012-05-21 13:58:22 -03002938static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2939 struct l2cap_ctrl *control,
2940 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002941{
Mat Martineau608bcc62012-05-17 20:53:32 -07002942 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2943 event);
2944
2945 switch (event) {
2946 case L2CAP_EV_DATA_REQUEST:
2947 if (chan->tx_send_head == NULL)
2948 chan->tx_send_head = skb_peek(skbs);
2949 /* Queue data, but don't send. */
2950 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2951 break;
2952 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2953 BT_DBG("Enter LOCAL_BUSY");
2954 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2955
2956 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2957 /* The SREJ_SENT state must be aborted if we are to
2958 * enter the LOCAL_BUSY state.
2959 */
2960 l2cap_abort_rx_srej_sent(chan);
2961 }
2962
2963 l2cap_send_ack(chan);
2964
2965 break;
2966 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2967 BT_DBG("Exit LOCAL_BUSY");
2968 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2969
2970 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2971 struct l2cap_ctrl local_control;
2972 memset(&local_control, 0, sizeof(local_control));
2973 local_control.sframe = 1;
2974 local_control.super = L2CAP_SUPER_RR;
2975 local_control.poll = 1;
2976 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002977 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002978
2979 chan->retry_count = 1;
2980 __set_monitor_timer(chan);
2981 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2982 }
2983 break;
2984 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2985 l2cap_process_reqseq(chan, control->reqseq);
2986
2987 /* Fall through */
2988
2989 case L2CAP_EV_RECV_FBIT:
2990 if (control && control->final) {
2991 __clear_monitor_timer(chan);
2992 if (chan->unacked_frames > 0)
2993 __set_retrans_timer(chan);
2994 chan->retry_count = 0;
2995 chan->tx_state = L2CAP_TX_STATE_XMIT;
2996 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2997 }
2998 break;
2999 case L2CAP_EV_EXPLICIT_POLL:
3000 /* Ignore */
3001 break;
3002 case L2CAP_EV_MONITOR_TO:
3003 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
3004 l2cap_send_rr_or_rnr(chan, 1);
3005 __set_monitor_timer(chan);
3006 chan->retry_count++;
3007 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02003008 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07003009 }
3010 break;
3011 default:
3012 break;
3013 }
Mat Martineau608bcc62012-05-17 20:53:32 -07003014}
3015
Gustavo Padovand6603662012-05-21 13:58:22 -03003016static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
3017 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07003018{
Mat Martineau608bcc62012-05-17 20:53:32 -07003019 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
3020 chan, control, skbs, event, chan->tx_state);
3021
3022 switch (chan->tx_state) {
3023 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03003024 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07003025 break;
3026 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03003027 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07003028 break;
3029 default:
3030 /* Ignore event */
3031 break;
3032 }
Mat Martineau608bcc62012-05-17 20:53:32 -07003033}
3034
Mat Martineau4b51dae92012-05-17 20:53:37 -07003035static void l2cap_pass_to_tx(struct l2cap_chan *chan,
3036 struct l2cap_ctrl *control)
3037{
3038 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03003039 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07003040}
3041
Mat Martineauf80842a2012-05-17 20:53:46 -07003042static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
3043 struct l2cap_ctrl *control)
3044{
3045 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03003046 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07003047}
3048
Linus Torvalds1da177e2005-04-16 15:20:36 -07003049/* Copy frame to all raw sockets on that connection */
3050static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
3051{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003052 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003053 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003054
3055 BT_DBG("conn %p", conn);
3056
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003057 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02003058
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003059 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03003060 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003061 continue;
3062
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02003063 /* Don't send frame to the channel it came from */
3064 if (bt_cb(skb)->chan == chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003065 continue;
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02003066
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03003067 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003068 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003069 continue;
Gustavo Padovan80b98022012-05-27 22:27:51 -03003070 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003071 kfree_skb(nskb);
3072 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02003073
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003074 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003075}
3076
3077/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003078static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
3079 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003080{
3081 struct sk_buff *skb, **frag;
3082 struct l2cap_cmd_hdr *cmd;
3083 struct l2cap_hdr *lh;
3084 int len, count;
3085
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003086 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
3087 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003088
Anderson Lizardo300b9622013-06-02 16:30:40 -04003089 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
3090 return NULL;
3091
Linus Torvalds1da177e2005-04-16 15:20:36 -07003092 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
3093 count = min_t(unsigned int, conn->mtu, len);
3094
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03003095 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003096 if (!skb)
3097 return NULL;
3098
3099 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003100 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02003101
3102 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003103 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02003104 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003105 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003106
3107 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
3108 cmd->code = code;
3109 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003110 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003111
3112 if (dlen) {
3113 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
3114 memcpy(skb_put(skb, count), data, count);
3115 data += count;
3116 }
3117
3118 len -= skb->len;
3119
3120 /* Continuation fragments (no L2CAP header) */
3121 frag = &skb_shinfo(skb)->frag_list;
3122 while (len) {
3123 count = min_t(unsigned int, conn->mtu, len);
3124
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03003125 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003126 if (!*frag)
3127 goto fail;
3128
3129 memcpy(skb_put(*frag, count), data, count);
3130
3131 len -= count;
3132 data += count;
3133
3134 frag = &(*frag)->next;
3135 }
3136
3137 return skb;
3138
3139fail:
3140 kfree_skb(skb);
3141 return NULL;
3142}
3143
Gustavo Padovan2d792812012-10-06 10:07:01 +01003144static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
3145 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003146{
3147 struct l2cap_conf_opt *opt = *ptr;
3148 int len;
3149
3150 len = L2CAP_CONF_OPT_SIZE + opt->len;
3151 *ptr += len;
3152
3153 *type = opt->type;
3154 *olen = opt->len;
3155
3156 switch (opt->len) {
3157 case 1:
3158 *val = *((u8 *) opt->val);
3159 break;
3160
3161 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04003162 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003163 break;
3164
3165 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04003166 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003167 break;
3168
3169 default:
3170 *val = (unsigned long) opt->val;
3171 break;
3172 }
3173
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003174 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003175 return len;
3176}
3177
Linus Torvalds1da177e2005-04-16 15:20:36 -07003178static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
3179{
3180 struct l2cap_conf_opt *opt = *ptr;
3181
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003182 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003183
3184 opt->type = type;
3185 opt->len = len;
3186
3187 switch (len) {
3188 case 1:
3189 *((u8 *) opt->val) = val;
3190 break;
3191
3192 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003193 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003194 break;
3195
3196 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003197 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003198 break;
3199
3200 default:
3201 memcpy(opt->val, (void *) val, len);
3202 break;
3203 }
3204
3205 *ptr += L2CAP_CONF_OPT_SIZE + len;
3206}
3207
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003208static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
3209{
3210 struct l2cap_conf_efs efs;
3211
Szymon Janc1ec918c2011-11-16 09:32:21 +01003212 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003213 case L2CAP_MODE_ERTM:
3214 efs.id = chan->local_id;
3215 efs.stype = chan->local_stype;
3216 efs.msdu = cpu_to_le16(chan->local_msdu);
3217 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003218 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003219 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003220 break;
3221
3222 case L2CAP_MODE_STREAMING:
3223 efs.id = 1;
3224 efs.stype = L2CAP_SERV_BESTEFFORT;
3225 efs.msdu = cpu_to_le16(chan->local_msdu);
3226 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
3227 efs.acc_lat = 0;
3228 efs.flush_to = 0;
3229 break;
3230
3231 default:
3232 return;
3233 }
3234
3235 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003236 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003237}
3238
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003239static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003240{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003241 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003242 ack_timer.work);
3243 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003244
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003245 BT_DBG("chan %p", chan);
3246
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003247 l2cap_chan_lock(chan);
3248
Mat Martineau03625202012-05-17 20:53:51 -07003249 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3250 chan->last_acked_seq);
3251
3252 if (frames_to_ack)
3253 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003254
3255 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003256 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003257}
3258
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003259int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003260{
Mat Martineau3c588192012-04-11 10:48:42 -07003261 int err;
3262
Mat Martineau105bdf92012-04-27 16:50:48 -07003263 chan->next_tx_seq = 0;
3264 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003265 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003266 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003267 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003268 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003269 chan->last_acked_seq = 0;
3270 chan->sdu = NULL;
3271 chan->sdu_last_frag = NULL;
3272 chan->sdu_len = 0;
3273
Mat Martineaud34c34f2012-05-14 14:49:27 -07003274 skb_queue_head_init(&chan->tx_q);
3275
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003276 chan->local_amp_id = AMP_ID_BREDR;
3277 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003278 chan->move_state = L2CAP_MOVE_STABLE;
3279 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3280
Mat Martineau105bdf92012-04-27 16:50:48 -07003281 if (chan->mode != L2CAP_MODE_ERTM)
3282 return 0;
3283
3284 chan->rx_state = L2CAP_RX_STATE_RECV;
3285 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003286
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003287 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3288 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3289 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003290
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003291 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003292
Mat Martineau3c588192012-04-11 10:48:42 -07003293 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3294 if (err < 0)
3295 return err;
3296
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003297 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3298 if (err < 0)
3299 l2cap_seq_list_free(&chan->srej_list);
3300
3301 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003302}
3303
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003304static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3305{
3306 switch (mode) {
3307 case L2CAP_MODE_STREAMING:
3308 case L2CAP_MODE_ERTM:
3309 if (l2cap_mode_supported(mode, remote_feat_mask))
3310 return mode;
3311 /* fall through */
3312 default:
3313 return L2CAP_MODE_BASIC;
3314 }
3315}
3316
Marcel Holtmann848566b2013-10-01 22:59:22 -07003317static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003318{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003319 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003320}
3321
Marcel Holtmann848566b2013-10-01 22:59:22 -07003322static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003323{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003324 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003325}
3326
Mat Martineau36c86c82012-10-23 15:24:20 -07003327static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3328 struct l2cap_conf_rfc *rfc)
3329{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003330 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003331 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3332
3333 /* Class 1 devices have must have ERTM timeouts
3334 * exceeding the Link Supervision Timeout. The
3335 * default Link Supervision Timeout for AMP
3336 * controllers is 10 seconds.
3337 *
3338 * Class 1 devices use 0xffffffff for their
3339 * best-effort flush timeout, so the clamping logic
3340 * will result in a timeout that meets the above
3341 * requirement. ERTM timeouts are 16-bit values, so
3342 * the maximum timeout is 65.535 seconds.
3343 */
3344
3345 /* Convert timeout to milliseconds and round */
3346 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3347
3348 /* This is the recommended formula for class 2 devices
3349 * that start ERTM timers when packets are sent to the
3350 * controller.
3351 */
3352 ertm_to = 3 * ertm_to + 500;
3353
3354 if (ertm_to > 0xffff)
3355 ertm_to = 0xffff;
3356
3357 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3358 rfc->monitor_timeout = rfc->retrans_timeout;
3359 } else {
3360 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3361 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3362 }
3363}
3364
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003365static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3366{
3367 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003368 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003369 /* use extended control field */
3370 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003371 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3372 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003373 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003374 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003375 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3376 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003377 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003378}
3379
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003380static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003381{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003382 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003383 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003384 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003385 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003386
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003387 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003388
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003389 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003390 goto done;
3391
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003392 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003393 case L2CAP_MODE_STREAMING:
3394 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003395 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003396 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003397
Marcel Holtmann848566b2013-10-01 22:59:22 -07003398 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003399 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3400
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003401 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003402 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003403 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003404 break;
3405 }
3406
3407done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003408 if (chan->imtu != L2CAP_DEFAULT_MTU)
3409 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003410
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003411 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003412 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003413 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003414 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003415 break;
3416
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003417 rfc.mode = L2CAP_MODE_BASIC;
3418 rfc.txwin_size = 0;
3419 rfc.max_transmit = 0;
3420 rfc.retrans_timeout = 0;
3421 rfc.monitor_timeout = 0;
3422 rfc.max_pdu_size = 0;
3423
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003424 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003425 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003426 break;
3427
3428 case L2CAP_MODE_ERTM:
3429 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003430 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003431
3432 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003433
3434 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003435 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3436 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003437 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003438
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003439 l2cap_txwin_setup(chan);
3440
3441 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003442 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003443
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003444 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003445 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003446
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003447 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3448 l2cap_add_opt_efs(&ptr, chan);
3449
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003450 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3451 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003452 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003453
3454 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3455 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003456 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003457 chan->fcs = L2CAP_FCS_NONE;
3458 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3459 chan->fcs);
3460 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003461 break;
3462
3463 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003464 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003465 rfc.mode = L2CAP_MODE_STREAMING;
3466 rfc.txwin_size = 0;
3467 rfc.max_transmit = 0;
3468 rfc.retrans_timeout = 0;
3469 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003470
3471 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003472 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3473 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003474 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003475
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003476 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003477 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003478
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003479 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3480 l2cap_add_opt_efs(&ptr, chan);
3481
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003482 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3483 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003484 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003485 chan->fcs = L2CAP_FCS_NONE;
3486 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3487 chan->fcs);
3488 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003489 break;
3490 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003491
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003492 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003493 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003494
3495 return ptr - data;
3496}
3497
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003498static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003499{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003500 struct l2cap_conf_rsp *rsp = data;
3501 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003502 void *req = chan->conf_req;
3503 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003504 int type, hint, olen;
3505 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003506 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003507 struct l2cap_conf_efs efs;
3508 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003509 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003510 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003511 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003512
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003513 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003514
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003515 while (len >= L2CAP_CONF_OPT_SIZE) {
3516 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003517
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003518 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003519 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003520
3521 switch (type) {
3522 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003523 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003524 break;
3525
3526 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003527 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003528 break;
3529
3530 case L2CAP_CONF_QOS:
3531 break;
3532
Marcel Holtmann6464f352007-10-20 13:39:51 +02003533 case L2CAP_CONF_RFC:
3534 if (olen == sizeof(rfc))
3535 memcpy(&rfc, (void *) val, olen);
3536 break;
3537
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003538 case L2CAP_CONF_FCS:
3539 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003540 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003541 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003542
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003543 case L2CAP_CONF_EFS:
3544 remote_efs = 1;
3545 if (olen == sizeof(efs))
3546 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003547 break;
3548
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003549 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003550 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003551 return -ECONNREFUSED;
3552
3553 set_bit(FLAG_EXT_CTRL, &chan->flags);
3554 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003555 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003556 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003557 break;
3558
3559 default:
3560 if (hint)
3561 break;
3562
3563 result = L2CAP_CONF_UNKNOWN;
3564 *((u8 *) ptr++) = type;
3565 break;
3566 }
3567 }
3568
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003569 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003570 goto done;
3571
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003572 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003573 case L2CAP_MODE_STREAMING:
3574 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003575 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003576 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003577 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003578 break;
3579 }
3580
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003581 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003582 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003583 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3584 else
3585 return -ECONNREFUSED;
3586 }
3587
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003588 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003589 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003590
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003591 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003592 }
3593
3594done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003595 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003596 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003597 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003598
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003599 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003600 return -ECONNREFUSED;
3601
Gustavo Padovan2d792812012-10-06 10:07:01 +01003602 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3603 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003604 }
3605
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003606 if (result == L2CAP_CONF_SUCCESS) {
3607 /* Configure output options and let the other side know
3608 * which ones we don't like. */
3609
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003610 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3611 result = L2CAP_CONF_UNACCEPT;
3612 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003613 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003614 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003615 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003616 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003617
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003618 if (remote_efs) {
3619 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003620 efs.stype != L2CAP_SERV_NOTRAFIC &&
3621 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003622
3623 result = L2CAP_CONF_UNACCEPT;
3624
3625 if (chan->num_conf_req >= 1)
3626 return -ECONNREFUSED;
3627
3628 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003629 sizeof(efs),
3630 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003631 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003632 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003633 result = L2CAP_CONF_PENDING;
3634 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003635 }
3636 }
3637
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003638 switch (rfc.mode) {
3639 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003640 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003641 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003642 break;
3643
3644 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003645 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3646 chan->remote_tx_win = rfc.txwin_size;
3647 else
3648 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3649
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003650 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003651
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003652 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003653 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3654 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003655 rfc.max_pdu_size = cpu_to_le16(size);
3656 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003657
Mat Martineau36c86c82012-10-23 15:24:20 -07003658 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003659
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003660 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003661
3662 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003663 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003664
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003665 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3666 chan->remote_id = efs.id;
3667 chan->remote_stype = efs.stype;
3668 chan->remote_msdu = le16_to_cpu(efs.msdu);
3669 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003670 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003671 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003672 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003673 chan->remote_sdu_itime =
3674 le32_to_cpu(efs.sdu_itime);
3675 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003676 sizeof(efs),
3677 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003678 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003679 break;
3680
3681 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003682 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003683 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3684 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003685 rfc.max_pdu_size = cpu_to_le16(size);
3686 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003687
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003688 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003689
Gustavo Padovan2d792812012-10-06 10:07:01 +01003690 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3691 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003692
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003693 break;
3694
3695 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003696 result = L2CAP_CONF_UNACCEPT;
3697
3698 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003699 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003700 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003701
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003702 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003703 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003704 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003705 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003706 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003707 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003708
3709 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003710}
3711
Gustavo Padovan2d792812012-10-06 10:07:01 +01003712static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3713 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003714{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003715 struct l2cap_conf_req *req = data;
3716 void *ptr = req->data;
3717 int type, olen;
3718 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003719 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003720 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003721
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003722 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003723
3724 while (len >= L2CAP_CONF_OPT_SIZE) {
3725 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3726
3727 switch (type) {
3728 case L2CAP_CONF_MTU:
3729 if (val < L2CAP_DEFAULT_MIN_MTU) {
3730 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003731 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003732 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003733 chan->imtu = val;
3734 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003735 break;
3736
3737 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003738 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003739 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003740 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003741 break;
3742
3743 case L2CAP_CONF_RFC:
3744 if (olen == sizeof(rfc))
3745 memcpy(&rfc, (void *)val, olen);
3746
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003747 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003748 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003749 return -ECONNREFUSED;
3750
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003751 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003752
3753 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003754 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003755 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003756
3757 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003758 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003759 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003760 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003761 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003762
3763 case L2CAP_CONF_EFS:
3764 if (olen == sizeof(efs))
3765 memcpy(&efs, (void *)val, olen);
3766
3767 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003768 efs.stype != L2CAP_SERV_NOTRAFIC &&
3769 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003770 return -ECONNREFUSED;
3771
Gustavo Padovan2d792812012-10-06 10:07:01 +01003772 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3773 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003774 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003775
3776 case L2CAP_CONF_FCS:
3777 if (*result == L2CAP_CONF_PENDING)
3778 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003779 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003780 &chan->conf_state);
3781 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003782 }
3783 }
3784
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003785 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003786 return -ECONNREFUSED;
3787
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003788 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003789
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003790 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003791 switch (rfc.mode) {
3792 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003793 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3794 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3795 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003796 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3797 chan->ack_win = min_t(u16, chan->ack_win,
3798 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003799
3800 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3801 chan->local_msdu = le16_to_cpu(efs.msdu);
3802 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003803 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003804 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3805 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003806 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003807 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003808 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003809
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003810 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003811 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003812 }
3813 }
3814
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003815 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003816 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003817
3818 return ptr - data;
3819}
3820
Gustavo Padovan2d792812012-10-06 10:07:01 +01003821static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3822 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003823{
3824 struct l2cap_conf_rsp *rsp = data;
3825 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003826
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003827 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003828
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003829 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003830 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003831 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003832
3833 return ptr - data;
3834}
3835
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003836void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan)
3837{
3838 struct l2cap_le_conn_rsp rsp;
3839 struct l2cap_conn *conn = chan->conn;
3840
3841 BT_DBG("chan %p", chan);
3842
3843 rsp.dcid = cpu_to_le16(chan->scid);
3844 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02003845 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03003846 rsp.credits = cpu_to_le16(chan->rx_credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003847 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3848
3849 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
3850 &rsp);
3851}
3852
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003853void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003854{
3855 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003856 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003857 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003858 u8 rsp_code;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003859
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003860 rsp.scid = cpu_to_le16(chan->dcid);
3861 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003862 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3863 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003864
3865 if (chan->hs_hcon)
3866 rsp_code = L2CAP_CREATE_CHAN_RSP;
3867 else
3868 rsp_code = L2CAP_CONN_RSP;
3869
3870 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3871
3872 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003873
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003874 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003875 return;
3876
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003877 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003878 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003879 chan->num_conf_req++;
3880}
3881
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003882static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003883{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003884 int type, olen;
3885 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003886 /* Use sane default values in case a misbehaving remote device
3887 * did not send an RFC or extended window size option.
3888 */
3889 u16 txwin_ext = chan->ack_win;
3890 struct l2cap_conf_rfc rfc = {
3891 .mode = chan->mode,
3892 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3893 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3894 .max_pdu_size = cpu_to_le16(chan->imtu),
3895 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3896 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003897
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003898 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003899
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003900 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003901 return;
3902
3903 while (len >= L2CAP_CONF_OPT_SIZE) {
3904 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3905
Mat Martineauc20f8e32012-07-10 05:47:07 -07003906 switch (type) {
3907 case L2CAP_CONF_RFC:
3908 if (olen == sizeof(rfc))
3909 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003910 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003911 case L2CAP_CONF_EWS:
3912 txwin_ext = val;
3913 break;
3914 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003915 }
3916
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003917 switch (rfc.mode) {
3918 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003919 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3920 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003921 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3922 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3923 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3924 else
3925 chan->ack_win = min_t(u16, chan->ack_win,
3926 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003927 break;
3928 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003929 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003930 }
3931}
3932
Gustavo Padovan2d792812012-10-06 10:07:01 +01003933static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003934 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3935 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003936{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003937 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003938
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003939 if (cmd_len < sizeof(*rej))
3940 return -EPROTO;
3941
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003942 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003943 return 0;
3944
3945 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003946 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003947 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003948
3949 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003950 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003951
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003952 l2cap_conn_start(conn);
3953 }
3954
3955 return 0;
3956}
3957
Mat Martineau17009152012-10-23 15:24:07 -07003958static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3959 struct l2cap_cmd_hdr *cmd,
3960 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003961{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003962 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3963 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003964 struct l2cap_chan *chan = NULL, *pchan;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003965 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003966
3967 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003968 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003969
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003970 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003971
3972 /* Check if we have socket listening on psm */
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003973 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03003974 &conn->hcon->dst, ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003975 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003976 result = L2CAP_CR_BAD_PSM;
3977 goto sendresp;
3978 }
3979
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003980 mutex_lock(&conn->chan_lock);
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003981 l2cap_chan_lock(pchan);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003982
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003983 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003984 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003985 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003986 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003987 result = L2CAP_CR_SEC_BLOCK;
3988 goto response;
3989 }
3990
Linus Torvalds1da177e2005-04-16 15:20:36 -07003991 result = L2CAP_CR_NO_MEM;
3992
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003993 /* Check if we already have channel with that dcid */
3994 if (__l2cap_get_chan_by_dcid(conn, scid))
3995 goto response;
3996
Gustavo Padovan80b98022012-05-27 22:27:51 -03003997 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003998 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003999 goto response;
4000
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09004001 /* For certain devices (ex: HID mouse), support for authentication,
4002 * pairing and bonding is optional. For such devices, inorder to avoid
4003 * the ACL alive for too long after L2CAP disconnection, reset the ACL
4004 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
4005 */
4006 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
4007
Marcel Holtmann7eafc592013-10-13 08:12:47 -07004008 bacpy(&chan->src, &conn->hcon->src);
4009 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07004010 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
4011 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004012 chan->psm = psm;
4013 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07004014 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004015
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004016 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004017
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004018 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004019
Gustavo Padovan8d836d72013-10-15 19:24:47 -03004020 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004021
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03004022 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004023
Marcel Holtmann984947d2009-02-06 23:35:19 +01004024 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02004025 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07004026 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004027 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004028 result = L2CAP_CR_PEND;
4029 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08004030 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004031 } else {
Mat Martineau17009152012-10-23 15:24:07 -07004032 /* Force pending result for AMP controllers.
4033 * The connection will succeed after the
4034 * physical link is up.
4035 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004036 if (amp_id == AMP_ID_BREDR) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004037 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau17009152012-10-23 15:24:07 -07004038 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004039 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004040 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004041 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07004042 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004043 status = L2CAP_CS_NO_INFO;
4044 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004045 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004046 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004047 result = L2CAP_CR_PEND;
4048 status = L2CAP_CS_AUTHEN_PEND;
4049 }
4050 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004051 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004052 result = L2CAP_CR_PEND;
4053 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004054 }
4055
Linus Torvalds1da177e2005-04-16 15:20:36 -07004056response:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02004057 l2cap_chan_unlock(pchan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004058 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004059
4060sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07004061 rsp.scid = cpu_to_le16(scid);
4062 rsp.dcid = cpu_to_le16(dcid);
4063 rsp.result = cpu_to_le16(result);
4064 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004065 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004066
4067 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
4068 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004069 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004070
4071 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
4072 conn->info_ident = l2cap_get_ident(conn);
4073
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004074 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004075
Gustavo Padovan2d792812012-10-06 10:07:01 +01004076 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
4077 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004078 }
4079
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004080 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01004081 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004082 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004083 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004084 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004085 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004086 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004087 }
Mat Martineau17009152012-10-23 15:24:07 -07004088
4089 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004090}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004091
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004092static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004093 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004094{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05304095 struct hci_dev *hdev = conn->hcon->hdev;
4096 struct hci_conn *hcon = conn->hcon;
4097
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004098 if (cmd_len < sizeof(struct l2cap_conn_req))
4099 return -EPROTO;
4100
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05304101 hci_dev_lock(hdev);
4102 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
4103 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
4104 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
4105 hcon->dst_type, 0, NULL, 0,
4106 hcon->dev_class);
4107 hci_dev_unlock(hdev);
4108
Gustavo Padovan300229f2012-10-12 19:40:40 +08004109 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004110 return 0;
4111}
4112
Mat Martineau5909cf32012-10-23 15:24:08 -07004113static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004114 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4115 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004116{
4117 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
4118 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004119 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004120 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004121 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004122
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004123 if (cmd_len < sizeof(*rsp))
4124 return -EPROTO;
4125
Linus Torvalds1da177e2005-04-16 15:20:36 -07004126 scid = __le16_to_cpu(rsp->scid);
4127 dcid = __le16_to_cpu(rsp->dcid);
4128 result = __le16_to_cpu(rsp->result);
4129 status = __le16_to_cpu(rsp->status);
4130
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02004131 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 +01004132 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004133
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004134 mutex_lock(&conn->chan_lock);
4135
Linus Torvalds1da177e2005-04-16 15:20:36 -07004136 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004137 chan = __l2cap_get_chan_by_scid(conn, scid);
4138 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03004139 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004140 goto unlock;
4141 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004142 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004143 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
4144 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03004145 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004146 goto unlock;
4147 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004148 }
4149
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004150 err = 0;
4151
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004152 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004153
Linus Torvalds1da177e2005-04-16 15:20:36 -07004154 switch (result) {
4155 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03004156 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03004157 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004158 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004159 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004160
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004161 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004162 break;
4163
Linus Torvalds1da177e2005-04-16 15:20:36 -07004164 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004165 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004166 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004167 break;
4168
4169 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004170 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004171 break;
4172
4173 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004174 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004175 break;
4176 }
4177
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004178 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004179
4180unlock:
4181 mutex_unlock(&conn->chan_lock);
4182
4183 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004184}
4185
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004186static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07004187{
4188 /* FCS is enabled only in ERTM or streaming mode, if one or both
4189 * sides request it.
4190 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03004191 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004192 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02004193 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004194 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07004195}
4196
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004197static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
4198 u8 ident, u16 flags)
4199{
4200 struct l2cap_conn *conn = chan->conn;
4201
4202 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
4203 flags);
4204
4205 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
4206 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
4207
4208 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
4209 l2cap_build_conf_rsp(chan, data,
4210 L2CAP_CONF_SUCCESS, flags), data);
4211}
4212
Johan Hedberg662d6522013-10-16 11:20:47 +03004213static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident,
4214 u16 scid, u16 dcid)
4215{
4216 struct l2cap_cmd_rej_cid rej;
4217
4218 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
4219 rej.scid = __cpu_to_le16(scid);
4220 rej.dcid = __cpu_to_le16(dcid);
4221
4222 l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4223}
4224
Gustavo Padovan2d792812012-10-06 10:07:01 +01004225static inline int l2cap_config_req(struct l2cap_conn *conn,
4226 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4227 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004228{
4229 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
4230 u16 dcid, flags;
4231 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004232 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07004233 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004234
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004235 if (cmd_len < sizeof(*req))
4236 return -EPROTO;
4237
Linus Torvalds1da177e2005-04-16 15:20:36 -07004238 dcid = __le16_to_cpu(req->dcid);
4239 flags = __le16_to_cpu(req->flags);
4240
4241 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
4242
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004243 chan = l2cap_get_chan_by_scid(conn, dcid);
Johan Hedberg662d6522013-10-16 11:20:47 +03004244 if (!chan) {
4245 cmd_reject_invalid_cid(conn, cmd->ident, dcid, 0);
4246 return 0;
4247 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004248
David S. Miller033b1142011-07-21 13:38:42 -07004249 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Johan Hedberg662d6522013-10-16 11:20:47 +03004250 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4251 chan->dcid);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004252 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004253 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004254
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004255 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004256 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004257 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004258 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004259 l2cap_build_conf_rsp(chan, rsp,
4260 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004261 goto unlock;
4262 }
4263
4264 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004265 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4266 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004268 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004269 /* Incomplete config. Send empty response. */
4270 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004271 l2cap_build_conf_rsp(chan, rsp,
4272 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004273 goto unlock;
4274 }
4275
4276 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004277 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004278 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004279 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004280 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004281 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004282
Mat Martineau1500109b2012-10-23 15:24:15 -07004283 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004284 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004285 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004286
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004287 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004288 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004289
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004290 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004291 goto unlock;
4292
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004293 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004294 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004295
Mat Martineau105bdf92012-04-27 16:50:48 -07004296 if (chan->mode == L2CAP_MODE_ERTM ||
4297 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004298 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004299
Mat Martineau3c588192012-04-11 10:48:42 -07004300 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004301 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004302 else
4303 l2cap_chan_ready(chan);
4304
Marcel Holtmann876d9482007-10-20 13:35:42 +02004305 goto unlock;
4306 }
4307
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004308 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004309 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004310 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004311 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004312 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004313 }
4314
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004315 /* Got Conf Rsp PENDING from remote side and asume we sent
4316 Conf Rsp PENDING in the code above */
4317 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004318 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004319
4320 /* check compatibility */
4321
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004322 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004323 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004324 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4325 else
4326 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004327 }
4328
Linus Torvalds1da177e2005-04-16 15:20:36 -07004329unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004330 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004331 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004332}
4333
Gustavo Padovan2d792812012-10-06 10:07:01 +01004334static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004335 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4336 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004337{
4338 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4339 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004340 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004341 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004342 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004343
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004344 if (cmd_len < sizeof(*rsp))
4345 return -EPROTO;
4346
Linus Torvalds1da177e2005-04-16 15:20:36 -07004347 scid = __le16_to_cpu(rsp->scid);
4348 flags = __le16_to_cpu(rsp->flags);
4349 result = __le16_to_cpu(rsp->result);
4350
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004351 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4352 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004353
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004354 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004355 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004356 return 0;
4357
4358 switch (result) {
4359 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004360 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004361 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004362 break;
4363
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004364 case L2CAP_CONF_PENDING:
4365 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4366
4367 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4368 char buf[64];
4369
4370 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004371 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004372 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004373 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004374 goto done;
4375 }
4376
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004377 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004378 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4379 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004380 } else {
4381 if (l2cap_check_efs(chan)) {
4382 amp_create_logical_link(chan);
4383 chan->ident = cmd->ident;
4384 }
4385 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004386 }
4387 goto done;
4388
Linus Torvalds1da177e2005-04-16 15:20:36 -07004389 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004390 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004391 char req[64];
4392
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004393 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004394 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004395 goto done;
4396 }
4397
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004398 /* throw out any old stored conf requests */
4399 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004400 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004401 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004402 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004403 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004404 goto done;
4405 }
4406
4407 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004408 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004409 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004410 if (result != L2CAP_CONF_SUCCESS)
4411 goto done;
4412 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004413 }
4414
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004415 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004416 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004417
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004418 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004419 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004420 goto done;
4421 }
4422
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004423 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004424 goto done;
4425
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004426 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004427
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004428 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004429 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004430
Mat Martineau105bdf92012-04-27 16:50:48 -07004431 if (chan->mode == L2CAP_MODE_ERTM ||
4432 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004433 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004434
Mat Martineau3c588192012-04-11 10:48:42 -07004435 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004436 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004437 else
4438 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004439 }
4440
4441done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004442 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004443 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004444}
4445
Gustavo Padovan2d792812012-10-06 10:07:01 +01004446static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004447 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4448 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004449{
4450 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4451 struct l2cap_disconn_rsp rsp;
4452 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004453 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004454
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004455 if (cmd_len != sizeof(*req))
4456 return -EPROTO;
4457
Linus Torvalds1da177e2005-04-16 15:20:36 -07004458 scid = __le16_to_cpu(req->scid);
4459 dcid = __le16_to_cpu(req->dcid);
4460
4461 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4462
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004463 mutex_lock(&conn->chan_lock);
4464
4465 chan = __l2cap_get_chan_by_scid(conn, dcid);
4466 if (!chan) {
4467 mutex_unlock(&conn->chan_lock);
Johan Hedberg662d6522013-10-16 11:20:47 +03004468 cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid);
4469 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004470 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004471
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004472 l2cap_chan_lock(chan);
4473
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004474 rsp.dcid = cpu_to_le16(chan->scid);
4475 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004476 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4477
Gustavo Padovan5ec1bbe2013-10-15 19:24:48 -03004478 chan->ops->set_shutdown(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004479
Mat Martineau61d6ef32012-04-27 16:50:50 -07004480 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004481 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004482
4483 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004484
Gustavo Padovan80b98022012-05-27 22:27:51 -03004485 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004486 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004487
4488 mutex_unlock(&conn->chan_lock);
4489
Linus Torvalds1da177e2005-04-16 15:20:36 -07004490 return 0;
4491}
4492
Gustavo Padovan2d792812012-10-06 10:07:01 +01004493static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004494 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4495 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004496{
4497 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4498 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004499 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004500
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004501 if (cmd_len != sizeof(*rsp))
4502 return -EPROTO;
4503
Linus Torvalds1da177e2005-04-16 15:20:36 -07004504 scid = __le16_to_cpu(rsp->scid);
4505 dcid = __le16_to_cpu(rsp->dcid);
4506
4507 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4508
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004509 mutex_lock(&conn->chan_lock);
4510
4511 chan = __l2cap_get_chan_by_scid(conn, scid);
4512 if (!chan) {
4513 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004514 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004515 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004516
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004517 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004518
Mat Martineau61d6ef32012-04-27 16:50:50 -07004519 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004520 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004521
4522 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004523
Gustavo Padovan80b98022012-05-27 22:27:51 -03004524 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004525 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004526
4527 mutex_unlock(&conn->chan_lock);
4528
Linus Torvalds1da177e2005-04-16 15:20:36 -07004529 return 0;
4530}
4531
Gustavo Padovan2d792812012-10-06 10:07:01 +01004532static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004533 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4534 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004535{
4536 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004537 u16 type;
4538
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004539 if (cmd_len != sizeof(*req))
4540 return -EPROTO;
4541
Linus Torvalds1da177e2005-04-16 15:20:36 -07004542 type = __le16_to_cpu(req->type);
4543
4544 BT_DBG("type 0x%4.4x", type);
4545
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004546 if (type == L2CAP_IT_FEAT_MASK) {
4547 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004548 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004549 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004550 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4551 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004552 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004553 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004554 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004555 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004556 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004557 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004558
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004559 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004560 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4561 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004562 } else if (type == L2CAP_IT_FIXED_CHAN) {
4563 u8 buf[12];
4564 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004565
Marcel Holtmann848566b2013-10-01 22:59:22 -07004566 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004567 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4568 else
4569 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4570
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004571 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4572 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004573 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004574 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4575 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004576 } else {
4577 struct l2cap_info_rsp rsp;
4578 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004579 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004580 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4581 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004582 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004583
4584 return 0;
4585}
4586
Gustavo Padovan2d792812012-10-06 10:07:01 +01004587static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004588 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4589 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004590{
4591 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4592 u16 type, result;
4593
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304594 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004595 return -EPROTO;
4596
Linus Torvalds1da177e2005-04-16 15:20:36 -07004597 type = __le16_to_cpu(rsp->type);
4598 result = __le16_to_cpu(rsp->result);
4599
4600 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4601
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004602 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4603 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004604 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004605 return 0;
4606
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004607 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004608
Ville Tervoadb08ed2010-08-04 09:43:33 +03004609 if (result != L2CAP_IR_SUCCESS) {
4610 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4611 conn->info_ident = 0;
4612
4613 l2cap_conn_start(conn);
4614
4615 return 0;
4616 }
4617
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004618 switch (type) {
4619 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004620 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004621
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004622 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004623 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004624 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004625
4626 conn->info_ident = l2cap_get_ident(conn);
4627
4628 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004629 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004630 } else {
4631 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4632 conn->info_ident = 0;
4633
4634 l2cap_conn_start(conn);
4635 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004636 break;
4637
4638 case L2CAP_IT_FIXED_CHAN:
4639 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004640 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004641 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004642
4643 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004644 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004645 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004646
Linus Torvalds1da177e2005-04-16 15:20:36 -07004647 return 0;
4648}
4649
Mat Martineau17009152012-10-23 15:24:07 -07004650static int l2cap_create_channel_req(struct l2cap_conn *conn,
4651 struct l2cap_cmd_hdr *cmd,
4652 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004653{
4654 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004655 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004656 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004657 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004658 u16 psm, scid;
4659
4660 if (cmd_len != sizeof(*req))
4661 return -EPROTO;
4662
Marcel Holtmann848566b2013-10-01 22:59:22 -07004663 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004664 return -EINVAL;
4665
4666 psm = le16_to_cpu(req->psm);
4667 scid = le16_to_cpu(req->scid);
4668
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004669 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 -07004670
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004671 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004672 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004673 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4674 req->amp_id);
4675 return 0;
4676 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004677
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004678 /* Validate AMP controller id */
4679 hdev = hci_dev_get(req->amp_id);
4680 if (!hdev)
4681 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004682
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004683 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004684 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004685 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004686 }
4687
4688 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4689 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004690 if (chan) {
4691 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4692 struct hci_conn *hs_hcon;
4693
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004694 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4695 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004696 if (!hs_hcon) {
4697 hci_dev_put(hdev);
Johan Hedberg662d6522013-10-16 11:20:47 +03004698 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4699 chan->dcid);
4700 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004701 }
4702
4703 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4704
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004705 mgr->bredr_chan = chan;
4706 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004707 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004708 conn->mtu = hdev->block_mtu;
4709 }
4710
4711 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004712
4713 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004714
4715error:
4716 rsp.dcid = 0;
4717 rsp.scid = cpu_to_le16(scid);
4718 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4719 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4720
4721 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4722 sizeof(rsp), &rsp);
4723
Johan Hedbergdc280802013-09-16 13:05:13 +03004724 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004725}
4726
Mat Martineau8eb200b2012-10-23 15:24:17 -07004727static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4728{
4729 struct l2cap_move_chan_req req;
4730 u8 ident;
4731
4732 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4733
4734 ident = l2cap_get_ident(chan->conn);
4735 chan->ident = ident;
4736
4737 req.icid = cpu_to_le16(chan->scid);
4738 req.dest_amp_id = dest_amp_id;
4739
4740 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4741 &req);
4742
4743 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4744}
4745
Mat Martineau1500109b2012-10-23 15:24:15 -07004746static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004747{
4748 struct l2cap_move_chan_rsp rsp;
4749
Mat Martineau1500109b2012-10-23 15:24:15 -07004750 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004751
Mat Martineau1500109b2012-10-23 15:24:15 -07004752 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004753 rsp.result = cpu_to_le16(result);
4754
Mat Martineau1500109b2012-10-23 15:24:15 -07004755 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4756 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004757}
4758
Mat Martineau5b155ef2012-10-23 15:24:14 -07004759static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004760{
4761 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004762
Mat Martineau5b155ef2012-10-23 15:24:14 -07004763 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004764
Mat Martineau5b155ef2012-10-23 15:24:14 -07004765 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004766
Mat Martineau5b155ef2012-10-23 15:24:14 -07004767 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004768 cfm.result = cpu_to_le16(result);
4769
Mat Martineau5b155ef2012-10-23 15:24:14 -07004770 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4771 sizeof(cfm), &cfm);
4772
4773 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4774}
4775
4776static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4777{
4778 struct l2cap_move_chan_cfm cfm;
4779
4780 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4781
4782 cfm.icid = cpu_to_le16(icid);
4783 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4784
4785 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4786 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004787}
4788
4789static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004790 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004791{
4792 struct l2cap_move_chan_cfm_rsp rsp;
4793
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004794 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004795
4796 rsp.icid = cpu_to_le16(icid);
4797 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4798}
4799
Mat Martineau5f3847a2012-10-23 15:24:12 -07004800static void __release_logical_link(struct l2cap_chan *chan)
4801{
4802 chan->hs_hchan = NULL;
4803 chan->hs_hcon = NULL;
4804
4805 /* Placeholder - release the logical link */
4806}
4807
Mat Martineau1500109b2012-10-23 15:24:15 -07004808static void l2cap_logical_fail(struct l2cap_chan *chan)
4809{
4810 /* Logical link setup failed */
4811 if (chan->state != BT_CONNECTED) {
4812 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004813 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004814 return;
4815 }
4816
4817 switch (chan->move_role) {
4818 case L2CAP_MOVE_ROLE_RESPONDER:
4819 l2cap_move_done(chan);
4820 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4821 break;
4822 case L2CAP_MOVE_ROLE_INITIATOR:
4823 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4824 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4825 /* Remote has only sent pending or
4826 * success responses, clean up
4827 */
4828 l2cap_move_done(chan);
4829 }
4830
4831 /* Other amp move states imply that the move
4832 * has already aborted
4833 */
4834 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4835 break;
4836 }
4837}
4838
4839static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4840 struct hci_chan *hchan)
4841{
4842 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004843
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004844 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004845 chan->hs_hcon->l2cap_data = chan->conn;
4846
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004847 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004848
4849 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004850 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004851
4852 set_default_fcs(chan);
4853
4854 err = l2cap_ertm_init(chan);
4855 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004856 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004857 else
4858 l2cap_chan_ready(chan);
4859 }
4860}
4861
4862static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4863 struct hci_chan *hchan)
4864{
4865 chan->hs_hcon = hchan->conn;
4866 chan->hs_hcon->l2cap_data = chan->conn;
4867
4868 BT_DBG("move_state %d", chan->move_state);
4869
4870 switch (chan->move_state) {
4871 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4872 /* Move confirm will be sent after a success
4873 * response is received
4874 */
4875 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4876 break;
4877 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4878 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4879 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4880 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4881 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4882 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4883 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4884 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4885 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4886 }
4887 break;
4888 default:
4889 /* Move was not in expected state, free the channel */
4890 __release_logical_link(chan);
4891
4892 chan->move_state = L2CAP_MOVE_STABLE;
4893 }
4894}
4895
4896/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004897void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4898 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004899{
Mat Martineau1500109b2012-10-23 15:24:15 -07004900 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4901
4902 if (status) {
4903 l2cap_logical_fail(chan);
4904 __release_logical_link(chan);
4905 return;
4906 }
4907
4908 if (chan->state != BT_CONNECTED) {
4909 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004910 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004911 l2cap_logical_finish_create(chan, hchan);
4912 } else {
4913 l2cap_logical_finish_move(chan, hchan);
4914 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004915}
4916
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004917void l2cap_move_start(struct l2cap_chan *chan)
4918{
4919 BT_DBG("chan %p", chan);
4920
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004921 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004922 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4923 return;
4924 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4925 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4926 /* Placeholder - start physical link setup */
4927 } else {
4928 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4929 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4930 chan->move_id = 0;
4931 l2cap_move_setup(chan);
4932 l2cap_send_move_chan_req(chan, 0);
4933 }
4934}
4935
Mat Martineau8eb200b2012-10-23 15:24:17 -07004936static void l2cap_do_create(struct l2cap_chan *chan, int result,
4937 u8 local_amp_id, u8 remote_amp_id)
4938{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004939 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4940 local_amp_id, remote_amp_id);
4941
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004942 chan->fcs = L2CAP_FCS_NONE;
4943
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004944 /* Outgoing channel on AMP */
4945 if (chan->state == BT_CONNECT) {
4946 if (result == L2CAP_CR_SUCCESS) {
4947 chan->local_amp_id = local_amp_id;
4948 l2cap_send_create_chan_req(chan, remote_amp_id);
4949 } else {
4950 /* Revert to BR/EDR connect */
4951 l2cap_send_conn_req(chan);
4952 }
4953
4954 return;
4955 }
4956
4957 /* Incoming channel on AMP */
4958 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004959 struct l2cap_conn_rsp rsp;
4960 char buf[128];
4961 rsp.scid = cpu_to_le16(chan->dcid);
4962 rsp.dcid = cpu_to_le16(chan->scid);
4963
Mat Martineau8eb200b2012-10-23 15:24:17 -07004964 if (result == L2CAP_CR_SUCCESS) {
4965 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004966 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4967 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004968 } else {
4969 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004970 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4971 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004972 }
4973
4974 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4975 sizeof(rsp), &rsp);
4976
4977 if (result == L2CAP_CR_SUCCESS) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004978 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004979 set_bit(CONF_REQ_SENT, &chan->conf_state);
4980 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4981 L2CAP_CONF_REQ,
4982 l2cap_build_conf_req(chan, buf), buf);
4983 chan->num_conf_req++;
4984 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004985 }
4986}
4987
4988static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4989 u8 remote_amp_id)
4990{
4991 l2cap_move_setup(chan);
4992 chan->move_id = local_amp_id;
4993 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4994
4995 l2cap_send_move_chan_req(chan, remote_amp_id);
4996}
4997
4998static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4999{
5000 struct hci_chan *hchan = NULL;
5001
5002 /* Placeholder - get hci_chan for logical link */
5003
5004 if (hchan) {
5005 if (hchan->state == BT_CONNECTED) {
5006 /* Logical link is ready to go */
5007 chan->hs_hcon = hchan->conn;
5008 chan->hs_hcon->l2cap_data = chan->conn;
5009 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
5010 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
5011
5012 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5013 } else {
5014 /* Wait for logical link to be ready */
5015 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5016 }
5017 } else {
5018 /* Logical link not available */
5019 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
5020 }
5021}
5022
5023static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
5024{
5025 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
5026 u8 rsp_result;
5027 if (result == -EINVAL)
5028 rsp_result = L2CAP_MR_BAD_ID;
5029 else
5030 rsp_result = L2CAP_MR_NOT_ALLOWED;
5031
5032 l2cap_send_move_chan_rsp(chan, rsp_result);
5033 }
5034
5035 chan->move_role = L2CAP_MOVE_ROLE_NONE;
5036 chan->move_state = L2CAP_MOVE_STABLE;
5037
5038 /* Restart data transmission */
5039 l2cap_ertm_send(chan);
5040}
5041
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02005042/* Invoke with locked chan */
5043void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07005044{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02005045 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02005046 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02005047
Mat Martineau8eb200b2012-10-23 15:24:17 -07005048 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
5049 chan, result, local_amp_id, remote_amp_id);
5050
Mat Martineau8eb200b2012-10-23 15:24:17 -07005051 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
5052 l2cap_chan_unlock(chan);
5053 return;
5054 }
5055
5056 if (chan->state != BT_CONNECTED) {
5057 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
5058 } else if (result != L2CAP_MR_SUCCESS) {
5059 l2cap_do_move_cancel(chan, result);
5060 } else {
5061 switch (chan->move_role) {
5062 case L2CAP_MOVE_ROLE_INITIATOR:
5063 l2cap_do_move_initiate(chan, local_amp_id,
5064 remote_amp_id);
5065 break;
5066 case L2CAP_MOVE_ROLE_RESPONDER:
5067 l2cap_do_move_respond(chan, result);
5068 break;
5069 default:
5070 l2cap_do_move_cancel(chan, result);
5071 break;
5072 }
5073 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07005074}
5075
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005076static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005077 struct l2cap_cmd_hdr *cmd,
5078 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005079{
5080 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07005081 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005082 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005083 u16 icid = 0;
5084 u16 result = L2CAP_MR_NOT_ALLOWED;
5085
5086 if (cmd_len != sizeof(*req))
5087 return -EPROTO;
5088
5089 icid = le16_to_cpu(req->icid);
5090
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005091 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005092
Marcel Holtmann848566b2013-10-01 22:59:22 -07005093 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005094 return -EINVAL;
5095
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005096 chan = l2cap_get_chan_by_dcid(conn, icid);
5097 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07005098 rsp.icid = cpu_to_le16(icid);
5099 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
5100 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
5101 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005102 return 0;
5103 }
5104
Mat Martineau1500109b2012-10-23 15:24:15 -07005105 chan->ident = cmd->ident;
5106
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005107 if (chan->scid < L2CAP_CID_DYN_START ||
5108 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
5109 (chan->mode != L2CAP_MODE_ERTM &&
5110 chan->mode != L2CAP_MODE_STREAMING)) {
5111 result = L2CAP_MR_NOT_ALLOWED;
5112 goto send_move_response;
5113 }
5114
5115 if (chan->local_amp_id == req->dest_amp_id) {
5116 result = L2CAP_MR_SAME_ID;
5117 goto send_move_response;
5118 }
5119
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005120 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005121 struct hci_dev *hdev;
5122 hdev = hci_dev_get(req->dest_amp_id);
5123 if (!hdev || hdev->dev_type != HCI_AMP ||
5124 !test_bit(HCI_UP, &hdev->flags)) {
5125 if (hdev)
5126 hci_dev_put(hdev);
5127
5128 result = L2CAP_MR_BAD_ID;
5129 goto send_move_response;
5130 }
5131 hci_dev_put(hdev);
5132 }
5133
5134 /* Detect a move collision. Only send a collision response
5135 * if this side has "lost", otherwise proceed with the move.
5136 * The winner has the larger bd_addr.
5137 */
5138 if ((__chan_is_moving(chan) ||
5139 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07005140 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005141 result = L2CAP_MR_COLLISION;
5142 goto send_move_response;
5143 }
5144
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005145 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5146 l2cap_move_setup(chan);
5147 chan->move_id = req->dest_amp_id;
5148 icid = chan->dcid;
5149
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005150 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005151 /* Moving to BR/EDR */
5152 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5153 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
5154 result = L2CAP_MR_PEND;
5155 } else {
5156 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
5157 result = L2CAP_MR_SUCCESS;
5158 }
5159 } else {
5160 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
5161 /* Placeholder - uncomment when amp functions are available */
5162 /*amp_accept_physical(chan, req->dest_amp_id);*/
5163 result = L2CAP_MR_PEND;
5164 }
5165
5166send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07005167 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005168
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005169 l2cap_chan_unlock(chan);
5170
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005171 return 0;
5172}
5173
Mat Martineau5b155ef2012-10-23 15:24:14 -07005174static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
5175{
5176 struct l2cap_chan *chan;
5177 struct hci_chan *hchan = NULL;
5178
5179 chan = l2cap_get_chan_by_scid(conn, icid);
5180 if (!chan) {
5181 l2cap_send_move_chan_cfm_icid(conn, icid);
5182 return;
5183 }
5184
5185 __clear_chan_timer(chan);
5186 if (result == L2CAP_MR_PEND)
5187 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
5188
5189 switch (chan->move_state) {
5190 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
5191 /* Move confirm will be sent when logical link
5192 * is complete.
5193 */
5194 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5195 break;
5196 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
5197 if (result == L2CAP_MR_PEND) {
5198 break;
5199 } else if (test_bit(CONN_LOCAL_BUSY,
5200 &chan->conn_state)) {
5201 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
5202 } else {
5203 /* Logical link is up or moving to BR/EDR,
5204 * proceed with move
5205 */
5206 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
5207 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5208 }
5209 break;
5210 case L2CAP_MOVE_WAIT_RSP:
5211 /* Moving to AMP */
5212 if (result == L2CAP_MR_SUCCESS) {
5213 /* Remote is ready, send confirm immediately
5214 * after logical link is ready
5215 */
5216 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5217 } else {
5218 /* Both logical link and move success
5219 * are required to confirm
5220 */
5221 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
5222 }
5223
5224 /* Placeholder - get hci_chan for logical link */
5225 if (!hchan) {
5226 /* Logical link not available */
5227 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5228 break;
5229 }
5230
5231 /* If the logical link is not yet connected, do not
5232 * send confirmation.
5233 */
5234 if (hchan->state != BT_CONNECTED)
5235 break;
5236
5237 /* Logical link is already ready to go */
5238
5239 chan->hs_hcon = hchan->conn;
5240 chan->hs_hcon->l2cap_data = chan->conn;
5241
5242 if (result == L2CAP_MR_SUCCESS) {
5243 /* Can confirm now */
5244 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5245 } else {
5246 /* Now only need move success
5247 * to confirm
5248 */
5249 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
5250 }
5251
5252 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5253 break;
5254 default:
5255 /* Any other amp move state means the move failed. */
5256 chan->move_id = chan->local_amp_id;
5257 l2cap_move_done(chan);
5258 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5259 }
5260
5261 l2cap_chan_unlock(chan);
5262}
5263
5264static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5265 u16 result)
5266{
5267 struct l2cap_chan *chan;
5268
5269 chan = l2cap_get_chan_by_ident(conn, ident);
5270 if (!chan) {
5271 /* Could not locate channel, icid is best guess */
5272 l2cap_send_move_chan_cfm_icid(conn, icid);
5273 return;
5274 }
5275
5276 __clear_chan_timer(chan);
5277
5278 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5279 if (result == L2CAP_MR_COLLISION) {
5280 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5281 } else {
5282 /* Cleanup - cancel move */
5283 chan->move_id = chan->local_amp_id;
5284 l2cap_move_done(chan);
5285 }
5286 }
5287
5288 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5289
5290 l2cap_chan_unlock(chan);
5291}
5292
5293static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5294 struct l2cap_cmd_hdr *cmd,
5295 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005296{
5297 struct l2cap_move_chan_rsp *rsp = data;
5298 u16 icid, result;
5299
5300 if (cmd_len != sizeof(*rsp))
5301 return -EPROTO;
5302
5303 icid = le16_to_cpu(rsp->icid);
5304 result = le16_to_cpu(rsp->result);
5305
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005306 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005307
Mat Martineau5b155ef2012-10-23 15:24:14 -07005308 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5309 l2cap_move_continue(conn, icid, result);
5310 else
5311 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005312
5313 return 0;
5314}
5315
Mat Martineau5f3847a2012-10-23 15:24:12 -07005316static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5317 struct l2cap_cmd_hdr *cmd,
5318 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005319{
5320 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005321 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005322 u16 icid, result;
5323
5324 if (cmd_len != sizeof(*cfm))
5325 return -EPROTO;
5326
5327 icid = le16_to_cpu(cfm->icid);
5328 result = le16_to_cpu(cfm->result);
5329
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005330 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005331
Mat Martineau5f3847a2012-10-23 15:24:12 -07005332 chan = l2cap_get_chan_by_dcid(conn, icid);
5333 if (!chan) {
5334 /* Spec requires a response even if the icid was not found */
5335 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5336 return 0;
5337 }
5338
5339 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5340 if (result == L2CAP_MC_CONFIRMED) {
5341 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005342 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005343 __release_logical_link(chan);
5344 } else {
5345 chan->move_id = chan->local_amp_id;
5346 }
5347
5348 l2cap_move_done(chan);
5349 }
5350
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005351 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5352
Mat Martineau5f3847a2012-10-23 15:24:12 -07005353 l2cap_chan_unlock(chan);
5354
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005355 return 0;
5356}
5357
5358static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005359 struct l2cap_cmd_hdr *cmd,
5360 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005361{
5362 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005363 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005364 u16 icid;
5365
5366 if (cmd_len != sizeof(*rsp))
5367 return -EPROTO;
5368
5369 icid = le16_to_cpu(rsp->icid);
5370
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005371 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005372
Mat Martineau3fd71a02012-10-23 15:24:16 -07005373 chan = l2cap_get_chan_by_scid(conn, icid);
5374 if (!chan)
5375 return 0;
5376
5377 __clear_chan_timer(chan);
5378
5379 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5380 chan->local_amp_id = chan->move_id;
5381
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005382 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005383 __release_logical_link(chan);
5384
5385 l2cap_move_done(chan);
5386 }
5387
5388 l2cap_chan_unlock(chan);
5389
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005390 return 0;
5391}
5392
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005393static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005394 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005395{
5396 u16 max_latency;
5397
5398 if (min > max || min < 6 || max > 3200)
5399 return -EINVAL;
5400
5401 if (to_multiplier < 10 || to_multiplier > 3200)
5402 return -EINVAL;
5403
5404 if (max >= to_multiplier * 8)
5405 return -EINVAL;
5406
5407 max_latency = (to_multiplier * 8 / max) - 1;
5408 if (latency > 499 || latency > max_latency)
5409 return -EINVAL;
5410
5411 return 0;
5412}
5413
5414static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005415 struct l2cap_cmd_hdr *cmd,
Johan Hedberg203e6392013-05-15 10:07:15 +03005416 u16 cmd_len, u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005417{
5418 struct hci_conn *hcon = conn->hcon;
5419 struct l2cap_conn_param_update_req *req;
5420 struct l2cap_conn_param_update_rsp rsp;
Johan Hedberg203e6392013-05-15 10:07:15 +03005421 u16 min, max, latency, to_multiplier;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005422 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005423
5424 if (!(hcon->link_mode & HCI_LM_MASTER))
5425 return -EINVAL;
5426
Claudio Takahaside731152011-02-11 19:28:55 -02005427 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5428 return -EPROTO;
5429
5430 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005431 min = __le16_to_cpu(req->min);
5432 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005433 latency = __le16_to_cpu(req->latency);
5434 to_multiplier = __le16_to_cpu(req->to_multiplier);
5435
5436 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 +01005437 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005438
5439 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005440
5441 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5442 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005443 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005444 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005445 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005446
5447 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005448 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005449
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005450 if (!err)
5451 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5452
Claudio Takahaside731152011-02-11 19:28:55 -02005453 return 0;
5454}
5455
Johan Hedbergf1496de2013-05-13 14:15:56 +03005456static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
5457 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5458 u8 *data)
5459{
5460 struct l2cap_le_conn_rsp *rsp = (struct l2cap_le_conn_rsp *) data;
5461 u16 dcid, mtu, mps, credits, result;
5462 struct l2cap_chan *chan;
5463 int err;
5464
5465 if (cmd_len < sizeof(*rsp))
5466 return -EPROTO;
5467
5468 dcid = __le16_to_cpu(rsp->dcid);
5469 mtu = __le16_to_cpu(rsp->mtu);
5470 mps = __le16_to_cpu(rsp->mps);
5471 credits = __le16_to_cpu(rsp->credits);
5472 result = __le16_to_cpu(rsp->result);
5473
5474 if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23))
5475 return -EPROTO;
5476
5477 BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x",
5478 dcid, mtu, mps, credits, result);
5479
5480 mutex_lock(&conn->chan_lock);
5481
5482 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
5483 if (!chan) {
5484 err = -EBADSLT;
5485 goto unlock;
5486 }
5487
5488 err = 0;
5489
5490 l2cap_chan_lock(chan);
5491
5492 switch (result) {
5493 case L2CAP_CR_SUCCESS:
5494 chan->ident = 0;
5495 chan->dcid = dcid;
5496 chan->omtu = mtu;
5497 chan->remote_mps = mps;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005498 chan->tx_credits = credits;
Johan Hedbergf1496de2013-05-13 14:15:56 +03005499 l2cap_chan_ready(chan);
5500 break;
5501
5502 default:
5503 l2cap_chan_del(chan, ECONNREFUSED);
5504 break;
5505 }
5506
5507 l2cap_chan_unlock(chan);
5508
5509unlock:
5510 mutex_unlock(&conn->chan_lock);
5511
5512 return err;
5513}
5514
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005515static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005516 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5517 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005518{
5519 int err = 0;
5520
5521 switch (cmd->code) {
5522 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005523 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005524 break;
5525
5526 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005527 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005528 break;
5529
5530 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005531 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005532 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005533 break;
5534
5535 case L2CAP_CONF_REQ:
5536 err = l2cap_config_req(conn, cmd, cmd_len, data);
5537 break;
5538
5539 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005540 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005541 break;
5542
5543 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005544 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005545 break;
5546
5547 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005548 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005549 break;
5550
5551 case L2CAP_ECHO_REQ:
5552 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5553 break;
5554
5555 case L2CAP_ECHO_RSP:
5556 break;
5557
5558 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005559 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005560 break;
5561
5562 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005563 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005564 break;
5565
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005566 case L2CAP_CREATE_CHAN_REQ:
5567 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5568 break;
5569
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005570 case L2CAP_MOVE_CHAN_REQ:
5571 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5572 break;
5573
5574 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005575 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005576 break;
5577
5578 case L2CAP_MOVE_CHAN_CFM:
5579 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5580 break;
5581
5582 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005583 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005584 break;
5585
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005586 default:
5587 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5588 err = -EINVAL;
5589 break;
5590 }
5591
5592 return err;
5593}
5594
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005595static int l2cap_le_connect_req(struct l2cap_conn *conn,
5596 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5597 u8 *data)
5598{
5599 struct l2cap_le_conn_req *req = (struct l2cap_le_conn_req *) data;
5600 struct l2cap_le_conn_rsp rsp;
5601 struct l2cap_chan *chan, *pchan;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005602 u16 dcid, scid, credits, mtu, mps;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005603 __le16 psm;
5604 u8 result;
5605
5606 if (cmd_len != sizeof(*req))
5607 return -EPROTO;
5608
5609 scid = __le16_to_cpu(req->scid);
5610 mtu = __le16_to_cpu(req->mtu);
5611 mps = __le16_to_cpu(req->mps);
5612 psm = req->psm;
5613 dcid = 0;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005614 credits = 0;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005615
5616 if (mtu < 23 || mps < 23)
5617 return -EPROTO;
5618
5619 BT_DBG("psm 0x%2.2x scid 0x%4.4x mtu %u mps %u", __le16_to_cpu(psm),
5620 scid, mtu, mps);
5621
5622 /* Check if we have socket listening on psm */
5623 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
5624 &conn->hcon->dst, LE_LINK);
5625 if (!pchan) {
5626 result = L2CAP_CR_BAD_PSM;
5627 chan = NULL;
5628 goto response;
5629 }
5630
5631 mutex_lock(&conn->chan_lock);
5632 l2cap_chan_lock(pchan);
5633
5634 if (!smp_sufficient_security(conn->hcon, pchan->sec_level)) {
5635 result = L2CAP_CR_AUTHENTICATION;
5636 chan = NULL;
5637 goto response_unlock;
5638 }
5639
5640 /* Check if we already have channel with that dcid */
5641 if (__l2cap_get_chan_by_dcid(conn, scid)) {
5642 result = L2CAP_CR_NO_MEM;
5643 chan = NULL;
5644 goto response_unlock;
5645 }
5646
5647 chan = pchan->ops->new_connection(pchan);
5648 if (!chan) {
5649 result = L2CAP_CR_NO_MEM;
5650 goto response_unlock;
5651 }
5652
Johan Hedberg0ce43ce2013-12-05 14:55:33 +02005653 l2cap_le_flowctl_init(chan);
5654
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005655 bacpy(&chan->src, &conn->hcon->src);
5656 bacpy(&chan->dst, &conn->hcon->dst);
5657 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
5658 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
5659 chan->psm = psm;
5660 chan->dcid = scid;
5661 chan->omtu = mtu;
5662 chan->remote_mps = mps;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005663 chan->tx_credits = __le16_to_cpu(req->credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005664
5665 __l2cap_chan_add(conn, chan);
5666 dcid = chan->scid;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005667 credits = chan->rx_credits;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005668
5669 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
5670
5671 chan->ident = cmd->ident;
5672
5673 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
5674 l2cap_state_change(chan, BT_CONNECT2);
5675 result = L2CAP_CR_PEND;
5676 chan->ops->defer(chan);
5677 } else {
5678 l2cap_chan_ready(chan);
5679 result = L2CAP_CR_SUCCESS;
5680 }
5681
5682response_unlock:
5683 l2cap_chan_unlock(pchan);
5684 mutex_unlock(&conn->chan_lock);
5685
5686 if (result == L2CAP_CR_PEND)
5687 return 0;
5688
5689response:
5690 if (chan) {
5691 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02005692 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005693 } else {
5694 rsp.mtu = 0;
5695 rsp.mps = 0;
5696 }
5697
5698 rsp.dcid = cpu_to_le16(dcid);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005699 rsp.credits = cpu_to_le16(credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005700 rsp.result = cpu_to_le16(result);
5701
5702 l2cap_send_cmd(conn, cmd->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), &rsp);
5703
5704 return 0;
5705}
5706
Johan Hedbergfad5fc82013-12-05 09:45:01 +02005707static inline int l2cap_le_credits(struct l2cap_conn *conn,
5708 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5709 u8 *data)
5710{
5711 struct l2cap_le_credits *pkt;
5712 struct l2cap_chan *chan;
5713 u16 cid, credits;
5714
5715 if (cmd_len != sizeof(*pkt))
5716 return -EPROTO;
5717
5718 pkt = (struct l2cap_le_credits *) data;
5719 cid = __le16_to_cpu(pkt->cid);
5720 credits = __le16_to_cpu(pkt->credits);
5721
5722 BT_DBG("cid 0x%4.4x credits 0x%4.4x", cid, credits);
5723
5724 chan = l2cap_get_chan_by_dcid(conn, cid);
5725 if (!chan)
5726 return -EBADSLT;
5727
5728 chan->tx_credits += credits;
5729
5730 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
5731 l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
5732 chan->tx_credits--;
5733 }
5734
5735 if (chan->tx_credits)
5736 chan->ops->resume(chan);
5737
5738 l2cap_chan_unlock(chan);
5739
5740 return 0;
5741}
5742
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005743static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Johan Hedberg203e6392013-05-15 10:07:15 +03005744 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5745 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005746{
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005747 int err = 0;
5748
Johan Hedberg3af8ace2013-12-03 09:51:51 +02005749 if (!enable_lecoc) {
5750 switch (cmd->code) {
5751 case L2CAP_LE_CONN_REQ:
5752 case L2CAP_LE_CONN_RSP:
5753 case L2CAP_LE_CREDITS:
5754 case L2CAP_DISCONN_REQ:
5755 case L2CAP_DISCONN_RSP:
5756 return -EINVAL;
5757 }
5758 }
5759
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005760 switch (cmd->code) {
5761 case L2CAP_COMMAND_REJ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005762 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005763
5764 case L2CAP_CONN_PARAM_UPDATE_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005765 err = l2cap_conn_param_update_req(conn, cmd, cmd_len, data);
5766 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005767
5768 case L2CAP_CONN_PARAM_UPDATE_RSP:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005769 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005770
Johan Hedbergf1496de2013-05-13 14:15:56 +03005771 case L2CAP_LE_CONN_RSP:
5772 l2cap_le_connect_rsp(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005773 break;
Johan Hedbergf1496de2013-05-13 14:15:56 +03005774
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005775 case L2CAP_LE_CONN_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005776 err = l2cap_le_connect_req(conn, cmd, cmd_len, data);
5777 break;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005778
Johan Hedbergfad5fc82013-12-05 09:45:01 +02005779 case L2CAP_LE_CREDITS:
5780 err = l2cap_le_credits(conn, cmd, cmd_len, data);
5781 break;
5782
Johan Hedberg3defe012013-05-15 10:16:06 +03005783 case L2CAP_DISCONN_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005784 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
5785 break;
Johan Hedberg3defe012013-05-15 10:16:06 +03005786
5787 case L2CAP_DISCONN_RSP:
5788 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005789 break;
Johan Hedberg3defe012013-05-15 10:16:06 +03005790
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005791 default:
5792 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005793 err = -EINVAL;
5794 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005795 }
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005796
5797 return err;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005798}
5799
Johan Hedbergc5623552013-04-29 19:35:33 +03005800static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5801 struct sk_buff *skb)
5802{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005803 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005804 struct l2cap_cmd_hdr *cmd;
5805 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005806 int err;
5807
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005808 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005809 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005810
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005811 if (skb->len < L2CAP_CMD_HDR_SIZE)
5812 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005813
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005814 cmd = (void *) skb->data;
5815 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005816
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005817 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005818
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005819 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005820
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005821 if (len != skb->len || !cmd->ident) {
5822 BT_DBG("corrupted command");
5823 goto drop;
5824 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005825
Johan Hedberg203e6392013-05-15 10:07:15 +03005826 err = l2cap_le_sig_cmd(conn, cmd, len, skb->data);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005827 if (err) {
5828 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005829
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005830 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005831
Johan Hedberga5211492013-10-16 11:20:49 +03005832 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005833 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5834 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005835 }
5836
Marcel Holtmann3b166292013-10-02 08:28:21 -07005837drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005838 kfree_skb(skb);
5839}
5840
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005841static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005842 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005843{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005844 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005845 u8 *data = skb->data;
5846 int len = skb->len;
5847 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005848 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005849
5850 l2cap_raw_recv(conn, skb);
5851
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005852 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005853 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005854
Linus Torvalds1da177e2005-04-16 15:20:36 -07005855 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005856 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005857 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5858 data += L2CAP_CMD_HDR_SIZE;
5859 len -= L2CAP_CMD_HDR_SIZE;
5860
Al Viro88219a02007-07-29 00:17:25 -07005861 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005862
Gustavo Padovan2d792812012-10-06 10:07:01 +01005863 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5864 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005865
Al Viro88219a02007-07-29 00:17:25 -07005866 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005867 BT_DBG("corrupted command");
5868 break;
5869 }
5870
Johan Hedbergc5623552013-04-29 19:35:33 +03005871 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005872 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005873 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005874
5875 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005876
Johan Hedberga5211492013-10-16 11:20:49 +03005877 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005878 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5879 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005880 }
5881
Al Viro88219a02007-07-29 00:17:25 -07005882 data += cmd_len;
5883 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005884 }
5885
Marcel Holtmann3b166292013-10-02 08:28:21 -07005886drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005887 kfree_skb(skb);
5888}
5889
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005890static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005891{
5892 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005893 int hdr_size;
5894
5895 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5896 hdr_size = L2CAP_EXT_HDR_SIZE;
5897 else
5898 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005899
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005900 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005901 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005902 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5903 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5904
5905 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005906 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005907 }
5908 return 0;
5909}
5910
Mat Martineau6ea00482012-05-17 20:53:52 -07005911static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005912{
Mat Martineaue31f7632012-05-17 20:53:41 -07005913 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005914
Mat Martineaue31f7632012-05-17 20:53:41 -07005915 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005916
Mat Martineaue31f7632012-05-17 20:53:41 -07005917 memset(&control, 0, sizeof(control));
5918 control.sframe = 1;
5919 control.final = 1;
5920 control.reqseq = chan->buffer_seq;
5921 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005922
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005923 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005924 control.super = L2CAP_SUPER_RNR;
5925 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005926 }
5927
Mat Martineaue31f7632012-05-17 20:53:41 -07005928 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5929 chan->unacked_frames > 0)
5930 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005931
Mat Martineaue31f7632012-05-17 20:53:41 -07005932 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005933 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005934
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005935 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005936 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5937 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5938 * send it now.
5939 */
5940 control.super = L2CAP_SUPER_RR;
5941 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005942 }
5943}
5944
Gustavo Padovan2d792812012-10-06 10:07:01 +01005945static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5946 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005947{
Mat Martineau84084a32011-07-22 14:54:00 -07005948 /* skb->len reflects data in skb as well as all fragments
5949 * skb->data_len reflects only data in fragments
5950 */
5951 if (!skb_has_frag_list(skb))
5952 skb_shinfo(skb)->frag_list = new_frag;
5953
5954 new_frag->next = NULL;
5955
5956 (*last_frag)->next = new_frag;
5957 *last_frag = new_frag;
5958
5959 skb->len += new_frag->len;
5960 skb->data_len += new_frag->len;
5961 skb->truesize += new_frag->truesize;
5962}
5963
Mat Martineau4b51dae92012-05-17 20:53:37 -07005964static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5965 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005966{
5967 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005968
Mat Martineau4b51dae92012-05-17 20:53:37 -07005969 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005970 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005971 if (chan->sdu)
5972 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005973
Gustavo Padovan80b98022012-05-27 22:27:51 -03005974 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005975 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005976
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005977 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005978 if (chan->sdu)
5979 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005980
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005981 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005982 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005983
Mat Martineau84084a32011-07-22 14:54:00 -07005984 if (chan->sdu_len > chan->imtu) {
5985 err = -EMSGSIZE;
5986 break;
5987 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005988
Mat Martineau84084a32011-07-22 14:54:00 -07005989 if (skb->len >= chan->sdu_len)
5990 break;
5991
5992 chan->sdu = skb;
5993 chan->sdu_last_frag = skb;
5994
5995 skb = NULL;
5996 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005997 break;
5998
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005999 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03006000 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07006001 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006002
Mat Martineau84084a32011-07-22 14:54:00 -07006003 append_skb_frag(chan->sdu, skb,
6004 &chan->sdu_last_frag);
6005 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006006
Mat Martineau84084a32011-07-22 14:54:00 -07006007 if (chan->sdu->len >= chan->sdu_len)
6008 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03006009
Mat Martineau84084a32011-07-22 14:54:00 -07006010 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006011 break;
6012
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03006013 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03006014 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07006015 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006016
Mat Martineau84084a32011-07-22 14:54:00 -07006017 append_skb_frag(chan->sdu, skb,
6018 &chan->sdu_last_frag);
6019 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006020
Mat Martineau84084a32011-07-22 14:54:00 -07006021 if (chan->sdu->len != chan->sdu_len)
6022 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006023
Gustavo Padovan80b98022012-05-27 22:27:51 -03006024 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03006025
Mat Martineau84084a32011-07-22 14:54:00 -07006026 if (!err) {
6027 /* Reassembly complete */
6028 chan->sdu = NULL;
6029 chan->sdu_last_frag = NULL;
6030 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03006031 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006032 break;
6033 }
6034
Mat Martineau84084a32011-07-22 14:54:00 -07006035 if (err) {
6036 kfree_skb(skb);
6037 kfree_skb(chan->sdu);
6038 chan->sdu = NULL;
6039 chan->sdu_last_frag = NULL;
6040 chan->sdu_len = 0;
6041 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006042
Mat Martineau84084a32011-07-22 14:54:00 -07006043 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006044}
6045
Mat Martineau32b32732012-10-23 15:24:11 -07006046static int l2cap_resegment(struct l2cap_chan *chan)
6047{
6048 /* Placeholder */
6049 return 0;
6050}
6051
Mat Martineaue3281402011-07-07 09:39:02 -07006052void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132eb2010-06-21 19:39:50 -03006053{
Mat Martineau61aa4f52012-05-17 20:53:40 -07006054 u8 event;
6055
6056 if (chan->mode != L2CAP_MODE_ERTM)
6057 return;
6058
6059 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03006060 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03006061}
6062
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006063static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
6064{
Mat Martineau63838722012-05-17 20:53:45 -07006065 int err = 0;
6066 /* Pass sequential frames to l2cap_reassemble_sdu()
6067 * until a gap is encountered.
6068 */
6069
6070 BT_DBG("chan %p", chan);
6071
6072 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6073 struct sk_buff *skb;
6074 BT_DBG("Searching for skb with txseq %d (queue len %d)",
6075 chan->buffer_seq, skb_queue_len(&chan->srej_q));
6076
6077 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
6078
6079 if (!skb)
6080 break;
6081
6082 skb_unlink(skb, &chan->srej_q);
6083 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6084 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
6085 if (err)
6086 break;
6087 }
6088
6089 if (skb_queue_empty(&chan->srej_q)) {
6090 chan->rx_state = L2CAP_RX_STATE_RECV;
6091 l2cap_send_ack(chan);
6092 }
6093
6094 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006095}
6096
6097static void l2cap_handle_srej(struct l2cap_chan *chan,
6098 struct l2cap_ctrl *control)
6099{
Mat Martineauf80842a2012-05-17 20:53:46 -07006100 struct sk_buff *skb;
6101
6102 BT_DBG("chan %p, control %p", chan, control);
6103
6104 if (control->reqseq == chan->next_tx_seq) {
6105 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006106 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07006107 return;
6108 }
6109
6110 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
6111
6112 if (skb == NULL) {
6113 BT_DBG("Seq %d not available for retransmission",
6114 control->reqseq);
6115 return;
6116 }
6117
6118 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
6119 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006120 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07006121 return;
6122 }
6123
6124 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6125
6126 if (control->poll) {
6127 l2cap_pass_to_tx(chan, control);
6128
6129 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6130 l2cap_retransmit(chan, control);
6131 l2cap_ertm_send(chan);
6132
6133 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
6134 set_bit(CONN_SREJ_ACT, &chan->conn_state);
6135 chan->srej_save_reqseq = control->reqseq;
6136 }
6137 } else {
6138 l2cap_pass_to_tx_fbit(chan, control);
6139
6140 if (control->final) {
6141 if (chan->srej_save_reqseq != control->reqseq ||
6142 !test_and_clear_bit(CONN_SREJ_ACT,
6143 &chan->conn_state))
6144 l2cap_retransmit(chan, control);
6145 } else {
6146 l2cap_retransmit(chan, control);
6147 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
6148 set_bit(CONN_SREJ_ACT, &chan->conn_state);
6149 chan->srej_save_reqseq = control->reqseq;
6150 }
6151 }
6152 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006153}
6154
6155static void l2cap_handle_rej(struct l2cap_chan *chan,
6156 struct l2cap_ctrl *control)
6157{
Mat Martineaufcd289d2012-05-17 20:53:47 -07006158 struct sk_buff *skb;
6159
6160 BT_DBG("chan %p, control %p", chan, control);
6161
6162 if (control->reqseq == chan->next_tx_seq) {
6163 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006164 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07006165 return;
6166 }
6167
6168 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
6169
6170 if (chan->max_tx && skb &&
6171 bt_cb(skb)->control.retries >= chan->max_tx) {
6172 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006173 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07006174 return;
6175 }
6176
6177 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6178
6179 l2cap_pass_to_tx(chan, control);
6180
6181 if (control->final) {
6182 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
6183 l2cap_retransmit_all(chan, control);
6184 } else {
6185 l2cap_retransmit_all(chan, control);
6186 l2cap_ertm_send(chan);
6187 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
6188 set_bit(CONN_REJ_ACT, &chan->conn_state);
6189 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006190}
6191
Mat Martineau4b51dae92012-05-17 20:53:37 -07006192static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
6193{
6194 BT_DBG("chan %p, txseq %d", chan, txseq);
6195
6196 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
6197 chan->expected_tx_seq);
6198
6199 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
6200 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01006201 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07006202 /* See notes below regarding "double poll" and
6203 * invalid packets.
6204 */
6205 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
6206 BT_DBG("Invalid/Ignore - after SREJ");
6207 return L2CAP_TXSEQ_INVALID_IGNORE;
6208 } else {
6209 BT_DBG("Invalid - in window after SREJ sent");
6210 return L2CAP_TXSEQ_INVALID;
6211 }
6212 }
6213
6214 if (chan->srej_list.head == txseq) {
6215 BT_DBG("Expected SREJ");
6216 return L2CAP_TXSEQ_EXPECTED_SREJ;
6217 }
6218
6219 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
6220 BT_DBG("Duplicate SREJ - txseq already stored");
6221 return L2CAP_TXSEQ_DUPLICATE_SREJ;
6222 }
6223
6224 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
6225 BT_DBG("Unexpected SREJ - not requested");
6226 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
6227 }
6228 }
6229
6230 if (chan->expected_tx_seq == txseq) {
6231 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
6232 chan->tx_win) {
6233 BT_DBG("Invalid - txseq outside tx window");
6234 return L2CAP_TXSEQ_INVALID;
6235 } else {
6236 BT_DBG("Expected");
6237 return L2CAP_TXSEQ_EXPECTED;
6238 }
6239 }
6240
6241 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01006242 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07006243 BT_DBG("Duplicate - expected_tx_seq later than txseq");
6244 return L2CAP_TXSEQ_DUPLICATE;
6245 }
6246
6247 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
6248 /* A source of invalid packets is a "double poll" condition,
6249 * where delays cause us to send multiple poll packets. If
6250 * the remote stack receives and processes both polls,
6251 * sequence numbers can wrap around in such a way that a
6252 * resent frame has a sequence number that looks like new data
6253 * with a sequence gap. This would trigger an erroneous SREJ
6254 * request.
6255 *
6256 * Fortunately, this is impossible with a tx window that's
6257 * less than half of the maximum sequence number, which allows
6258 * invalid frames to be safely ignored.
6259 *
6260 * With tx window sizes greater than half of the tx window
6261 * maximum, the frame is invalid and cannot be ignored. This
6262 * causes a disconnect.
6263 */
6264
6265 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
6266 BT_DBG("Invalid/Ignore - txseq outside tx window");
6267 return L2CAP_TXSEQ_INVALID_IGNORE;
6268 } else {
6269 BT_DBG("Invalid - txseq outside tx window");
6270 return L2CAP_TXSEQ_INVALID;
6271 }
6272 } else {
6273 BT_DBG("Unexpected - txseq indicates missing frames");
6274 return L2CAP_TXSEQ_UNEXPECTED;
6275 }
6276}
6277
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006278static int l2cap_rx_state_recv(struct l2cap_chan *chan,
6279 struct l2cap_ctrl *control,
6280 struct sk_buff *skb, u8 event)
6281{
6282 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006283 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006284
6285 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6286 event);
6287
6288 switch (event) {
6289 case L2CAP_EV_RECV_IFRAME:
6290 switch (l2cap_classify_txseq(chan, control->txseq)) {
6291 case L2CAP_TXSEQ_EXPECTED:
6292 l2cap_pass_to_tx(chan, control);
6293
6294 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6295 BT_DBG("Busy, discarding expected seq %d",
6296 control->txseq);
6297 break;
6298 }
6299
6300 chan->expected_tx_seq = __next_seq(chan,
6301 control->txseq);
6302
6303 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006304 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006305
6306 err = l2cap_reassemble_sdu(chan, skb, control);
6307 if (err)
6308 break;
6309
6310 if (control->final) {
6311 if (!test_and_clear_bit(CONN_REJ_ACT,
6312 &chan->conn_state)) {
6313 control->final = 0;
6314 l2cap_retransmit_all(chan, control);
6315 l2cap_ertm_send(chan);
6316 }
6317 }
6318
6319 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
6320 l2cap_send_ack(chan);
6321 break;
6322 case L2CAP_TXSEQ_UNEXPECTED:
6323 l2cap_pass_to_tx(chan, control);
6324
6325 /* Can't issue SREJ frames in the local busy state.
6326 * Drop this frame, it will be seen as missing
6327 * when local busy is exited.
6328 */
6329 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6330 BT_DBG("Busy, discarding unexpected seq %d",
6331 control->txseq);
6332 break;
6333 }
6334
6335 /* There was a gap in the sequence, so an SREJ
6336 * must be sent for each missing frame. The
6337 * current frame is stored for later use.
6338 */
6339 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006340 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006341 BT_DBG("Queued %p (queue len %d)", skb,
6342 skb_queue_len(&chan->srej_q));
6343
6344 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
6345 l2cap_seq_list_clear(&chan->srej_list);
6346 l2cap_send_srej(chan, control->txseq);
6347
6348 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
6349 break;
6350 case L2CAP_TXSEQ_DUPLICATE:
6351 l2cap_pass_to_tx(chan, control);
6352 break;
6353 case L2CAP_TXSEQ_INVALID_IGNORE:
6354 break;
6355 case L2CAP_TXSEQ_INVALID:
6356 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006357 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006358 break;
6359 }
6360 break;
6361 case L2CAP_EV_RECV_RR:
6362 l2cap_pass_to_tx(chan, control);
6363 if (control->final) {
6364 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6365
Mat Martineaue6a3ee62012-10-23 15:24:22 -07006366 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
6367 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006368 control->final = 0;
6369 l2cap_retransmit_all(chan, control);
6370 }
6371
6372 l2cap_ertm_send(chan);
6373 } else if (control->poll) {
6374 l2cap_send_i_or_rr_or_rnr(chan);
6375 } else {
6376 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6377 &chan->conn_state) &&
6378 chan->unacked_frames)
6379 __set_retrans_timer(chan);
6380
6381 l2cap_ertm_send(chan);
6382 }
6383 break;
6384 case L2CAP_EV_RECV_RNR:
6385 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6386 l2cap_pass_to_tx(chan, control);
6387 if (control && control->poll) {
6388 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6389 l2cap_send_rr_or_rnr(chan, 0);
6390 }
6391 __clear_retrans_timer(chan);
6392 l2cap_seq_list_clear(&chan->retrans_list);
6393 break;
6394 case L2CAP_EV_RECV_REJ:
6395 l2cap_handle_rej(chan, control);
6396 break;
6397 case L2CAP_EV_RECV_SREJ:
6398 l2cap_handle_srej(chan, control);
6399 break;
6400 default:
6401 break;
6402 }
6403
6404 if (skb && !skb_in_use) {
6405 BT_DBG("Freeing %p", skb);
6406 kfree_skb(skb);
6407 }
6408
6409 return err;
6410}
6411
6412static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
6413 struct l2cap_ctrl *control,
6414 struct sk_buff *skb, u8 event)
6415{
6416 int err = 0;
6417 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006418 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006419
6420 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6421 event);
6422
6423 switch (event) {
6424 case L2CAP_EV_RECV_IFRAME:
6425 switch (l2cap_classify_txseq(chan, txseq)) {
6426 case L2CAP_TXSEQ_EXPECTED:
6427 /* Keep frame for reassembly later */
6428 l2cap_pass_to_tx(chan, control);
6429 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006430 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006431 BT_DBG("Queued %p (queue len %d)", skb,
6432 skb_queue_len(&chan->srej_q));
6433
6434 chan->expected_tx_seq = __next_seq(chan, txseq);
6435 break;
6436 case L2CAP_TXSEQ_EXPECTED_SREJ:
6437 l2cap_seq_list_pop(&chan->srej_list);
6438
6439 l2cap_pass_to_tx(chan, control);
6440 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006441 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006442 BT_DBG("Queued %p (queue len %d)", skb,
6443 skb_queue_len(&chan->srej_q));
6444
6445 err = l2cap_rx_queued_iframes(chan);
6446 if (err)
6447 break;
6448
6449 break;
6450 case L2CAP_TXSEQ_UNEXPECTED:
6451 /* Got a frame that can't be reassembled yet.
6452 * Save it for later, and send SREJs to cover
6453 * the missing frames.
6454 */
6455 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006456 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006457 BT_DBG("Queued %p (queue len %d)", skb,
6458 skb_queue_len(&chan->srej_q));
6459
6460 l2cap_pass_to_tx(chan, control);
6461 l2cap_send_srej(chan, control->txseq);
6462 break;
6463 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
6464 /* This frame was requested with an SREJ, but
6465 * some expected retransmitted frames are
6466 * missing. Request retransmission of missing
6467 * SREJ'd frames.
6468 */
6469 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006470 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006471 BT_DBG("Queued %p (queue len %d)", skb,
6472 skb_queue_len(&chan->srej_q));
6473
6474 l2cap_pass_to_tx(chan, control);
6475 l2cap_send_srej_list(chan, control->txseq);
6476 break;
6477 case L2CAP_TXSEQ_DUPLICATE_SREJ:
6478 /* We've already queued this frame. Drop this copy. */
6479 l2cap_pass_to_tx(chan, control);
6480 break;
6481 case L2CAP_TXSEQ_DUPLICATE:
6482 /* Expecting a later sequence number, so this frame
6483 * was already received. Ignore it completely.
6484 */
6485 break;
6486 case L2CAP_TXSEQ_INVALID_IGNORE:
6487 break;
6488 case L2CAP_TXSEQ_INVALID:
6489 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006490 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006491 break;
6492 }
6493 break;
6494 case L2CAP_EV_RECV_RR:
6495 l2cap_pass_to_tx(chan, control);
6496 if (control->final) {
6497 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6498
6499 if (!test_and_clear_bit(CONN_REJ_ACT,
6500 &chan->conn_state)) {
6501 control->final = 0;
6502 l2cap_retransmit_all(chan, control);
6503 }
6504
6505 l2cap_ertm_send(chan);
6506 } else if (control->poll) {
6507 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6508 &chan->conn_state) &&
6509 chan->unacked_frames) {
6510 __set_retrans_timer(chan);
6511 }
6512
6513 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6514 l2cap_send_srej_tail(chan);
6515 } else {
6516 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6517 &chan->conn_state) &&
6518 chan->unacked_frames)
6519 __set_retrans_timer(chan);
6520
6521 l2cap_send_ack(chan);
6522 }
6523 break;
6524 case L2CAP_EV_RECV_RNR:
6525 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6526 l2cap_pass_to_tx(chan, control);
6527 if (control->poll) {
6528 l2cap_send_srej_tail(chan);
6529 } else {
6530 struct l2cap_ctrl rr_control;
6531 memset(&rr_control, 0, sizeof(rr_control));
6532 rr_control.sframe = 1;
6533 rr_control.super = L2CAP_SUPER_RR;
6534 rr_control.reqseq = chan->buffer_seq;
6535 l2cap_send_sframe(chan, &rr_control);
6536 }
6537
6538 break;
6539 case L2CAP_EV_RECV_REJ:
6540 l2cap_handle_rej(chan, control);
6541 break;
6542 case L2CAP_EV_RECV_SREJ:
6543 l2cap_handle_srej(chan, control);
6544 break;
6545 }
6546
6547 if (skb && !skb_in_use) {
6548 BT_DBG("Freeing %p", skb);
6549 kfree_skb(skb);
6550 }
6551
6552 return err;
6553}
6554
Mat Martineau32b32732012-10-23 15:24:11 -07006555static int l2cap_finish_move(struct l2cap_chan *chan)
6556{
6557 BT_DBG("chan %p", chan);
6558
6559 chan->rx_state = L2CAP_RX_STATE_RECV;
6560
6561 if (chan->hs_hcon)
6562 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6563 else
6564 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6565
6566 return l2cap_resegment(chan);
6567}
6568
6569static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6570 struct l2cap_ctrl *control,
6571 struct sk_buff *skb, u8 event)
6572{
6573 int err;
6574
6575 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6576 event);
6577
6578 if (!control->poll)
6579 return -EPROTO;
6580
6581 l2cap_process_reqseq(chan, control->reqseq);
6582
6583 if (!skb_queue_empty(&chan->tx_q))
6584 chan->tx_send_head = skb_peek(&chan->tx_q);
6585 else
6586 chan->tx_send_head = NULL;
6587
6588 /* Rewind next_tx_seq to the point expected
6589 * by the receiver.
6590 */
6591 chan->next_tx_seq = control->reqseq;
6592 chan->unacked_frames = 0;
6593
6594 err = l2cap_finish_move(chan);
6595 if (err)
6596 return err;
6597
6598 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6599 l2cap_send_i_or_rr_or_rnr(chan);
6600
6601 if (event == L2CAP_EV_RECV_IFRAME)
6602 return -EPROTO;
6603
6604 return l2cap_rx_state_recv(chan, control, NULL, event);
6605}
6606
6607static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6608 struct l2cap_ctrl *control,
6609 struct sk_buff *skb, u8 event)
6610{
6611 int err;
6612
6613 if (!control->final)
6614 return -EPROTO;
6615
6616 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6617
6618 chan->rx_state = L2CAP_RX_STATE_RECV;
6619 l2cap_process_reqseq(chan, control->reqseq);
6620
6621 if (!skb_queue_empty(&chan->tx_q))
6622 chan->tx_send_head = skb_peek(&chan->tx_q);
6623 else
6624 chan->tx_send_head = NULL;
6625
6626 /* Rewind next_tx_seq to the point expected
6627 * by the receiver.
6628 */
6629 chan->next_tx_seq = control->reqseq;
6630 chan->unacked_frames = 0;
6631
6632 if (chan->hs_hcon)
6633 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6634 else
6635 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6636
6637 err = l2cap_resegment(chan);
6638
6639 if (!err)
6640 err = l2cap_rx_state_recv(chan, control, skb, event);
6641
6642 return err;
6643}
6644
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006645static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6646{
6647 /* Make sure reqseq is for a packet that has been sent but not acked */
6648 u16 unacked;
6649
6650 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6651 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6652}
6653
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006654static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6655 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006656{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006657 int err = 0;
6658
6659 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6660 control, skb, event, chan->rx_state);
6661
6662 if (__valid_reqseq(chan, control->reqseq)) {
6663 switch (chan->rx_state) {
6664 case L2CAP_RX_STATE_RECV:
6665 err = l2cap_rx_state_recv(chan, control, skb, event);
6666 break;
6667 case L2CAP_RX_STATE_SREJ_SENT:
6668 err = l2cap_rx_state_srej_sent(chan, control, skb,
6669 event);
6670 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006671 case L2CAP_RX_STATE_WAIT_P:
6672 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6673 break;
6674 case L2CAP_RX_STATE_WAIT_F:
6675 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6676 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006677 default:
6678 /* shut it down */
6679 break;
6680 }
6681 } else {
6682 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6683 control->reqseq, chan->next_tx_seq,
6684 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006685 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006686 }
6687
6688 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006689}
6690
6691static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6692 struct sk_buff *skb)
6693{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006694 int err = 0;
6695
6696 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6697 chan->rx_state);
6698
6699 if (l2cap_classify_txseq(chan, control->txseq) ==
6700 L2CAP_TXSEQ_EXPECTED) {
6701 l2cap_pass_to_tx(chan, control);
6702
6703 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6704 __next_seq(chan, chan->buffer_seq));
6705
6706 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6707
6708 l2cap_reassemble_sdu(chan, skb, control);
6709 } else {
6710 if (chan->sdu) {
6711 kfree_skb(chan->sdu);
6712 chan->sdu = NULL;
6713 }
6714 chan->sdu_last_frag = NULL;
6715 chan->sdu_len = 0;
6716
6717 if (skb) {
6718 BT_DBG("Freeing %p", skb);
6719 kfree_skb(skb);
6720 }
6721 }
6722
6723 chan->last_acked_seq = control->txseq;
6724 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6725
6726 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006727}
6728
6729static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6730{
6731 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6732 u16 len;
6733 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006734
Mat Martineaub76bbd62012-04-11 10:48:43 -07006735 __unpack_control(chan, skb);
6736
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006737 len = skb->len;
6738
6739 /*
6740 * We can just drop the corrupted I-frame here.
6741 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006742 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006743 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006744 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006745 goto drop;
6746
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006747 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006748 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006749
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006750 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006751 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006752
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006753 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006754 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006755 goto drop;
6756 }
6757
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006758 if (!control->sframe) {
6759 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006760
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006761 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6762 control->sar, control->reqseq, control->final,
6763 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006764
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006765 /* Validate F-bit - F=0 always valid, F=1 only
6766 * valid in TX WAIT_F
6767 */
6768 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006769 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006770
6771 if (chan->mode != L2CAP_MODE_STREAMING) {
6772 event = L2CAP_EV_RECV_IFRAME;
6773 err = l2cap_rx(chan, control, skb, event);
6774 } else {
6775 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006776 }
6777
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006778 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006779 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006780 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006781 const u8 rx_func_to_event[4] = {
6782 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6783 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6784 };
6785
6786 /* Only I-frames are expected in streaming mode */
6787 if (chan->mode == L2CAP_MODE_STREAMING)
6788 goto drop;
6789
6790 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6791 control->reqseq, control->final, control->poll,
6792 control->super);
6793
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006794 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006795 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006796 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006797 goto drop;
6798 }
6799
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006800 /* Validate F and P bits */
6801 if (control->final && (control->poll ||
6802 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6803 goto drop;
6804
6805 event = rx_func_to_event[control->super];
6806 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006807 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006808 }
6809
6810 return 0;
6811
6812drop:
6813 kfree_skb(skb);
6814 return 0;
6815}
6816
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006817static void l2cap_chan_le_send_credits(struct l2cap_chan *chan)
6818{
6819 struct l2cap_conn *conn = chan->conn;
6820 struct l2cap_le_credits pkt;
6821 u16 return_credits;
6822
6823 /* We return more credits to the sender only after the amount of
6824 * credits falls below half of the initial amount.
6825 */
Johan Hedbergf15b8ec2013-12-03 15:08:25 +02006826 if (chan->rx_credits >= (le_max_credits + 1) / 2)
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006827 return;
6828
Johan Hedbergf15b8ec2013-12-03 15:08:25 +02006829 return_credits = le_max_credits - chan->rx_credits;
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006830
6831 BT_DBG("chan %p returning %u credits to sender", chan, return_credits);
6832
6833 chan->rx_credits += return_credits;
6834
6835 pkt.cid = cpu_to_le16(chan->scid);
6836 pkt.credits = cpu_to_le16(return_credits);
6837
6838 chan->ident = l2cap_get_ident(conn);
6839
6840 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CREDITS, sizeof(pkt), &pkt);
6841}
6842
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006843static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6844{
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006845 int err;
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006846
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006847 if (!chan->rx_credits) {
6848 BT_ERR("No credits to receive LE L2CAP data");
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006849 return -ENOBUFS;
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006850 }
6851
6852 if (chan->imtu < skb->len) {
6853 BT_ERR("Too big LE L2CAP PDU");
6854 return -ENOBUFS;
6855 }
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006856
6857 chan->rx_credits--;
6858 BT_DBG("rx_credits %u -> %u", chan->rx_credits + 1, chan->rx_credits);
6859
6860 l2cap_chan_le_send_credits(chan);
6861
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006862 err = 0;
6863
6864 if (!chan->sdu) {
6865 u16 sdu_len;
6866
6867 sdu_len = get_unaligned_le16(skb->data);
6868 skb_pull(skb, L2CAP_SDULEN_SIZE);
6869
6870 BT_DBG("Start of new SDU. sdu_len %u skb->len %u imtu %u",
6871 sdu_len, skb->len, chan->imtu);
6872
6873 if (sdu_len > chan->imtu) {
6874 BT_ERR("Too big LE L2CAP SDU length received");
6875 err = -EMSGSIZE;
6876 goto failed;
6877 }
6878
6879 if (skb->len > sdu_len) {
6880 BT_ERR("Too much LE L2CAP data received");
6881 err = -EINVAL;
6882 goto failed;
6883 }
6884
6885 if (skb->len == sdu_len)
6886 return chan->ops->recv(chan, skb);
6887
6888 chan->sdu = skb;
6889 chan->sdu_len = sdu_len;
6890 chan->sdu_last_frag = skb;
6891
6892 return 0;
6893 }
6894
6895 BT_DBG("SDU fragment. chan->sdu->len %u skb->len %u chan->sdu_len %u",
6896 chan->sdu->len, skb->len, chan->sdu_len);
6897
6898 if (chan->sdu->len + skb->len > chan->sdu_len) {
6899 BT_ERR("Too much LE L2CAP data received");
6900 err = -EINVAL;
6901 goto failed;
6902 }
6903
6904 append_skb_frag(chan->sdu, skb, &chan->sdu_last_frag);
6905 skb = NULL;
6906
6907 if (chan->sdu->len == chan->sdu_len) {
6908 err = chan->ops->recv(chan, chan->sdu);
6909 if (!err) {
6910 chan->sdu = NULL;
6911 chan->sdu_last_frag = NULL;
6912 chan->sdu_len = 0;
6913 }
6914 }
6915
6916failed:
6917 if (err) {
6918 kfree_skb(skb);
6919 kfree_skb(chan->sdu);
6920 chan->sdu = NULL;
6921 chan->sdu_last_frag = NULL;
6922 chan->sdu_len = 0;
6923 }
6924
6925 /* We can't return an error here since we took care of the skb
6926 * freeing internally. An error return would cause the caller to
6927 * do a double-free of the skb.
6928 */
6929 return 0;
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006930}
6931
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006932static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6933 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006934{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006935 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006936
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006937 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006938 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006939 if (cid == L2CAP_CID_A2MP) {
6940 chan = a2mp_channel_create(conn, skb);
6941 if (!chan) {
6942 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006943 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006944 }
6945
6946 l2cap_chan_lock(chan);
6947 } else {
6948 BT_DBG("unknown cid 0x%4.4x", cid);
6949 /* Drop packet and return */
6950 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006951 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006952 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006953 }
6954
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006955 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006956
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006957 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006958 goto drop;
6959
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006960 switch (chan->mode) {
Johan Hedberg38319712013-05-17 12:49:23 +03006961 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006962 if (l2cap_le_data_rcv(chan, skb) < 0)
6963 goto drop;
6964
6965 goto done;
6966
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006967 case L2CAP_MODE_BASIC:
6968 /* If socket recv buffers overflows we drop data here
6969 * which is *bad* because L2CAP has to be reliable.
6970 * But we don't have any other choice. L2CAP doesn't
6971 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006972
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006973 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006974 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006975
Gustavo Padovan80b98022012-05-27 22:27:51 -03006976 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006977 goto done;
6978 break;
6979
6980 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006981 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006982 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006983 goto done;
6984
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006985 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006986 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006987 break;
6988 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006989
6990drop:
6991 kfree_skb(skb);
6992
6993done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006994 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006995}
6996
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006997static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6998 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006999{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07007000 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007001 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007002
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07007003 if (hcon->type != ACL_LINK)
7004 goto drop;
7005
Johan Hedbergbf20fd42013-05-14 13:23:13 +03007006 chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst,
7007 ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007008 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007009 goto drop;
7010
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02007011 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007012
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03007013 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007014 goto drop;
7015
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03007016 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007017 goto drop;
7018
Marcel Holtmann2edf8702013-10-13 12:55:29 -07007019 /* Store remote BD_ADDR and PSM for msg_name */
Marcel Holtmann06ae3312013-10-18 03:43:00 -07007020 bacpy(&bt_cb(skb)->bdaddr, &hcon->dst);
Marcel Holtmann2edf8702013-10-13 12:55:29 -07007021 bt_cb(skb)->psm = psm;
7022
Gustavo Padovan80b98022012-05-27 22:27:51 -03007023 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03007024 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007025
7026drop:
7027 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007028}
7029
Marcel Holtmann72f78352013-04-23 00:59:00 -07007030static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03007031 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007032{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07007033 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007034 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007035
Marcel Holtmannb99707d2013-10-03 02:54:11 -07007036 if (hcon->type != LE_LINK)
7037 goto drop;
7038
Johan Hedbergaf1c0132013-04-29 19:35:42 +03007039 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann06ae3312013-10-18 03:43:00 -07007040 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007041 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007042 goto drop;
7043
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02007044 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007045
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07007046 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, hcon->dst_type))
7047 goto drop;
7048
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03007049 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007050 goto drop;
7051
Gustavo Padovan80b98022012-05-27 22:27:51 -03007052 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03007053 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007054
7055drop:
7056 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007057}
7058
Linus Torvalds1da177e2005-04-16 15:20:36 -07007059static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
7060{
7061 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07007062 u16 cid, len;
7063 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007064
7065 skb_pull(skb, L2CAP_HDR_SIZE);
7066 cid = __le16_to_cpu(lh->cid);
7067 len = __le16_to_cpu(lh->len);
7068
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03007069 if (len != skb->len) {
7070 kfree_skb(skb);
7071 return;
7072 }
7073
Linus Torvalds1da177e2005-04-16 15:20:36 -07007074 BT_DBG("len %d, cid 0x%4.4x", len, cid);
7075
7076 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03007077 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007078 l2cap_sig_channel(conn, skb);
7079 break;
7080
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03007081 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02007082 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03007083 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007084 l2cap_conless_channel(conn, psm, skb);
7085 break;
7086
Johan Hedberg073d1cf2013-04-29 19:35:35 +03007087 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07007088 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007089 break;
7090
Marcel Holtmanna2877622013-10-02 23:46:54 -07007091 case L2CAP_CID_LE_SIGNALING:
7092 l2cap_le_sig_channel(conn, skb);
7093 break;
7094
Anderson Brigliab501d6a2011-06-07 18:46:31 -03007095 case L2CAP_CID_SMP:
7096 if (smp_sig_channel(conn, skb))
7097 l2cap_conn_del(conn->hcon, EACCES);
7098 break;
7099
Linus Torvalds1da177e2005-04-16 15:20:36 -07007100 default:
7101 l2cap_data_channel(conn, cid, skb);
7102 break;
7103 }
7104}
7105
7106/* ---- L2CAP interface with lower layer (HCI) ---- */
7107
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007108int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007109{
7110 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007111 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007112
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03007113 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007114
7115 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007116 read_lock(&chan_list_lock);
7117 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03007118 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007119 continue;
7120
Marcel Holtmann7eafc592013-10-13 08:12:47 -07007121 if (!bacmp(&c->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007122 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03007123 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007124 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007125 exact++;
Marcel Holtmann7eafc592013-10-13 08:12:47 -07007126 } else if (!bacmp(&c->src, BDADDR_ANY)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007127 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03007128 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007129 lm2 |= HCI_LM_MASTER;
7130 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007131 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007132 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007133
7134 return exact ? lm1 : lm2;
7135}
7136
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03007137void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007138{
Marcel Holtmann01394182006-07-03 10:02:46 +02007139 struct l2cap_conn *conn;
7140
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03007141 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007142
Linus Torvalds1da177e2005-04-16 15:20:36 -07007143 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03007144 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007145 if (conn)
7146 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02007147 } else {
Joe Perchese1750722011-06-29 18:18:29 -07007148 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02007149 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007150}
7151
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007152int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01007153{
7154 struct l2cap_conn *conn = hcon->l2cap_data;
7155
7156 BT_DBG("hcon %p", hcon);
7157
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007158 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02007159 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01007160 return conn->disc_reason;
7161}
7162
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03007163void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007164{
7165 BT_DBG("hcon %p reason %d", hcon, reason);
7166
Joe Perchese1750722011-06-29 18:18:29 -07007167 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007168}
7169
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007170static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007171{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03007172 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01007173 return;
7174
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007175 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007176 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007177 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007178 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03007179 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007180 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007181 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03007182 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007183 }
7184}
7185
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007186int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007187{
Marcel Holtmann40be4922008-07-14 20:13:50 +02007188 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03007189 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007190
Marcel Holtmann01394182006-07-03 10:02:46 +02007191 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007192 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02007193
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03007194 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007195
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03007196 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05307197 if (!status && encrypt)
7198 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02007199 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03007200 }
7201
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007202 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007203
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007204 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007205 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007206
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03007207 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
7208 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007209
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03007210 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
7211 l2cap_chan_unlock(chan);
7212 continue;
7213 }
7214
Johan Hedberg073d1cf2013-04-29 19:35:35 +03007215 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007216 if (!status && encrypt) {
7217 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02007218 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007219 }
7220
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007221 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007222 continue;
7223 }
7224
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02007225 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007226 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01007227 continue;
7228 }
7229
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03007230 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01007231 chan->state == BT_CONFIG)) {
Marcel Holtmannd97c8992013-10-14 02:53:54 -07007232 chan->ops->resume(chan);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007233 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007234 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02007235 continue;
7236 }
7237
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03007238 if (chan->state == BT_CONNECT) {
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02007239 if (!status)
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03007240 l2cap_start_connection(chan);
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02007241 else
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007242 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03007243 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007244 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007245 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007246
7247 if (!status) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07007248 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007249 res = L2CAP_CR_PEND;
7250 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08007251 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007252 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02007253 l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007254 res = L2CAP_CR_SUCCESS;
7255 stat = L2CAP_CS_NO_INFO;
7256 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007257 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02007258 l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007259 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007260 res = L2CAP_CR_SEC_BLOCK;
7261 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007262 }
7263
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03007264 rsp.scid = cpu_to_le16(chan->dcid);
7265 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007266 rsp.result = cpu_to_le16(res);
7267 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03007268 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01007269 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07007270
7271 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
7272 res == L2CAP_CR_SUCCESS) {
7273 char buf[128];
7274 set_bit(CONF_REQ_SENT, &chan->conf_state);
7275 l2cap_send_cmd(conn, l2cap_get_ident(conn),
7276 L2CAP_CONF_REQ,
7277 l2cap_build_conf_req(chan, buf),
7278 buf);
7279 chan->num_conf_req++;
7280 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007281 }
7282
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007283 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007284 }
7285
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007286 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007287
Linus Torvalds1da177e2005-04-16 15:20:36 -07007288 return 0;
7289}
7290
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007291int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007292{
7293 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007294 struct l2cap_hdr *hdr;
7295 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007296
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03007297 /* For AMP controller do not create l2cap conn */
7298 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
7299 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007300
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02007301 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03007302 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02007303
7304 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007305 goto drop;
7306
7307 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
7308
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007309 switch (flags) {
7310 case ACL_START:
7311 case ACL_START_NO_FLUSH:
7312 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007313 if (conn->rx_len) {
7314 BT_ERR("Unexpected start frame (len %d)", skb->len);
7315 kfree_skb(conn->rx_skb);
7316 conn->rx_skb = NULL;
7317 conn->rx_len = 0;
7318 l2cap_conn_unreliable(conn, ECOMM);
7319 }
7320
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03007321 /* Start fragment always begin with Basic L2CAP header */
7322 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007323 BT_ERR("Frame is too short (len %d)", skb->len);
7324 l2cap_conn_unreliable(conn, ECOMM);
7325 goto drop;
7326 }
7327
7328 hdr = (struct l2cap_hdr *) skb->data;
7329 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
7330
7331 if (len == skb->len) {
7332 /* Complete frame received */
7333 l2cap_recv_frame(conn, skb);
7334 return 0;
7335 }
7336
7337 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
7338
7339 if (skb->len > len) {
7340 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007341 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007342 l2cap_conn_unreliable(conn, ECOMM);
7343 goto drop;
7344 }
7345
7346 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03007347 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03007348 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007349 goto drop;
7350
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007351 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007352 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007353 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007354 break;
7355
7356 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007357 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
7358
7359 if (!conn->rx_len) {
7360 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
7361 l2cap_conn_unreliable(conn, ECOMM);
7362 goto drop;
7363 }
7364
7365 if (skb->len > conn->rx_len) {
7366 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007367 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007368 kfree_skb(conn->rx_skb);
7369 conn->rx_skb = NULL;
7370 conn->rx_len = 0;
7371 l2cap_conn_unreliable(conn, ECOMM);
7372 goto drop;
7373 }
7374
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007375 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007376 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007377 conn->rx_len -= skb->len;
7378
7379 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007380 /* Complete frame received. l2cap_recv_frame
7381 * takes ownership of the skb so set the global
7382 * rx_skb pointer to NULL first.
7383 */
7384 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007385 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007386 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007387 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007388 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007389 }
7390
7391drop:
7392 kfree_skb(skb);
7393 return 0;
7394}
7395
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007396static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007397{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007398 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007399
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007400 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007401
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007402 list_for_each_entry(c, &chan_list, global_l) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007403 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 -07007404 &c->src, &c->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007405 c->state, __le16_to_cpu(c->psm),
7406 c->scid, c->dcid, c->imtu, c->omtu,
7407 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02007408 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007409
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007410 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007411
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007412 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007413}
7414
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007415static int l2cap_debugfs_open(struct inode *inode, struct file *file)
7416{
7417 return single_open(file, l2cap_debugfs_show, inode->i_private);
7418}
7419
7420static const struct file_operations l2cap_debugfs_fops = {
7421 .open = l2cap_debugfs_open,
7422 .read = seq_read,
7423 .llseek = seq_lseek,
7424 .release = single_release,
7425};
7426
7427static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007428
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007429int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007430{
7431 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007432
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007433 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007434 if (err < 0)
7435 return err;
7436
Marcel Holtmann1120e4b2013-10-17 17:24:16 -07007437 if (IS_ERR_OR_NULL(bt_debugfs))
7438 return 0;
7439
7440 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
7441 NULL, &l2cap_debugfs_fops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007442
Johan Hedbergf15b8ec2013-12-03 15:08:25 +02007443 debugfs_create_u16("l2cap_le_max_credits", 0466, bt_debugfs,
7444 &le_max_credits);
7445 debugfs_create_u16("l2cap_le_default_mps", 0466, bt_debugfs,
7446 &le_default_mps);
7447
Linus Torvalds1da177e2005-04-16 15:20:36 -07007448 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007449}
7450
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007451void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007452{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007453 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007454 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007455}
7456
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03007457module_param(disable_ertm, bool, 0644);
7458MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");