blob: 8e9e883874ce86b6042cfd063ed077d3ab0aad8c [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. Padovan89bc5002011-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. Padovan89bc5002011-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. Padovan89bc5002011-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. Padovan89bc5002011-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. Padovan89bc5002011-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. Padovan89bc5002011-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 Hedberg38319712013-05-17 12:49:23 +0300501void l2cap_le_flowctl_init(struct l2cap_chan *chan)
502{
503 chan->imtu = L2CAP_DEFAULT_MTU;
504 chan->omtu = L2CAP_LE_MIN_MTU;
505 chan->mode = L2CAP_MODE_LE_FLOWCTL;
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 Hedberg38319712013-05-17 12:49:23 +0300513}
514
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300515void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200516{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300517 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200518 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200519
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200520 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100521
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300522 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200523
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200524 switch (chan->chan_type) {
525 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300526 if (conn->hcon->type == LE_LINK) {
Johan Hedbergaeddd072013-10-07 16:15:25 +0200527 if (chan->dcid == L2CAP_CID_ATT) {
528 chan->omtu = L2CAP_DEFAULT_MTU;
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300529 chan->scid = L2CAP_CID_ATT;
Johan Hedbergaeddd072013-10-07 16:15:25 +0200530 } else {
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300531 chan->scid = l2cap_alloc_cid(conn);
Johan Hedbergaeddd072013-10-07 16:15:25 +0200532 }
Ville Tervob62f3282011-02-10 22:38:50 -0300533 } else {
534 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300535 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300536 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300537 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200538 break;
539
540 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200541 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300542 chan->scid = L2CAP_CID_CONN_LESS;
543 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300544 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200545 break;
546
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300547 case L2CAP_CHAN_CONN_FIX_A2MP:
548 chan->scid = L2CAP_CID_A2MP;
549 chan->dcid = L2CAP_CID_A2MP;
550 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
551 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
552 break;
553
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200554 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200555 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300556 chan->scid = L2CAP_CID_SIGNALING;
557 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300558 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200559 }
560
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300561 chan->local_id = L2CAP_BESTEFFORT_ID;
562 chan->local_stype = L2CAP_SERV_BESTEFFORT;
563 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
564 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
565 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300566 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300567
Ulisses Furquim371fd832011-12-21 20:02:36 -0200568 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300569
Johan Hedberg5ee98912013-04-29 19:35:43 +0300570 hci_conn_hold(conn->hcon);
571
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200572 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200573}
574
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300575void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200576{
577 mutex_lock(&conn->chan_lock);
578 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200579 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200580}
581
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300582void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200583{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300584 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200585
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300586 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200587
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300588 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200589
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900590 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300591 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300592 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200593 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200594
Ulisses Furquim371fd832011-12-21 20:02:36 -0200595 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300596
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300597 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300598
599 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200600 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300601
602 if (mgr && mgr->bredr_chan == chan)
603 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200604 }
605
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200606 if (chan->hs_hchan) {
607 struct hci_chan *hs_hchan = chan->hs_hchan;
608
609 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
610 amp_disconnect_logical_link(hs_hchan);
611 }
612
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100613 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200614
Mat Martineau28270112012-05-17 21:14:09 -0700615 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300616 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300617
Gustavo Padovanee556f62012-05-18 20:22:38 -0300618 switch(chan->mode) {
619 case L2CAP_MODE_BASIC:
620 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300621
Johan Hedberg38319712013-05-17 12:49:23 +0300622 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedberg177f8f22013-05-31 17:54:51 +0300623 skb_queue_purge(&chan->tx_q);
Johan Hedberg38319712013-05-17 12:49:23 +0300624 break;
625
Gustavo Padovanee556f62012-05-18 20:22:38 -0300626 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300627 __clear_retrans_timer(chan);
628 __clear_monitor_timer(chan);
629 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300630
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300631 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300632
Mat Martineau3c588192012-04-11 10:48:42 -0700633 l2cap_seq_list_free(&chan->srej_list);
634 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300635
636 /* fall through */
637
638 case L2CAP_MODE_STREAMING:
639 skb_queue_purge(&chan->tx_q);
640 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300641 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300642
643 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200644}
645
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300646static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
647{
648 struct l2cap_conn *conn = chan->conn;
649 struct l2cap_le_conn_rsp rsp;
650 u16 result;
651
652 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
653 result = L2CAP_CR_AUTHORIZATION;
654 else
655 result = L2CAP_CR_BAD_PSM;
656
657 l2cap_state_change(chan, BT_DISCONN);
658
659 rsp.dcid = cpu_to_le16(chan->scid);
660 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +0200661 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +0300662 rsp.credits = cpu_to_le16(chan->rx_credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300663 rsp.result = cpu_to_le16(result);
664
665 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
666 &rsp);
667}
668
Johan Hedberg791d60f2013-05-14 22:24:44 +0300669static void l2cap_chan_connect_reject(struct l2cap_chan *chan)
670{
671 struct l2cap_conn *conn = chan->conn;
672 struct l2cap_conn_rsp rsp;
673 u16 result;
674
675 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
676 result = L2CAP_CR_SEC_BLOCK;
677 else
678 result = L2CAP_CR_BAD_PSM;
679
680 l2cap_state_change(chan, BT_DISCONN);
681
682 rsp.scid = cpu_to_le16(chan->dcid);
683 rsp.dcid = cpu_to_le16(chan->scid);
684 rsp.result = cpu_to_le16(result);
685 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
686
687 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
688}
689
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300690void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300691{
692 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300693
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700694 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300695
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300696 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300697 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100698 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300699 break;
700
701 case BT_CONNECTED:
702 case BT_CONFIG:
Johan Hedbergcea04ce32013-05-14 22:46:01 +0300703 /* ATT uses L2CAP_CHAN_CONN_ORIENTED so we must also
704 * check for chan->psm.
705 */
706 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && chan->psm) {
Gustavo Padovan8d836d72013-10-15 19:24:47 -0300707 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200708 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300709 } else
710 l2cap_chan_del(chan, reason);
711 break;
712
713 case BT_CONNECT2:
Johan Hedberg791d60f2013-05-14 22:24:44 +0300714 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) {
715 if (conn->hcon->type == ACL_LINK)
716 l2cap_chan_connect_reject(chan);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300717 else if (conn->hcon->type == LE_LINK)
718 l2cap_chan_le_connect_reject(chan);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300719 }
720
721 l2cap_chan_del(chan, reason);
722 break;
723
724 case BT_CONNECT:
725 case BT_DISCONN:
726 l2cap_chan_del(chan, reason);
727 break;
728
729 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100730 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300731 break;
732 }
733}
734
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300735static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530736{
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700737 switch (chan->chan_type) {
738 case L2CAP_CHAN_RAW:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300739 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530740 case BT_SECURITY_HIGH:
741 return HCI_AT_DEDICATED_BONDING_MITM;
742 case BT_SECURITY_MEDIUM:
743 return HCI_AT_DEDICATED_BONDING;
744 default:
745 return HCI_AT_NO_BONDING;
746 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700747 break;
Marcel Holtmann3124b842013-10-12 07:19:32 -0700748 case L2CAP_CHAN_CONN_LESS:
749 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_3DSP)) {
750 if (chan->sec_level == BT_SECURITY_LOW)
751 chan->sec_level = BT_SECURITY_SDP;
752 }
753 if (chan->sec_level == BT_SECURITY_HIGH)
754 return HCI_AT_NO_BONDING_MITM;
755 else
756 return HCI_AT_NO_BONDING;
757 break;
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700758 case L2CAP_CHAN_CONN_ORIENTED:
759 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
760 if (chan->sec_level == BT_SECURITY_LOW)
761 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530762
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700763 if (chan->sec_level == BT_SECURITY_HIGH)
764 return HCI_AT_NO_BONDING_MITM;
765 else
766 return HCI_AT_NO_BONDING;
767 }
768 /* fall through */
769 default:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300770 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530771 case BT_SECURITY_HIGH:
772 return HCI_AT_GENERAL_BONDING_MITM;
773 case BT_SECURITY_MEDIUM:
774 return HCI_AT_GENERAL_BONDING;
775 default:
776 return HCI_AT_NO_BONDING;
777 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700778 break;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530779 }
780}
781
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200782/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200783int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200784{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300785 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100786 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200787
Johan Hedberga17de2f2013-05-14 13:25:37 +0300788 if (conn->hcon->type == LE_LINK)
789 return smp_conn_security(conn->hcon, chan->sec_level);
790
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300791 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100792
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300793 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200794}
795
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200796static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200797{
798 u8 id;
799
800 /* Get next available identificator.
801 * 1 - 128 are used by kernel.
802 * 129 - 199 are reserved.
803 * 200 - 254 are used by utilities like l2ping, etc.
804 */
805
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200806 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200807
808 if (++conn->tx_ident > 128)
809 conn->tx_ident = 1;
810
811 id = conn->tx_ident;
812
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200813 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200814
815 return id;
816}
817
Gustavo Padovan2d792812012-10-06 10:07:01 +0100818static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
819 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200820{
821 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200822 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200823
824 BT_DBG("code 0x%2.2x", code);
825
826 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300827 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200828
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200829 if (lmp_no_flush_capable(conn->hcon->hdev))
830 flags = ACL_START_NO_FLUSH;
831 else
832 flags = ACL_START;
833
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700834 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200835 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700836
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200837 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200838}
839
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700840static bool __chan_is_moving(struct l2cap_chan *chan)
841{
842 return chan->move_state != L2CAP_MOVE_STABLE &&
843 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
844}
845
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200846static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
847{
848 struct hci_conn *hcon = chan->conn->hcon;
849 u16 flags;
850
851 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100852 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200853
Mat Martineaud5f8a752012-10-23 15:24:18 -0700854 if (chan->hs_hcon && !__chan_is_moving(chan)) {
855 if (chan->hs_hchan)
856 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
857 else
858 kfree_skb(skb);
859
860 return;
861 }
862
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200863 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100864 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200865 flags = ACL_START_NO_FLUSH;
866 else
867 flags = ACL_START;
868
869 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
870 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871}
872
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700873static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
874{
875 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
876 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
877
878 if (enh & L2CAP_CTRL_FRAME_TYPE) {
879 /* S-Frame */
880 control->sframe = 1;
881 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
882 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
883
884 control->sar = 0;
885 control->txseq = 0;
886 } else {
887 /* I-Frame */
888 control->sframe = 0;
889 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
890 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
891
892 control->poll = 0;
893 control->super = 0;
894 }
895}
896
897static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
898{
899 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
900 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
901
902 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
903 /* S-Frame */
904 control->sframe = 1;
905 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
906 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
907
908 control->sar = 0;
909 control->txseq = 0;
910 } else {
911 /* I-Frame */
912 control->sframe = 0;
913 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
914 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
915
916 control->poll = 0;
917 control->super = 0;
918 }
919}
920
921static inline void __unpack_control(struct l2cap_chan *chan,
922 struct sk_buff *skb)
923{
924 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
925 __unpack_extended_control(get_unaligned_le32(skb->data),
926 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700927 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700928 } else {
929 __unpack_enhanced_control(get_unaligned_le16(skb->data),
930 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700931 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700932 }
933}
934
935static u32 __pack_extended_control(struct l2cap_ctrl *control)
936{
937 u32 packed;
938
939 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
940 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
941
942 if (control->sframe) {
943 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
944 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
945 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
946 } else {
947 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
948 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
949 }
950
951 return packed;
952}
953
954static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
955{
956 u16 packed;
957
958 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
959 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
960
961 if (control->sframe) {
962 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
963 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
964 packed |= L2CAP_CTRL_FRAME_TYPE;
965 } else {
966 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
967 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
968 }
969
970 return packed;
971}
972
973static inline void __pack_control(struct l2cap_chan *chan,
974 struct l2cap_ctrl *control,
975 struct sk_buff *skb)
976{
977 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
978 put_unaligned_le32(__pack_extended_control(control),
979 skb->data + L2CAP_HDR_SIZE);
980 } else {
981 put_unaligned_le16(__pack_enhanced_control(control),
982 skb->data + L2CAP_HDR_SIZE);
983 }
984}
985
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300986static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
987{
988 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
989 return L2CAP_EXT_HDR_SIZE;
990 else
991 return L2CAP_ENH_HDR_SIZE;
992}
993
Mat Martineaua67d7f62012-05-17 20:53:35 -0700994static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
995 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300996{
997 struct sk_buff *skb;
998 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300999 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001000
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001001 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03001002 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001003
Mat Martineaua67d7f62012-05-17 20:53:35 -07001004 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001005
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001006 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -07001007 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001008
1009 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001010 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001011 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03001012
Mat Martineaua67d7f62012-05-17 20:53:35 -07001013 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1014 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
1015 else
1016 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001017
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001018 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -07001019 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03001020 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001021 }
1022
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001023 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -07001024 return skb;
1025}
1026
1027static void l2cap_send_sframe(struct l2cap_chan *chan,
1028 struct l2cap_ctrl *control)
1029{
1030 struct sk_buff *skb;
1031 u32 control_field;
1032
1033 BT_DBG("chan %p, control %p", chan, control);
1034
1035 if (!control->sframe)
1036 return;
1037
Mat Martineaub99e13a2012-10-23 15:24:19 -07001038 if (__chan_is_moving(chan))
1039 return;
1040
Mat Martineaua67d7f62012-05-17 20:53:35 -07001041 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
1042 !control->poll)
1043 control->final = 1;
1044
1045 if (control->super == L2CAP_SUPER_RR)
1046 clear_bit(CONN_RNR_SENT, &chan->conn_state);
1047 else if (control->super == L2CAP_SUPER_RNR)
1048 set_bit(CONN_RNR_SENT, &chan->conn_state);
1049
1050 if (control->super != L2CAP_SUPER_SREJ) {
1051 chan->last_acked_seq = control->reqseq;
1052 __clear_ack_timer(chan);
1053 }
1054
1055 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
1056 control->final, control->poll, control->super);
1057
1058 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1059 control_field = __pack_extended_control(control);
1060 else
1061 control_field = __pack_enhanced_control(control);
1062
1063 skb = l2cap_create_sframe_pdu(chan, control_field);
1064 if (!IS_ERR(skb))
1065 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001066}
1067
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001068static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001069{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001070 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001071
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001072 BT_DBG("chan %p, poll %d", chan, poll);
1073
1074 memset(&control, 0, sizeof(control));
1075 control.sframe = 1;
1076 control.poll = poll;
1077
1078 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1079 control.super = L2CAP_SUPER_RNR;
1080 else
1081 control.super = L2CAP_SUPER_RR;
1082
1083 control.reqseq = chan->buffer_seq;
1084 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001085}
1086
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001087static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001088{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001089 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001090}
1091
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001092static bool __amp_capable(struct l2cap_chan *chan)
1093{
1094 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001095 struct hci_dev *hdev;
1096 bool amp_available = false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001097
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001098 if (!conn->hs_enabled)
1099 return false;
1100
1101 if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
1102 return false;
1103
1104 read_lock(&hci_dev_list_lock);
1105 list_for_each_entry(hdev, &hci_dev_list, list) {
1106 if (hdev->amp_type != AMP_TYPE_BREDR &&
1107 test_bit(HCI_UP, &hdev->flags)) {
1108 amp_available = true;
1109 break;
1110 }
1111 }
1112 read_unlock(&hci_dev_list_lock);
1113
1114 if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED)
1115 return amp_available;
Marcel Holtmann848566b2013-10-01 22:59:22 -07001116
1117 return false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001118}
1119
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001120static bool l2cap_check_efs(struct l2cap_chan *chan)
1121{
1122 /* Check EFS parameters */
1123 return true;
1124}
1125
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001126void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001127{
1128 struct l2cap_conn *conn = chan->conn;
1129 struct l2cap_conn_req req;
1130
1131 req.scid = cpu_to_le16(chan->scid);
1132 req.psm = chan->psm;
1133
1134 chan->ident = l2cap_get_ident(conn);
1135
1136 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1137
1138 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1139}
1140
Mat Martineau8eb200b2012-10-23 15:24:17 -07001141static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1142{
1143 struct l2cap_create_chan_req req;
1144 req.scid = cpu_to_le16(chan->scid);
1145 req.psm = chan->psm;
1146 req.amp_id = amp_id;
1147
1148 chan->ident = l2cap_get_ident(chan->conn);
1149
1150 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1151 sizeof(req), &req);
1152}
1153
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001154static void l2cap_move_setup(struct l2cap_chan *chan)
1155{
1156 struct sk_buff *skb;
1157
1158 BT_DBG("chan %p", chan);
1159
1160 if (chan->mode != L2CAP_MODE_ERTM)
1161 return;
1162
1163 __clear_retrans_timer(chan);
1164 __clear_monitor_timer(chan);
1165 __clear_ack_timer(chan);
1166
1167 chan->retry_count = 0;
1168 skb_queue_walk(&chan->tx_q, skb) {
1169 if (bt_cb(skb)->control.retries)
1170 bt_cb(skb)->control.retries = 1;
1171 else
1172 break;
1173 }
1174
1175 chan->expected_tx_seq = chan->buffer_seq;
1176
1177 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1178 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1179 l2cap_seq_list_clear(&chan->retrans_list);
1180 l2cap_seq_list_clear(&chan->srej_list);
1181 skb_queue_purge(&chan->srej_q);
1182
1183 chan->tx_state = L2CAP_TX_STATE_XMIT;
1184 chan->rx_state = L2CAP_RX_STATE_MOVE;
1185
1186 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1187}
1188
Mat Martineau5f3847a2012-10-23 15:24:12 -07001189static void l2cap_move_done(struct l2cap_chan *chan)
1190{
1191 u8 move_role = chan->move_role;
1192 BT_DBG("chan %p", chan);
1193
1194 chan->move_state = L2CAP_MOVE_STABLE;
1195 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1196
1197 if (chan->mode != L2CAP_MODE_ERTM)
1198 return;
1199
1200 switch (move_role) {
1201 case L2CAP_MOVE_ROLE_INITIATOR:
1202 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1203 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1204 break;
1205 case L2CAP_MOVE_ROLE_RESPONDER:
1206 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1207 break;
1208 }
1209}
1210
Johan Hedberg177f8f22013-05-31 17:54:51 +03001211static void l2cap_le_flowctl_start(struct l2cap_chan *chan)
1212{
1213 chan->sdu = NULL;
1214 chan->sdu_last_frag = NULL;
1215 chan->sdu_len = 0;
1216
Johan Hedberg3916aed2013-10-07 15:35:26 +02001217 if (chan->imtu < L2CAP_LE_DEFAULT_MPS)
1218 chan->mps = chan->imtu;
1219 else
Johan Hedbergf15b8ec2013-12-03 15:08:25 +02001220 chan->mps = le_default_mps;
Johan Hedberg3916aed2013-10-07 15:35:26 +02001221
Johan Hedberg177f8f22013-05-31 17:54:51 +03001222 skb_queue_head_init(&chan->tx_q);
Johan Hedberg029727a2013-10-07 14:44:48 +02001223
1224 if (!chan->tx_credits)
1225 chan->ops->suspend(chan);
Johan Hedberg177f8f22013-05-31 17:54:51 +03001226}
1227
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001228static void l2cap_chan_ready(struct l2cap_chan *chan)
1229{
Mat Martineau28270112012-05-17 21:14:09 -07001230 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001231 chan->conf_state = 0;
1232 __clear_chan_timer(chan);
1233
Johan Hedberg177f8f22013-05-31 17:54:51 +03001234 if (chan->mode == L2CAP_MODE_LE_FLOWCTL)
1235 l2cap_le_flowctl_start(chan);
1236
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001237 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001238
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001239 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001240}
1241
Johan Hedbergf1496de2013-05-13 14:15:56 +03001242static void l2cap_le_connect(struct l2cap_chan *chan)
1243{
1244 struct l2cap_conn *conn = chan->conn;
1245 struct l2cap_le_conn_req req;
1246
Johan Hedberg595177f2013-12-02 22:12:22 +02001247 if (test_and_set_bit(FLAG_LE_CONN_REQ_SENT, &chan->flags))
1248 return;
1249
Johan Hedbergf1496de2013-05-13 14:15:56 +03001250 req.psm = chan->psm;
1251 req.scid = cpu_to_le16(chan->scid);
1252 req.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02001253 req.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03001254 req.credits = cpu_to_le16(chan->rx_credits);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001255
1256 chan->ident = l2cap_get_ident(conn);
1257
1258 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_REQ,
1259 sizeof(req), &req);
1260}
1261
1262static void l2cap_le_start(struct l2cap_chan *chan)
1263{
1264 struct l2cap_conn *conn = chan->conn;
1265
1266 if (!smp_conn_security(conn->hcon, chan->sec_level))
1267 return;
1268
1269 if (!chan->psm) {
1270 l2cap_chan_ready(chan);
1271 return;
1272 }
1273
1274 if (chan->state == BT_CONNECT)
1275 l2cap_le_connect(chan);
1276}
1277
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001278static void l2cap_start_connection(struct l2cap_chan *chan)
1279{
1280 if (__amp_capable(chan)) {
1281 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1282 a2mp_discover_amp(chan);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001283 } else if (chan->conn->hcon->type == LE_LINK) {
1284 l2cap_le_start(chan);
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001285 } else {
1286 l2cap_send_conn_req(chan);
1287 }
1288}
1289
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001290static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001291{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001292 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001293
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001294 if (conn->hcon->type == LE_LINK) {
Johan Hedberg96ac34f2013-05-13 11:15:07 +03001295 l2cap_le_start(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001296 return;
1297 }
1298
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001299 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001300 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1301 return;
1302
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001303 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001304 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001305 l2cap_start_connection(chan);
1306 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001307 } else {
1308 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001309 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001310
1311 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1312 conn->info_ident = l2cap_get_ident(conn);
1313
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001314 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001315
Gustavo Padovan2d792812012-10-06 10:07:01 +01001316 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1317 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001318 }
1319}
1320
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001321static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1322{
1323 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001324 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001325 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1326
1327 switch (mode) {
1328 case L2CAP_MODE_ERTM:
1329 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1330 case L2CAP_MODE_STREAMING:
1331 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1332 default:
1333 return 0x00;
1334 }
1335}
1336
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001337static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001338{
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001339 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001340 struct l2cap_disconn_req req;
1341
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001342 if (!conn)
1343 return;
1344
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001345 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001346 __clear_retrans_timer(chan);
1347 __clear_monitor_timer(chan);
1348 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001349 }
1350
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001351 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001352 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001353 return;
1354 }
1355
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001356 req.dcid = cpu_to_le16(chan->dcid);
1357 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001358 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1359 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001360
Gustavo Padovanf8e73012013-10-15 19:24:46 -03001361 l2cap_state_change_and_error(chan, BT_DISCONN, err);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001362}
1363
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001365static void l2cap_conn_start(struct l2cap_conn *conn)
1366{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001367 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001368
1369 BT_DBG("conn %p", conn);
1370
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001371 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001372
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001373 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001374 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001375
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001376 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001377 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001378 continue;
1379 }
1380
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001381 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001382 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001383 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001384 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001385 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001386 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001387
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001388 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001389 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001390 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001391 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001392 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001393 continue;
1394 }
1395
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001396 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001397
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001398 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001399 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001400 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001401 rsp.scid = cpu_to_le16(chan->dcid);
1402 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001403
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001404 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07001405 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001406 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1407 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001408 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001409
1410 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02001411 l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001412 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1413 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001414 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001415 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001416 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1417 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001418 }
1419
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001420 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001421 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001422
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001423 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001424 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001425 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001426 continue;
1427 }
1428
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001429 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001430 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001431 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001432 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001433 }
1434
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001435 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001436 }
1437
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001438 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001439}
1440
Ido Yarivc2287682012-04-20 15:46:07 -03001441/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001442 * Returns closest match, locked.
1443 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001444static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001445 bdaddr_t *src,
1446 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001447{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001448 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001449
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001450 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001451
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001452 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001453 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001454 continue;
1455
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001456 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001457 int src_match, dst_match;
1458 int src_any, dst_any;
1459
Ville Tervob62f3282011-02-10 22:38:50 -03001460 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001461 src_match = !bacmp(&c->src, src);
1462 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001463 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001464 read_unlock(&chan_list_lock);
1465 return c;
1466 }
Ville Tervob62f3282011-02-10 22:38:50 -03001467
1468 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001469 src_any = !bacmp(&c->src, BDADDR_ANY);
1470 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001471 if ((src_match && dst_any) || (src_any && dst_match) ||
1472 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001473 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001474 }
1475 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001476
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001477 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001478
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001479 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001480}
1481
1482static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1483{
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001484 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001485 struct l2cap_chan *chan, *pchan;
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001486 u8 dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001487
1488 BT_DBG("");
1489
1490 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001491 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001492 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001493 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001494 return;
1495
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001496 /* Client ATT sockets should override the server one */
1497 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1498 return;
1499
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001500 dst_type = bdaddr_type(hcon, hcon->dst_type);
1501
1502 /* If device is blocked, do not create a channel for it */
1503 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, dst_type))
1504 return;
1505
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001506 l2cap_chan_lock(pchan);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001507
Gustavo Padovan80b98022012-05-27 22:27:51 -03001508 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001509 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001510 goto clean;
1511
Johan Hedberg9f22398c2013-04-29 19:35:38 +03001512 chan->dcid = L2CAP_CID_ATT;
1513
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001514 bacpy(&chan->src, &hcon->src);
1515 bacpy(&chan->dst, &hcon->dst);
1516 chan->src_type = bdaddr_type(hcon, hcon->src_type);
1517 chan->dst_type = dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001518
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001519 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001520
Ville Tervob62f3282011-02-10 22:38:50 -03001521clean:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001522 l2cap_chan_unlock(pchan);
Ville Tervob62f3282011-02-10 22:38:50 -03001523}
1524
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001525static void l2cap_conn_ready(struct l2cap_conn *conn)
1526{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001527 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001528 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001529
1530 BT_DBG("conn %p", conn);
1531
Johan Hedbergd8729922013-04-29 19:35:39 +03001532 /* For outgoing pairing which doesn't necessarily have an
1533 * associated socket (e.g. mgmt_pair_device).
1534 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001535 if (hcon->out && hcon->type == LE_LINK)
1536 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001537
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001538 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001539
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001540 if (hcon->type == LE_LINK)
1541 l2cap_le_conn_ready(conn);
1542
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001543 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001544
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001545 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001546
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001547 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1548 l2cap_chan_unlock(chan);
1549 continue;
1550 }
1551
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001552 if (hcon->type == LE_LINK) {
Johan Hedbergf1496de2013-05-13 14:15:56 +03001553 l2cap_le_start(chan);
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001554 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo Padovan74e75742013-10-15 19:24:51 -03001555 l2cap_chan_ready(chan);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001556
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001557 } else if (chan->state == BT_CONNECT) {
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001558 l2cap_do_start(chan);
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001559 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001560
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001561 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001562 }
1563
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001564 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001565}
1566
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001567/* Notify sockets that we cannot guaranty reliability anymore */
1568static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1569{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001570 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001571
1572 BT_DBG("conn %p", conn);
1573
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001574 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001575
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001576 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001577 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001578 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001579 }
1580
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001581 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001582}
1583
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001584static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001585{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001586 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001587 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001588
Marcel Holtmann984947d2009-02-06 23:35:19 +01001589 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001590 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001591
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001592 l2cap_conn_start(conn);
1593}
1594
David Herrmann2c8e1412013-04-06 20:28:45 +02001595/*
1596 * l2cap_user
1597 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1598 * callback is called during registration. The ->remove callback is called
1599 * during unregistration.
1600 * An l2cap_user object can either be explicitly unregistered or when the
1601 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1602 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1603 * External modules must own a reference to the l2cap_conn object if they intend
1604 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1605 * any time if they don't.
1606 */
1607
1608int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1609{
1610 struct hci_dev *hdev = conn->hcon->hdev;
1611 int ret;
1612
1613 /* We need to check whether l2cap_conn is registered. If it is not, we
1614 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1615 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1616 * relies on the parent hci_conn object to be locked. This itself relies
1617 * on the hci_dev object to be locked. So we must lock the hci device
1618 * here, too. */
1619
1620 hci_dev_lock(hdev);
1621
1622 if (user->list.next || user->list.prev) {
1623 ret = -EINVAL;
1624 goto out_unlock;
1625 }
1626
1627 /* conn->hchan is NULL after l2cap_conn_del() was called */
1628 if (!conn->hchan) {
1629 ret = -ENODEV;
1630 goto out_unlock;
1631 }
1632
1633 ret = user->probe(conn, user);
1634 if (ret)
1635 goto out_unlock;
1636
1637 list_add(&user->list, &conn->users);
1638 ret = 0;
1639
1640out_unlock:
1641 hci_dev_unlock(hdev);
1642 return ret;
1643}
1644EXPORT_SYMBOL(l2cap_register_user);
1645
1646void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1647{
1648 struct hci_dev *hdev = conn->hcon->hdev;
1649
1650 hci_dev_lock(hdev);
1651
1652 if (!user->list.next || !user->list.prev)
1653 goto out_unlock;
1654
1655 list_del(&user->list);
1656 user->list.next = NULL;
1657 user->list.prev = NULL;
1658 user->remove(conn, user);
1659
1660out_unlock:
1661 hci_dev_unlock(hdev);
1662}
1663EXPORT_SYMBOL(l2cap_unregister_user);
1664
1665static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1666{
1667 struct l2cap_user *user;
1668
1669 while (!list_empty(&conn->users)) {
1670 user = list_first_entry(&conn->users, struct l2cap_user, list);
1671 list_del(&user->list);
1672 user->list.next = NULL;
1673 user->list.prev = NULL;
1674 user->remove(conn, user);
1675 }
1676}
1677
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001678static void l2cap_conn_del(struct hci_conn *hcon, int err)
1679{
1680 struct l2cap_conn *conn = hcon->l2cap_data;
1681 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001682
1683 if (!conn)
1684 return;
1685
1686 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1687
1688 kfree_skb(conn->rx_skb);
1689
David Herrmann2c8e1412013-04-06 20:28:45 +02001690 l2cap_unregister_all_users(conn);
1691
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001692 mutex_lock(&conn->chan_lock);
1693
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001694 /* Kill channels */
1695 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001696 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001697 l2cap_chan_lock(chan);
1698
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001699 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001700
1701 l2cap_chan_unlock(chan);
1702
Gustavo Padovan80b98022012-05-27 22:27:51 -03001703 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001704 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001705 }
1706
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001707 mutex_unlock(&conn->chan_lock);
1708
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001709 hci_chan_del(conn->hchan);
1710
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001711 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001712 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001713
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001714 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001715 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001716 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001717 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001718
1719 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001720 conn->hchan = NULL;
1721 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001722}
1723
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001724static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001725{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001726 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001727 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001728
Johan Hedbergd06cc412012-06-06 18:44:11 +08001729 BT_DBG("conn %p", conn);
1730
1731 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1732 smp_chan_destroy(conn);
1733 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1734 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001735}
1736
Claudio Takahasibaf43252013-04-11 13:55:50 -03001737static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738{
Marcel Holtmann01394182006-07-03 10:02:46 +02001739 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001740 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741
Claudio Takahasibaf43252013-04-11 13:55:50 -03001742 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 return conn;
1744
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001745 hchan = hci_chan_create(hcon);
1746 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001748
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001749 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001750 if (!conn) {
1751 hci_chan_del(hchan);
1752 return NULL;
1753 }
1754
David Herrmann9c903e32013-04-06 20:28:44 +02001755 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 hcon->l2cap_data = conn;
1757 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001758 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001759 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001761 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001762
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001763 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001764 case LE_LINK:
1765 if (hcon->hdev->le_mtu) {
1766 conn->mtu = hcon->hdev->le_mtu;
1767 break;
1768 }
1769 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001770 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001771 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001772 break;
1773 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001774
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001775 conn->feat_mask = 0;
1776
Marcel Holtmann848566b2013-10-01 22:59:22 -07001777 if (hcon->type == ACL_LINK)
1778 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
1779 &hcon->hdev->dev_flags);
1780
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001782 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001783
1784 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001785 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001787 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001788 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001789 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001790 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001791
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001792 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001793
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 return conn;
1795}
1796
David Herrmann9c903e32013-04-06 20:28:44 +02001797static void l2cap_conn_free(struct kref *ref)
1798{
1799 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1800
1801 hci_conn_put(conn->hcon);
1802 kfree(conn);
1803}
1804
1805void l2cap_conn_get(struct l2cap_conn *conn)
1806{
1807 kref_get(&conn->ref);
1808}
1809EXPORT_SYMBOL(l2cap_conn_get);
1810
1811void l2cap_conn_put(struct l2cap_conn *conn)
1812{
1813 kref_put(&conn->ref, l2cap_conn_free);
1814}
1815EXPORT_SYMBOL(l2cap_conn_put);
1816
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818
Ido Yarivc2287682012-04-20 15:46:07 -03001819/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820 * Returns closest match.
1821 */
Ido Yarivc2287682012-04-20 15:46:07 -03001822static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1823 bdaddr_t *src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001824 bdaddr_t *dst,
1825 u8 link_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001827 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001829 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001830
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001831 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001832 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 continue;
1834
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001835 if (link_type == ACL_LINK && c->src_type != BDADDR_BREDR)
1836 continue;
1837
1838 if (link_type == LE_LINK && c->src_type == BDADDR_BREDR)
1839 continue;
1840
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001841 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001842 int src_match, dst_match;
1843 int src_any, dst_any;
1844
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001846 src_match = !bacmp(&c->src, src);
1847 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001848 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001849 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001850 return c;
1851 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852
1853 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001854 src_any = !bacmp(&c->src, BDADDR_ANY);
1855 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001856 if ((src_match && dst_any) || (src_any && dst_match) ||
1857 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001858 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859 }
1860 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001862 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001863
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001864 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865}
1866
Johan Hedberg49460962013-10-08 13:55:46 +02001867static bool is_valid_psm(u16 psm, u8 dst_type)
1868{
1869 if (!psm)
1870 return false;
1871
1872 if (bdaddr_type_is_le(dst_type))
1873 return (psm < 0x00ff);
1874
1875 /* PSM must be odd and lsb of upper byte must be 0 */
1876 return ((psm & 0x0101) == 0x0001);
1877}
1878
Andre Guedes8e9f9892012-04-24 21:02:55 -03001879int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1880 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882 struct l2cap_conn *conn;
1883 struct hci_conn *hcon;
1884 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001885 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001886 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001888 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301889 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001891 hdev = hci_get_route(dst, &chan->src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001892 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893 return -EHOSTUNREACH;
1894
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001895 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001897 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001898
Johan Hedberg49460962013-10-08 13:55:46 +02001899 if (!is_valid_psm(__le16_to_cpu(psm), dst_type) && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001900 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001901 err = -EINVAL;
1902 goto done;
1903 }
1904
1905 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1906 err = -EINVAL;
1907 goto done;
1908 }
1909
1910 switch (chan->mode) {
1911 case L2CAP_MODE_BASIC:
Johan Hedberg38319712013-05-17 12:49:23 +03001912 case L2CAP_MODE_LE_FLOWCTL:
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001913 break;
1914 case L2CAP_MODE_ERTM:
1915 case L2CAP_MODE_STREAMING:
1916 if (!disable_ertm)
1917 break;
1918 /* fall through */
1919 default:
1920 err = -ENOTSUPP;
1921 goto done;
1922 }
1923
Gustavo Padovan0797e012012-05-27 22:27:54 -03001924 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001925 case BT_CONNECT:
1926 case BT_CONNECT2:
1927 case BT_CONFIG:
1928 /* Already connecting */
1929 err = 0;
1930 goto done;
1931
1932 case BT_CONNECTED:
1933 /* Already connected */
1934 err = -EISCONN;
1935 goto done;
1936
1937 case BT_OPEN:
1938 case BT_BOUND:
1939 /* Can connect */
1940 break;
1941
1942 default:
1943 err = -EBADFD;
1944 goto done;
1945 }
1946
1947 /* Set destination address and psm */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001948 bacpy(&chan->dst, dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001949 chan->dst_type = dst_type;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001950
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001951 chan->psm = psm;
1952 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001953
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001954 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001955
Johan Hedbergf224ca52013-04-29 19:35:36 +03001956 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001957 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001958 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001959 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001960 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001961 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001962
Ville Tervo30e76272011-02-22 16:10:53 -03001963 if (IS_ERR(hcon)) {
1964 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001966 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001967
Claudio Takahasibaf43252013-04-11 13:55:50 -03001968 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001970 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001971 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001972 goto done;
1973 }
1974
Johan Hedberg141d5702013-04-29 19:35:37 +03001975 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1976 hci_conn_drop(hcon);
1977 err = -EBUSY;
1978 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001979 }
1980
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981 /* Update source addr of the socket */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001982 bacpy(&chan->src, &hcon->src);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001983 chan->src_type = bdaddr_type(hcon, hcon->src_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001985 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001986 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001987 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001988
Johan Hedberg5ee98912013-04-29 19:35:43 +03001989 /* l2cap_chan_add takes its own ref so we can drop this one */
1990 hci_conn_drop(hcon);
1991
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001992 l2cap_state_change(chan, BT_CONNECT);
Gustavo Padovan8d836d72013-10-15 19:24:47 -03001993 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001994
1995 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001996 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001997 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001998 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001999 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002000 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03002001 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002002 }
2003
Ville Tervo30e76272011-02-22 16:10:53 -03002004 err = 0;
2005
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002007 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03002008 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002009 hci_dev_put(hdev);
2010 return err;
2011}
2012
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002013static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002014{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002015 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07002016 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002017
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03002018 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002019
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002020 l2cap_chan_lock(chan);
2021
Mat Martineau80909e02012-05-17 20:53:50 -07002022 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002023 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02002024 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002025 return;
2026 }
2027
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002028 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002029
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002030 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02002031 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002032}
2033
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002034static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002035{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002036 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07002037 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002038
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03002039 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002040
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002041 l2cap_chan_lock(chan);
2042
Mat Martineau80909e02012-05-17 20:53:50 -07002043 if (!chan->conn) {
2044 l2cap_chan_unlock(chan);
2045 l2cap_chan_put(chan);
2046 return;
2047 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002048
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002049 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002050 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02002051 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002052}
2053
Gustavo Padovand6603662012-05-21 13:58:22 -03002054static void l2cap_streaming_send(struct l2cap_chan *chan,
2055 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002056{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03002057 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07002058 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002059
Mat Martineau37339372012-05-17 20:53:33 -07002060 BT_DBG("chan %p, skbs %p", chan, skbs);
2061
Mat Martineaub99e13a2012-10-23 15:24:19 -07002062 if (__chan_is_moving(chan))
2063 return;
2064
Mat Martineau37339372012-05-17 20:53:33 -07002065 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2066
2067 while (!skb_queue_empty(&chan->tx_q)) {
2068
2069 skb = skb_dequeue(&chan->tx_q);
2070
2071 bt_cb(skb)->control.retries = 1;
2072 control = &bt_cb(skb)->control;
2073
2074 control->reqseq = 0;
2075 control->txseq = chan->next_tx_seq;
2076
2077 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002078
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002079 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07002080 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2081 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002082 }
2083
Gustavo F. Padovan43434782011-04-12 18:31:57 -03002084 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002085
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002086 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07002087
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002088 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07002089 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002090 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002091}
2092
Szymon Janc67c9e842011-07-28 16:24:33 +02002093static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002094{
2095 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07002096 struct l2cap_ctrl *control;
2097 int sent = 0;
2098
2099 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002100
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03002101 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03002102 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002103
Mat Martineau94122bb2012-05-02 09:42:02 -07002104 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2105 return 0;
2106
Mat Martineaub99e13a2012-10-23 15:24:19 -07002107 if (__chan_is_moving(chan))
2108 return 0;
2109
Mat Martineau18a48e72012-05-17 20:53:34 -07002110 while (chan->tx_send_head &&
2111 chan->unacked_frames < chan->remote_tx_win &&
2112 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002113
Mat Martineau18a48e72012-05-17 20:53:34 -07002114 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002115
Mat Martineau18a48e72012-05-17 20:53:34 -07002116 bt_cb(skb)->control.retries = 1;
2117 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03002118
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002119 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07002120 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002121
Mat Martineau18a48e72012-05-17 20:53:34 -07002122 control->reqseq = chan->buffer_seq;
2123 chan->last_acked_seq = chan->buffer_seq;
2124 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002125
Mat Martineau18a48e72012-05-17 20:53:34 -07002126 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002127
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002128 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002129 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2130 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002131 }
2132
Mat Martineau18a48e72012-05-17 20:53:34 -07002133 /* Clone after data has been modified. Data is assumed to be
2134 read-only (for locking purposes) on cloned sk_buffs.
2135 */
2136 tx_skb = skb_clone(skb, GFP_KERNEL);
2137
2138 if (!tx_skb)
2139 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002140
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002141 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002142
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002143 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002144 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002145 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002146 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002147
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002148 if (skb_queue_is_last(&chan->tx_q, skb))
2149 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002150 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002151 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002152
2153 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002154 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002155 }
2156
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002157 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2158 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002159
2160 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002161}
2162
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002163static void l2cap_ertm_resend(struct l2cap_chan *chan)
2164{
2165 struct l2cap_ctrl control;
2166 struct sk_buff *skb;
2167 struct sk_buff *tx_skb;
2168 u16 seq;
2169
2170 BT_DBG("chan %p", chan);
2171
2172 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2173 return;
2174
Mat Martineaub99e13a2012-10-23 15:24:19 -07002175 if (__chan_is_moving(chan))
2176 return;
2177
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002178 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2179 seq = l2cap_seq_list_pop(&chan->retrans_list);
2180
2181 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2182 if (!skb) {
2183 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002184 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002185 continue;
2186 }
2187
2188 bt_cb(skb)->control.retries++;
2189 control = bt_cb(skb)->control;
2190
2191 if (chan->max_tx != 0 &&
2192 bt_cb(skb)->control.retries > chan->max_tx) {
2193 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002194 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002195 l2cap_seq_list_clear(&chan->retrans_list);
2196 break;
2197 }
2198
2199 control.reqseq = chan->buffer_seq;
2200 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2201 control.final = 1;
2202 else
2203 control.final = 0;
2204
2205 if (skb_cloned(skb)) {
2206 /* Cloned sk_buffs are read-only, so we need a
2207 * writeable copy
2208 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002209 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002210 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002211 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002212 }
2213
2214 if (!tx_skb) {
2215 l2cap_seq_list_clear(&chan->retrans_list);
2216 break;
2217 }
2218
2219 /* Update skb contents */
2220 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2221 put_unaligned_le32(__pack_extended_control(&control),
2222 tx_skb->data + L2CAP_HDR_SIZE);
2223 } else {
2224 put_unaligned_le16(__pack_enhanced_control(&control),
2225 tx_skb->data + L2CAP_HDR_SIZE);
2226 }
2227
2228 if (chan->fcs == L2CAP_FCS_CRC16) {
2229 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2230 put_unaligned_le16(fcs, skb_put(tx_skb,
2231 L2CAP_FCS_SIZE));
2232 }
2233
2234 l2cap_do_send(chan, tx_skb);
2235
2236 BT_DBG("Resent txseq %d", control.txseq);
2237
2238 chan->last_acked_seq = chan->buffer_seq;
2239 }
2240}
2241
Mat Martineauf80842a2012-05-17 20:53:46 -07002242static void l2cap_retransmit(struct l2cap_chan *chan,
2243 struct l2cap_ctrl *control)
2244{
2245 BT_DBG("chan %p, control %p", chan, control);
2246
2247 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2248 l2cap_ertm_resend(chan);
2249}
2250
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002251static void l2cap_retransmit_all(struct l2cap_chan *chan,
2252 struct l2cap_ctrl *control)
2253{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002254 struct sk_buff *skb;
2255
2256 BT_DBG("chan %p, control %p", chan, control);
2257
2258 if (control->poll)
2259 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2260
2261 l2cap_seq_list_clear(&chan->retrans_list);
2262
2263 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2264 return;
2265
2266 if (chan->unacked_frames) {
2267 skb_queue_walk(&chan->tx_q, skb) {
2268 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002269 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002270 break;
2271 }
2272
2273 skb_queue_walk_from(&chan->tx_q, skb) {
2274 if (skb == chan->tx_send_head)
2275 break;
2276
2277 l2cap_seq_list_append(&chan->retrans_list,
2278 bt_cb(skb)->control.txseq);
2279 }
2280
2281 l2cap_ertm_resend(chan);
2282 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002283}
2284
Szymon Jancb17e73b2012-01-11 10:59:47 +01002285static void l2cap_send_ack(struct l2cap_chan *chan)
2286{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002287 struct l2cap_ctrl control;
2288 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2289 chan->last_acked_seq);
2290 int threshold;
2291
2292 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2293 chan, chan->last_acked_seq, chan->buffer_seq);
2294
2295 memset(&control, 0, sizeof(control));
2296 control.sframe = 1;
2297
2298 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2299 chan->rx_state == L2CAP_RX_STATE_RECV) {
2300 __clear_ack_timer(chan);
2301 control.super = L2CAP_SUPER_RNR;
2302 control.reqseq = chan->buffer_seq;
2303 l2cap_send_sframe(chan, &control);
2304 } else {
2305 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2306 l2cap_ertm_send(chan);
2307 /* If any i-frames were sent, they included an ack */
2308 if (chan->buffer_seq == chan->last_acked_seq)
2309 frames_to_ack = 0;
2310 }
2311
Mat Martineauc20f8e32012-07-10 05:47:07 -07002312 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002313 * Calculate without mul or div
2314 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002315 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002316 threshold += threshold << 1;
2317 threshold >>= 2;
2318
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002319 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002320 threshold);
2321
2322 if (frames_to_ack >= threshold) {
2323 __clear_ack_timer(chan);
2324 control.super = L2CAP_SUPER_RR;
2325 control.reqseq = chan->buffer_seq;
2326 l2cap_send_sframe(chan, &control);
2327 frames_to_ack = 0;
2328 }
2329
2330 if (frames_to_ack)
2331 __set_ack_timer(chan);
2332 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002333}
2334
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002335static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2336 struct msghdr *msg, int len,
2337 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002338{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002339 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002340 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002341 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002342
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002343 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002344 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002345
2346 sent += count;
2347 len -= count;
2348
2349 /* Continuation fragments (no L2CAP header) */
2350 frag = &skb_shinfo(skb)->frag_list;
2351 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002352 struct sk_buff *tmp;
2353
Linus Torvalds1da177e2005-04-16 15:20:36 -07002354 count = min_t(unsigned int, conn->mtu, len);
2355
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002356 tmp = chan->ops->alloc_skb(chan, count,
2357 msg->msg_flags & MSG_DONTWAIT);
2358 if (IS_ERR(tmp))
2359 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002360
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002361 *frag = tmp;
2362
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002363 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2364 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002365
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002366 (*frag)->priority = skb->priority;
2367
Linus Torvalds1da177e2005-04-16 15:20:36 -07002368 sent += count;
2369 len -= count;
2370
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002371 skb->len += (*frag)->len;
2372 skb->data_len += (*frag)->len;
2373
Linus Torvalds1da177e2005-04-16 15:20:36 -07002374 frag = &(*frag)->next;
2375 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002376
2377 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002378}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002379
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002380static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002381 struct msghdr *msg, size_t len,
2382 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002383{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002384 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002385 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002386 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002387 struct l2cap_hdr *lh;
2388
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002389 BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
2390 __le16_to_cpu(chan->psm), len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002391
2392 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002393
2394 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002395 msg->msg_flags & MSG_DONTWAIT);
2396 if (IS_ERR(skb))
2397 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002398
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002399 skb->priority = priority;
2400
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002401 /* Create L2CAP header */
2402 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002403 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002404 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002405 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002406
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002407 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002408 if (unlikely(err < 0)) {
2409 kfree_skb(skb);
2410 return ERR_PTR(err);
2411 }
2412 return skb;
2413}
2414
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002415static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002416 struct msghdr *msg, size_t len,
2417 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002418{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002419 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002420 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002421 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002422 struct l2cap_hdr *lh;
2423
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002424 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002425
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002426 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002427
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002428 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002429 msg->msg_flags & MSG_DONTWAIT);
2430 if (IS_ERR(skb))
2431 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002432
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002433 skb->priority = priority;
2434
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002435 /* Create L2CAP header */
2436 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002437 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002438 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002439
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002440 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002441 if (unlikely(err < 0)) {
2442 kfree_skb(skb);
2443 return ERR_PTR(err);
2444 }
2445 return skb;
2446}
2447
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002448static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002449 struct msghdr *msg, size_t len,
2450 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002451{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002452 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002453 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002454 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002455 struct l2cap_hdr *lh;
2456
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002457 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002458
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002459 if (!conn)
2460 return ERR_PTR(-ENOTCONN);
2461
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002462 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002463
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002464 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002465 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002466
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002467 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002468 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002469
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002470 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002471
2472 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002473 msg->msg_flags & MSG_DONTWAIT);
2474 if (IS_ERR(skb))
2475 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002476
2477 /* Create L2CAP header */
2478 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002479 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002480 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002481
Mat Martineau18a48e72012-05-17 20:53:34 -07002482 /* Control header is populated later */
2483 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2484 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2485 else
2486 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002487
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002488 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002489 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002490
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002491 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002492 if (unlikely(err < 0)) {
2493 kfree_skb(skb);
2494 return ERR_PTR(err);
2495 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002496
Mat Martineau18a48e72012-05-17 20:53:34 -07002497 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002498 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002499 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002500}
2501
Mat Martineau94122bb2012-05-02 09:42:02 -07002502static int l2cap_segment_sdu(struct l2cap_chan *chan,
2503 struct sk_buff_head *seg_queue,
2504 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002505{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002506 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002507 u16 sdu_len;
2508 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002509 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002510
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002511 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002512
Mat Martineau94122bb2012-05-02 09:42:02 -07002513 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2514 * so fragmented skbs are not used. The HCI layer's handling
2515 * of fragmented skbs is not compatible with ERTM's queueing.
2516 */
2517
2518 /* PDU size is derived from the HCI MTU */
2519 pdu_len = chan->conn->mtu;
2520
Mat Martineaua5495742012-10-23 15:24:21 -07002521 /* Constrain PDU size for BR/EDR connections */
2522 if (!chan->hs_hcon)
2523 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002524
2525 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002526 if (chan->fcs)
2527 pdu_len -= L2CAP_FCS_SIZE;
2528
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002529 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002530
2531 /* Remote device may have requested smaller PDUs */
2532 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2533
2534 if (len <= pdu_len) {
2535 sar = L2CAP_SAR_UNSEGMENTED;
2536 sdu_len = 0;
2537 pdu_len = len;
2538 } else {
2539 sar = L2CAP_SAR_START;
2540 sdu_len = len;
2541 pdu_len -= L2CAP_SDULEN_SIZE;
2542 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002543
2544 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002545 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002546
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002547 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002548 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002549 return PTR_ERR(skb);
2550 }
2551
Mat Martineau94122bb2012-05-02 09:42:02 -07002552 bt_cb(skb)->control.sar = sar;
2553 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002554
Mat Martineau94122bb2012-05-02 09:42:02 -07002555 len -= pdu_len;
2556 if (sdu_len) {
2557 sdu_len = 0;
2558 pdu_len += L2CAP_SDULEN_SIZE;
2559 }
2560
2561 if (len <= pdu_len) {
2562 sar = L2CAP_SAR_END;
2563 pdu_len = len;
2564 } else {
2565 sar = L2CAP_SAR_CONTINUE;
2566 }
2567 }
2568
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002569 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002570}
2571
Johan Hedberg177f8f22013-05-31 17:54:51 +03002572static struct sk_buff *l2cap_create_le_flowctl_pdu(struct l2cap_chan *chan,
2573 struct msghdr *msg,
2574 size_t len, u16 sdulen)
2575{
2576 struct l2cap_conn *conn = chan->conn;
2577 struct sk_buff *skb;
2578 int err, count, hlen;
2579 struct l2cap_hdr *lh;
2580
2581 BT_DBG("chan %p len %zu", chan, len);
2582
2583 if (!conn)
2584 return ERR_PTR(-ENOTCONN);
2585
2586 hlen = L2CAP_HDR_SIZE;
2587
2588 if (sdulen)
2589 hlen += L2CAP_SDULEN_SIZE;
2590
2591 count = min_t(unsigned int, (conn->mtu - hlen), len);
2592
2593 skb = chan->ops->alloc_skb(chan, count + hlen,
2594 msg->msg_flags & MSG_DONTWAIT);
2595 if (IS_ERR(skb))
2596 return skb;
2597
2598 /* Create L2CAP header */
2599 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
2600 lh->cid = cpu_to_le16(chan->dcid);
2601 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
2602
2603 if (sdulen)
2604 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
2605
2606 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
2607 if (unlikely(err < 0)) {
2608 kfree_skb(skb);
2609 return ERR_PTR(err);
2610 }
2611
2612 return skb;
2613}
2614
2615static int l2cap_segment_le_sdu(struct l2cap_chan *chan,
2616 struct sk_buff_head *seg_queue,
2617 struct msghdr *msg, size_t len)
2618{
2619 struct sk_buff *skb;
2620 size_t pdu_len;
2621 u16 sdu_len;
2622
2623 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
2624
2625 pdu_len = chan->conn->mtu - L2CAP_HDR_SIZE;
2626
2627 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2628
2629 sdu_len = len;
2630 pdu_len -= L2CAP_SDULEN_SIZE;
2631
2632 while (len > 0) {
2633 if (len <= pdu_len)
2634 pdu_len = len;
2635
2636 skb = l2cap_create_le_flowctl_pdu(chan, msg, pdu_len, sdu_len);
2637 if (IS_ERR(skb)) {
2638 __skb_queue_purge(seg_queue);
2639 return PTR_ERR(skb);
2640 }
2641
2642 __skb_queue_tail(seg_queue, skb);
2643
2644 len -= pdu_len;
2645
2646 if (sdu_len) {
2647 sdu_len = 0;
2648 pdu_len += L2CAP_SDULEN_SIZE;
2649 }
2650 }
2651
2652 return 0;
2653}
2654
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002655int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002656 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002657{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002658 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002659 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002660 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002661
Seung-Woo Kim31e8ce82013-11-05 18:46:33 +09002662 if (!chan->conn)
2663 return -ENOTCONN;
2664
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002665 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002666 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002667 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002668 if (IS_ERR(skb))
2669 return PTR_ERR(skb);
2670
2671 l2cap_do_send(chan, skb);
2672 return len;
2673 }
2674
2675 switch (chan->mode) {
Johan Hedberg38319712013-05-17 12:49:23 +03002676 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedberg177f8f22013-05-31 17:54:51 +03002677 /* Check outgoing MTU */
2678 if (len > chan->omtu)
2679 return -EMSGSIZE;
2680
Johan Hedbergfad5fc892013-12-05 09:45:01 +02002681 if (!chan->tx_credits)
2682 return -EAGAIN;
2683
Johan Hedberg177f8f22013-05-31 17:54:51 +03002684 __skb_queue_head_init(&seg_queue);
2685
2686 err = l2cap_segment_le_sdu(chan, &seg_queue, msg, len);
2687
2688 if (chan->state != BT_CONNECTED) {
2689 __skb_queue_purge(&seg_queue);
2690 err = -ENOTCONN;
2691 }
2692
2693 if (err)
2694 return err;
2695
2696 skb_queue_splice_tail_init(&seg_queue, &chan->tx_q);
2697
2698 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
2699 l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
2700 chan->tx_credits--;
2701 }
2702
2703 if (!chan->tx_credits)
2704 chan->ops->suspend(chan);
2705
2706 err = len;
2707
2708 break;
2709
Johan Hedbergfad5fc892013-12-05 09:45:01 +02002710 case L2CAP_MODE_BASIC:
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002711 /* Check outgoing MTU */
2712 if (len > chan->omtu)
2713 return -EMSGSIZE;
2714
2715 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002716 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002717 if (IS_ERR(skb))
2718 return PTR_ERR(skb);
2719
2720 l2cap_do_send(chan, skb);
2721 err = len;
2722 break;
2723
2724 case L2CAP_MODE_ERTM:
2725 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002726 /* Check outgoing MTU */
2727 if (len > chan->omtu) {
2728 err = -EMSGSIZE;
2729 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002730 }
2731
Mat Martineau94122bb2012-05-02 09:42:02 -07002732 __skb_queue_head_init(&seg_queue);
2733
2734 /* Do segmentation before calling in to the state machine,
2735 * since it's possible to block while waiting for memory
2736 * allocation.
2737 */
2738 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2739
2740 /* The channel could have been closed while segmenting,
2741 * check that it is still connected.
2742 */
2743 if (chan->state != BT_CONNECTED) {
2744 __skb_queue_purge(&seg_queue);
2745 err = -ENOTCONN;
2746 }
2747
2748 if (err)
2749 break;
2750
Mat Martineau37339372012-05-17 20:53:33 -07002751 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002752 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002753 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002754 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002755
Gustavo Padovand6603662012-05-21 13:58:22 -03002756 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002757
Mat Martineau94122bb2012-05-02 09:42:02 -07002758 /* If the skbs were not queued for sending, they'll still be in
2759 * seg_queue and need to be purged.
2760 */
2761 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002762 break;
2763
2764 default:
2765 BT_DBG("bad state %1.1x", chan->mode);
2766 err = -EBADFD;
2767 }
2768
2769 return err;
2770}
2771
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002772static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2773{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002774 struct l2cap_ctrl control;
2775 u16 seq;
2776
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002777 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002778
2779 memset(&control, 0, sizeof(control));
2780 control.sframe = 1;
2781 control.super = L2CAP_SUPER_SREJ;
2782
2783 for (seq = chan->expected_tx_seq; seq != txseq;
2784 seq = __next_seq(chan, seq)) {
2785 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2786 control.reqseq = seq;
2787 l2cap_send_sframe(chan, &control);
2788 l2cap_seq_list_append(&chan->srej_list, seq);
2789 }
2790 }
2791
2792 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002793}
2794
2795static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2796{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002797 struct l2cap_ctrl control;
2798
2799 BT_DBG("chan %p", chan);
2800
2801 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2802 return;
2803
2804 memset(&control, 0, sizeof(control));
2805 control.sframe = 1;
2806 control.super = L2CAP_SUPER_SREJ;
2807 control.reqseq = chan->srej_list.tail;
2808 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002809}
2810
2811static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2812{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002813 struct l2cap_ctrl control;
2814 u16 initial_head;
2815 u16 seq;
2816
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002817 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002818
2819 memset(&control, 0, sizeof(control));
2820 control.sframe = 1;
2821 control.super = L2CAP_SUPER_SREJ;
2822
2823 /* Capture initial list head to allow only one pass through the list. */
2824 initial_head = chan->srej_list.head;
2825
2826 do {
2827 seq = l2cap_seq_list_pop(&chan->srej_list);
2828 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2829 break;
2830
2831 control.reqseq = seq;
2832 l2cap_send_sframe(chan, &control);
2833 l2cap_seq_list_append(&chan->srej_list, seq);
2834 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002835}
2836
Mat Martineau608bcc62012-05-17 20:53:32 -07002837static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2838{
2839 struct sk_buff *acked_skb;
2840 u16 ackseq;
2841
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002842 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002843
2844 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2845 return;
2846
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002847 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002848 chan->expected_ack_seq, chan->unacked_frames);
2849
2850 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2851 ackseq = __next_seq(chan, ackseq)) {
2852
2853 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2854 if (acked_skb) {
2855 skb_unlink(acked_skb, &chan->tx_q);
2856 kfree_skb(acked_skb);
2857 chan->unacked_frames--;
2858 }
2859 }
2860
2861 chan->expected_ack_seq = reqseq;
2862
2863 if (chan->unacked_frames == 0)
2864 __clear_retrans_timer(chan);
2865
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002866 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002867}
2868
2869static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2870{
2871 BT_DBG("chan %p", chan);
2872
2873 chan->expected_tx_seq = chan->buffer_seq;
2874 l2cap_seq_list_clear(&chan->srej_list);
2875 skb_queue_purge(&chan->srej_q);
2876 chan->rx_state = L2CAP_RX_STATE_RECV;
2877}
2878
Gustavo Padovand6603662012-05-21 13:58:22 -03002879static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2880 struct l2cap_ctrl *control,
2881 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002882{
Mat Martineau608bcc62012-05-17 20:53:32 -07002883 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2884 event);
2885
2886 switch (event) {
2887 case L2CAP_EV_DATA_REQUEST:
2888 if (chan->tx_send_head == NULL)
2889 chan->tx_send_head = skb_peek(skbs);
2890
2891 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2892 l2cap_ertm_send(chan);
2893 break;
2894 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2895 BT_DBG("Enter LOCAL_BUSY");
2896 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2897
2898 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2899 /* The SREJ_SENT state must be aborted if we are to
2900 * enter the LOCAL_BUSY state.
2901 */
2902 l2cap_abort_rx_srej_sent(chan);
2903 }
2904
2905 l2cap_send_ack(chan);
2906
2907 break;
2908 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2909 BT_DBG("Exit LOCAL_BUSY");
2910 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2911
2912 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2913 struct l2cap_ctrl local_control;
2914
2915 memset(&local_control, 0, sizeof(local_control));
2916 local_control.sframe = 1;
2917 local_control.super = L2CAP_SUPER_RR;
2918 local_control.poll = 1;
2919 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002920 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002921
2922 chan->retry_count = 1;
2923 __set_monitor_timer(chan);
2924 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2925 }
2926 break;
2927 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2928 l2cap_process_reqseq(chan, control->reqseq);
2929 break;
2930 case L2CAP_EV_EXPLICIT_POLL:
2931 l2cap_send_rr_or_rnr(chan, 1);
2932 chan->retry_count = 1;
2933 __set_monitor_timer(chan);
2934 __clear_ack_timer(chan);
2935 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2936 break;
2937 case L2CAP_EV_RETRANS_TO:
2938 l2cap_send_rr_or_rnr(chan, 1);
2939 chan->retry_count = 1;
2940 __set_monitor_timer(chan);
2941 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2942 break;
2943 case L2CAP_EV_RECV_FBIT:
2944 /* Nothing to process */
2945 break;
2946 default:
2947 break;
2948 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002949}
2950
Gustavo Padovand6603662012-05-21 13:58:22 -03002951static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2952 struct l2cap_ctrl *control,
2953 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002954{
Mat Martineau608bcc62012-05-17 20:53:32 -07002955 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2956 event);
2957
2958 switch (event) {
2959 case L2CAP_EV_DATA_REQUEST:
2960 if (chan->tx_send_head == NULL)
2961 chan->tx_send_head = skb_peek(skbs);
2962 /* Queue data, but don't send. */
2963 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2964 break;
2965 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2966 BT_DBG("Enter LOCAL_BUSY");
2967 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2968
2969 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2970 /* The SREJ_SENT state must be aborted if we are to
2971 * enter the LOCAL_BUSY state.
2972 */
2973 l2cap_abort_rx_srej_sent(chan);
2974 }
2975
2976 l2cap_send_ack(chan);
2977
2978 break;
2979 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2980 BT_DBG("Exit LOCAL_BUSY");
2981 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2982
2983 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2984 struct l2cap_ctrl local_control;
2985 memset(&local_control, 0, sizeof(local_control));
2986 local_control.sframe = 1;
2987 local_control.super = L2CAP_SUPER_RR;
2988 local_control.poll = 1;
2989 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002990 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002991
2992 chan->retry_count = 1;
2993 __set_monitor_timer(chan);
2994 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2995 }
2996 break;
2997 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2998 l2cap_process_reqseq(chan, control->reqseq);
2999
3000 /* Fall through */
3001
3002 case L2CAP_EV_RECV_FBIT:
3003 if (control && control->final) {
3004 __clear_monitor_timer(chan);
3005 if (chan->unacked_frames > 0)
3006 __set_retrans_timer(chan);
3007 chan->retry_count = 0;
3008 chan->tx_state = L2CAP_TX_STATE_XMIT;
3009 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
3010 }
3011 break;
3012 case L2CAP_EV_EXPLICIT_POLL:
3013 /* Ignore */
3014 break;
3015 case L2CAP_EV_MONITOR_TO:
3016 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
3017 l2cap_send_rr_or_rnr(chan, 1);
3018 __set_monitor_timer(chan);
3019 chan->retry_count++;
3020 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02003021 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07003022 }
3023 break;
3024 default:
3025 break;
3026 }
Mat Martineau608bcc62012-05-17 20:53:32 -07003027}
3028
Gustavo Padovand6603662012-05-21 13:58:22 -03003029static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
3030 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07003031{
Mat Martineau608bcc62012-05-17 20:53:32 -07003032 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
3033 chan, control, skbs, event, chan->tx_state);
3034
3035 switch (chan->tx_state) {
3036 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03003037 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07003038 break;
3039 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03003040 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07003041 break;
3042 default:
3043 /* Ignore event */
3044 break;
3045 }
Mat Martineau608bcc62012-05-17 20:53:32 -07003046}
3047
Mat Martineau4b51dae92012-05-17 20:53:37 -07003048static void l2cap_pass_to_tx(struct l2cap_chan *chan,
3049 struct l2cap_ctrl *control)
3050{
3051 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03003052 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07003053}
3054
Mat Martineauf80842a2012-05-17 20:53:46 -07003055static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
3056 struct l2cap_ctrl *control)
3057{
3058 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03003059 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07003060}
3061
Linus Torvalds1da177e2005-04-16 15:20:36 -07003062/* Copy frame to all raw sockets on that connection */
3063static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
3064{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003065 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003066 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003067
3068 BT_DBG("conn %p", conn);
3069
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003070 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02003071
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003072 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03003073 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003074 continue;
3075
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02003076 /* Don't send frame to the channel it came from */
3077 if (bt_cb(skb)->chan == chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003078 continue;
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02003079
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03003080 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003081 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003082 continue;
Gustavo Padovan80b98022012-05-27 22:27:51 -03003083 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003084 kfree_skb(nskb);
3085 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02003086
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003087 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003088}
3089
3090/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003091static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
3092 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003093{
3094 struct sk_buff *skb, **frag;
3095 struct l2cap_cmd_hdr *cmd;
3096 struct l2cap_hdr *lh;
3097 int len, count;
3098
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003099 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
3100 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003101
Anderson Lizardo300b9622013-06-02 16:30:40 -04003102 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
3103 return NULL;
3104
Linus Torvalds1da177e2005-04-16 15:20:36 -07003105 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
3106 count = min_t(unsigned int, conn->mtu, len);
3107
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03003108 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003109 if (!skb)
3110 return NULL;
3111
3112 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003113 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02003114
3115 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003116 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02003117 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003118 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003119
3120 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
3121 cmd->code = code;
3122 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003123 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003124
3125 if (dlen) {
3126 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
3127 memcpy(skb_put(skb, count), data, count);
3128 data += count;
3129 }
3130
3131 len -= skb->len;
3132
3133 /* Continuation fragments (no L2CAP header) */
3134 frag = &skb_shinfo(skb)->frag_list;
3135 while (len) {
3136 count = min_t(unsigned int, conn->mtu, len);
3137
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03003138 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003139 if (!*frag)
3140 goto fail;
3141
3142 memcpy(skb_put(*frag, count), data, count);
3143
3144 len -= count;
3145 data += count;
3146
3147 frag = &(*frag)->next;
3148 }
3149
3150 return skb;
3151
3152fail:
3153 kfree_skb(skb);
3154 return NULL;
3155}
3156
Gustavo Padovan2d792812012-10-06 10:07:01 +01003157static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
3158 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003159{
3160 struct l2cap_conf_opt *opt = *ptr;
3161 int len;
3162
3163 len = L2CAP_CONF_OPT_SIZE + opt->len;
3164 *ptr += len;
3165
3166 *type = opt->type;
3167 *olen = opt->len;
3168
3169 switch (opt->len) {
3170 case 1:
3171 *val = *((u8 *) opt->val);
3172 break;
3173
3174 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04003175 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003176 break;
3177
3178 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04003179 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003180 break;
3181
3182 default:
3183 *val = (unsigned long) opt->val;
3184 break;
3185 }
3186
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003187 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003188 return len;
3189}
3190
Linus Torvalds1da177e2005-04-16 15:20:36 -07003191static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
3192{
3193 struct l2cap_conf_opt *opt = *ptr;
3194
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003195 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003196
3197 opt->type = type;
3198 opt->len = len;
3199
3200 switch (len) {
3201 case 1:
3202 *((u8 *) opt->val) = val;
3203 break;
3204
3205 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003206 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003207 break;
3208
3209 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003210 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003211 break;
3212
3213 default:
3214 memcpy(opt->val, (void *) val, len);
3215 break;
3216 }
3217
3218 *ptr += L2CAP_CONF_OPT_SIZE + len;
3219}
3220
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003221static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
3222{
3223 struct l2cap_conf_efs efs;
3224
Szymon Janc1ec918c2011-11-16 09:32:21 +01003225 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003226 case L2CAP_MODE_ERTM:
3227 efs.id = chan->local_id;
3228 efs.stype = chan->local_stype;
3229 efs.msdu = cpu_to_le16(chan->local_msdu);
3230 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003231 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003232 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003233 break;
3234
3235 case L2CAP_MODE_STREAMING:
3236 efs.id = 1;
3237 efs.stype = L2CAP_SERV_BESTEFFORT;
3238 efs.msdu = cpu_to_le16(chan->local_msdu);
3239 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
3240 efs.acc_lat = 0;
3241 efs.flush_to = 0;
3242 break;
3243
3244 default:
3245 return;
3246 }
3247
3248 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003249 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003250}
3251
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003252static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003253{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003254 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003255 ack_timer.work);
3256 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003257
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003258 BT_DBG("chan %p", chan);
3259
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003260 l2cap_chan_lock(chan);
3261
Mat Martineau03625202012-05-17 20:53:51 -07003262 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3263 chan->last_acked_seq);
3264
3265 if (frames_to_ack)
3266 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003267
3268 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003269 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003270}
3271
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003272int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003273{
Mat Martineau3c588192012-04-11 10:48:42 -07003274 int err;
3275
Mat Martineau105bdf92012-04-27 16:50:48 -07003276 chan->next_tx_seq = 0;
3277 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003278 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003279 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003280 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003281 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003282 chan->last_acked_seq = 0;
3283 chan->sdu = NULL;
3284 chan->sdu_last_frag = NULL;
3285 chan->sdu_len = 0;
3286
Mat Martineaud34c34f2012-05-14 14:49:27 -07003287 skb_queue_head_init(&chan->tx_q);
3288
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003289 chan->local_amp_id = AMP_ID_BREDR;
3290 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003291 chan->move_state = L2CAP_MOVE_STABLE;
3292 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3293
Mat Martineau105bdf92012-04-27 16:50:48 -07003294 if (chan->mode != L2CAP_MODE_ERTM)
3295 return 0;
3296
3297 chan->rx_state = L2CAP_RX_STATE_RECV;
3298 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003299
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003300 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3301 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3302 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003303
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003304 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003305
Mat Martineau3c588192012-04-11 10:48:42 -07003306 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3307 if (err < 0)
3308 return err;
3309
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003310 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3311 if (err < 0)
3312 l2cap_seq_list_free(&chan->srej_list);
3313
3314 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003315}
3316
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003317static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3318{
3319 switch (mode) {
3320 case L2CAP_MODE_STREAMING:
3321 case L2CAP_MODE_ERTM:
3322 if (l2cap_mode_supported(mode, remote_feat_mask))
3323 return mode;
3324 /* fall through */
3325 default:
3326 return L2CAP_MODE_BASIC;
3327 }
3328}
3329
Marcel Holtmann848566b2013-10-01 22:59:22 -07003330static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003331{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003332 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003333}
3334
Marcel Holtmann848566b2013-10-01 22:59:22 -07003335static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003336{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003337 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003338}
3339
Mat Martineau36c86c82012-10-23 15:24:20 -07003340static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3341 struct l2cap_conf_rfc *rfc)
3342{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003343 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003344 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3345
3346 /* Class 1 devices have must have ERTM timeouts
3347 * exceeding the Link Supervision Timeout. The
3348 * default Link Supervision Timeout for AMP
3349 * controllers is 10 seconds.
3350 *
3351 * Class 1 devices use 0xffffffff for their
3352 * best-effort flush timeout, so the clamping logic
3353 * will result in a timeout that meets the above
3354 * requirement. ERTM timeouts are 16-bit values, so
3355 * the maximum timeout is 65.535 seconds.
3356 */
3357
3358 /* Convert timeout to milliseconds and round */
3359 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3360
3361 /* This is the recommended formula for class 2 devices
3362 * that start ERTM timers when packets are sent to the
3363 * controller.
3364 */
3365 ertm_to = 3 * ertm_to + 500;
3366
3367 if (ertm_to > 0xffff)
3368 ertm_to = 0xffff;
3369
3370 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3371 rfc->monitor_timeout = rfc->retrans_timeout;
3372 } else {
3373 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3374 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3375 }
3376}
3377
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003378static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3379{
3380 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003381 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003382 /* use extended control field */
3383 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003384 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3385 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003386 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003387 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003388 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3389 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003390 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003391}
3392
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003393static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003394{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003395 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003396 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003397 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003398 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003399
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003400 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003401
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003402 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003403 goto done;
3404
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003405 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003406 case L2CAP_MODE_STREAMING:
3407 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003408 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003409 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003410
Marcel Holtmann848566b2013-10-01 22:59:22 -07003411 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003412 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3413
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003414 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003415 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003416 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003417 break;
3418 }
3419
3420done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003421 if (chan->imtu != L2CAP_DEFAULT_MTU)
3422 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003423
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003424 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003425 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003426 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003427 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003428 break;
3429
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003430 rfc.mode = L2CAP_MODE_BASIC;
3431 rfc.txwin_size = 0;
3432 rfc.max_transmit = 0;
3433 rfc.retrans_timeout = 0;
3434 rfc.monitor_timeout = 0;
3435 rfc.max_pdu_size = 0;
3436
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003437 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003438 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003439 break;
3440
3441 case L2CAP_MODE_ERTM:
3442 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003443 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003444
3445 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003446
3447 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003448 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3449 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003450 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003451
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003452 l2cap_txwin_setup(chan);
3453
3454 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003455 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003456
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003457 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003458 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003459
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003460 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3461 l2cap_add_opt_efs(&ptr, chan);
3462
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003463 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3464 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003465 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003466
3467 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3468 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003469 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003470 chan->fcs = L2CAP_FCS_NONE;
3471 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3472 chan->fcs);
3473 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003474 break;
3475
3476 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003477 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003478 rfc.mode = L2CAP_MODE_STREAMING;
3479 rfc.txwin_size = 0;
3480 rfc.max_transmit = 0;
3481 rfc.retrans_timeout = 0;
3482 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003483
3484 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003485 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3486 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003487 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003488
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003489 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003490 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003491
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003492 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3493 l2cap_add_opt_efs(&ptr, chan);
3494
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003495 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3496 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003497 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003498 chan->fcs = L2CAP_FCS_NONE;
3499 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3500 chan->fcs);
3501 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003502 break;
3503 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003504
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003505 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003506 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003507
3508 return ptr - data;
3509}
3510
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003511static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003512{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003513 struct l2cap_conf_rsp *rsp = data;
3514 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003515 void *req = chan->conf_req;
3516 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003517 int type, hint, olen;
3518 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003519 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003520 struct l2cap_conf_efs efs;
3521 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003522 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003523 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003524 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003525
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003526 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003527
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003528 while (len >= L2CAP_CONF_OPT_SIZE) {
3529 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003530
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003531 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003532 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003533
3534 switch (type) {
3535 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003536 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003537 break;
3538
3539 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003540 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003541 break;
3542
3543 case L2CAP_CONF_QOS:
3544 break;
3545
Marcel Holtmann6464f352007-10-20 13:39:51 +02003546 case L2CAP_CONF_RFC:
3547 if (olen == sizeof(rfc))
3548 memcpy(&rfc, (void *) val, olen);
3549 break;
3550
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003551 case L2CAP_CONF_FCS:
3552 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003553 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003554 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003555
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003556 case L2CAP_CONF_EFS:
3557 remote_efs = 1;
3558 if (olen == sizeof(efs))
3559 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003560 break;
3561
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003562 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003563 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003564 return -ECONNREFUSED;
3565
3566 set_bit(FLAG_EXT_CTRL, &chan->flags);
3567 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003568 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003569 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003570 break;
3571
3572 default:
3573 if (hint)
3574 break;
3575
3576 result = L2CAP_CONF_UNKNOWN;
3577 *((u8 *) ptr++) = type;
3578 break;
3579 }
3580 }
3581
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003582 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003583 goto done;
3584
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003585 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003586 case L2CAP_MODE_STREAMING:
3587 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003588 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003589 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003590 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003591 break;
3592 }
3593
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003594 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003595 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003596 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3597 else
3598 return -ECONNREFUSED;
3599 }
3600
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003601 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003602 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003603
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003604 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003605 }
3606
3607done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003608 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003609 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003610 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003611
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003612 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003613 return -ECONNREFUSED;
3614
Gustavo Padovan2d792812012-10-06 10:07:01 +01003615 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3616 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003617 }
3618
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003619 if (result == L2CAP_CONF_SUCCESS) {
3620 /* Configure output options and let the other side know
3621 * which ones we don't like. */
3622
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003623 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3624 result = L2CAP_CONF_UNACCEPT;
3625 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003626 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003627 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003628 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003629 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003630
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003631 if (remote_efs) {
3632 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003633 efs.stype != L2CAP_SERV_NOTRAFIC &&
3634 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003635
3636 result = L2CAP_CONF_UNACCEPT;
3637
3638 if (chan->num_conf_req >= 1)
3639 return -ECONNREFUSED;
3640
3641 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003642 sizeof(efs),
3643 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003644 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003645 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003646 result = L2CAP_CONF_PENDING;
3647 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003648 }
3649 }
3650
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003651 switch (rfc.mode) {
3652 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003653 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003654 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003655 break;
3656
3657 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003658 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3659 chan->remote_tx_win = rfc.txwin_size;
3660 else
3661 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3662
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003663 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003664
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003665 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003666 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3667 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003668 rfc.max_pdu_size = cpu_to_le16(size);
3669 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003670
Mat Martineau36c86c82012-10-23 15:24:20 -07003671 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003672
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003673 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003674
3675 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003676 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003677
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003678 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3679 chan->remote_id = efs.id;
3680 chan->remote_stype = efs.stype;
3681 chan->remote_msdu = le16_to_cpu(efs.msdu);
3682 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003683 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003684 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003685 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003686 chan->remote_sdu_itime =
3687 le32_to_cpu(efs.sdu_itime);
3688 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003689 sizeof(efs),
3690 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003691 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003692 break;
3693
3694 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003695 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003696 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3697 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003698 rfc.max_pdu_size = cpu_to_le16(size);
3699 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003700
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003701 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003702
Gustavo Padovan2d792812012-10-06 10:07:01 +01003703 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3704 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003705
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003706 break;
3707
3708 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003709 result = L2CAP_CONF_UNACCEPT;
3710
3711 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003712 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003713 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003714
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003715 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003716 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003717 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003718 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003719 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003720 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003721
3722 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003723}
3724
Gustavo Padovan2d792812012-10-06 10:07:01 +01003725static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3726 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003727{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003728 struct l2cap_conf_req *req = data;
3729 void *ptr = req->data;
3730 int type, olen;
3731 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003732 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003733 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003734
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003735 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003736
3737 while (len >= L2CAP_CONF_OPT_SIZE) {
3738 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3739
3740 switch (type) {
3741 case L2CAP_CONF_MTU:
3742 if (val < L2CAP_DEFAULT_MIN_MTU) {
3743 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003744 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003745 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003746 chan->imtu = val;
3747 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003748 break;
3749
3750 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003751 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003752 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003753 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003754 break;
3755
3756 case L2CAP_CONF_RFC:
3757 if (olen == sizeof(rfc))
3758 memcpy(&rfc, (void *)val, olen);
3759
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003760 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003761 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003762 return -ECONNREFUSED;
3763
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003764 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003765
3766 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003767 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003768 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003769
3770 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003771 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003772 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003773 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003774 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003775
3776 case L2CAP_CONF_EFS:
3777 if (olen == sizeof(efs))
3778 memcpy(&efs, (void *)val, olen);
3779
3780 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003781 efs.stype != L2CAP_SERV_NOTRAFIC &&
3782 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003783 return -ECONNREFUSED;
3784
Gustavo Padovan2d792812012-10-06 10:07:01 +01003785 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3786 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003787 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003788
3789 case L2CAP_CONF_FCS:
3790 if (*result == L2CAP_CONF_PENDING)
3791 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003792 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003793 &chan->conf_state);
3794 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003795 }
3796 }
3797
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003798 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003799 return -ECONNREFUSED;
3800
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003801 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003802
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003803 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003804 switch (rfc.mode) {
3805 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003806 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3807 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3808 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003809 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3810 chan->ack_win = min_t(u16, chan->ack_win,
3811 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003812
3813 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3814 chan->local_msdu = le16_to_cpu(efs.msdu);
3815 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003816 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003817 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3818 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003819 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003820 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003821 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003822
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003823 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003824 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003825 }
3826 }
3827
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003828 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003829 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003830
3831 return ptr - data;
3832}
3833
Gustavo Padovan2d792812012-10-06 10:07:01 +01003834static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3835 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003836{
3837 struct l2cap_conf_rsp *rsp = data;
3838 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003839
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003840 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003841
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003842 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003843 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003844 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003845
3846 return ptr - data;
3847}
3848
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003849void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan)
3850{
3851 struct l2cap_le_conn_rsp rsp;
3852 struct l2cap_conn *conn = chan->conn;
3853
3854 BT_DBG("chan %p", chan);
3855
3856 rsp.dcid = cpu_to_le16(chan->scid);
3857 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02003858 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03003859 rsp.credits = cpu_to_le16(chan->rx_credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003860 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3861
3862 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
3863 &rsp);
3864}
3865
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003866void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003867{
3868 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003869 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003870 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003871 u8 rsp_code;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003872
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003873 rsp.scid = cpu_to_le16(chan->dcid);
3874 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003875 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3876 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003877
3878 if (chan->hs_hcon)
3879 rsp_code = L2CAP_CREATE_CHAN_RSP;
3880 else
3881 rsp_code = L2CAP_CONN_RSP;
3882
3883 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3884
3885 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003886
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003887 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003888 return;
3889
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003890 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003891 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003892 chan->num_conf_req++;
3893}
3894
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003895static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003896{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003897 int type, olen;
3898 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003899 /* Use sane default values in case a misbehaving remote device
3900 * did not send an RFC or extended window size option.
3901 */
3902 u16 txwin_ext = chan->ack_win;
3903 struct l2cap_conf_rfc rfc = {
3904 .mode = chan->mode,
3905 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3906 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3907 .max_pdu_size = cpu_to_le16(chan->imtu),
3908 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3909 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003910
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003911 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003912
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003913 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003914 return;
3915
3916 while (len >= L2CAP_CONF_OPT_SIZE) {
3917 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3918
Mat Martineauc20f8e32012-07-10 05:47:07 -07003919 switch (type) {
3920 case L2CAP_CONF_RFC:
3921 if (olen == sizeof(rfc))
3922 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003923 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003924 case L2CAP_CONF_EWS:
3925 txwin_ext = val;
3926 break;
3927 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003928 }
3929
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003930 switch (rfc.mode) {
3931 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003932 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3933 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003934 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3935 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3936 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3937 else
3938 chan->ack_win = min_t(u16, chan->ack_win,
3939 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003940 break;
3941 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003942 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003943 }
3944}
3945
Gustavo Padovan2d792812012-10-06 10:07:01 +01003946static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003947 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3948 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003949{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003950 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003951
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003952 if (cmd_len < sizeof(*rej))
3953 return -EPROTO;
3954
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003955 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003956 return 0;
3957
3958 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003959 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003960 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003961
3962 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003963 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003964
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003965 l2cap_conn_start(conn);
3966 }
3967
3968 return 0;
3969}
3970
Mat Martineau17009152012-10-23 15:24:07 -07003971static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3972 struct l2cap_cmd_hdr *cmd,
3973 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003974{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003975 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3976 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003977 struct l2cap_chan *chan = NULL, *pchan;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003978 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003979
3980 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003981 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003982
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003983 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003984
3985 /* Check if we have socket listening on psm */
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003986 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03003987 &conn->hcon->dst, ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003988 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003989 result = L2CAP_CR_BAD_PSM;
3990 goto sendresp;
3991 }
3992
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003993 mutex_lock(&conn->chan_lock);
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003994 l2cap_chan_lock(pchan);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003995
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003996 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003997 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003998 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003999 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004000 result = L2CAP_CR_SEC_BLOCK;
4001 goto response;
4002 }
4003
Linus Torvalds1da177e2005-04-16 15:20:36 -07004004 result = L2CAP_CR_NO_MEM;
4005
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03004006 /* Check if we already have channel with that dcid */
4007 if (__l2cap_get_chan_by_dcid(conn, scid))
4008 goto response;
4009
Gustavo Padovan80b98022012-05-27 22:27:51 -03004010 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03004011 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004012 goto response;
4013
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09004014 /* For certain devices (ex: HID mouse), support for authentication,
4015 * pairing and bonding is optional. For such devices, inorder to avoid
4016 * the ACL alive for too long after L2CAP disconnection, reset the ACL
4017 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
4018 */
4019 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
4020
Marcel Holtmann7eafc592013-10-13 08:12:47 -07004021 bacpy(&chan->src, &conn->hcon->src);
4022 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07004023 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
4024 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004025 chan->psm = psm;
4026 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07004027 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004028
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004029 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004030
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004031 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004032
Gustavo Padovan8d836d72013-10-15 19:24:47 -03004033 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004034
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03004035 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004036
Marcel Holtmann984947d2009-02-06 23:35:19 +01004037 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02004038 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07004039 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004040 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004041 result = L2CAP_CR_PEND;
4042 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08004043 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004044 } else {
Mat Martineau17009152012-10-23 15:24:07 -07004045 /* Force pending result for AMP controllers.
4046 * The connection will succeed after the
4047 * physical link is up.
4048 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004049 if (amp_id == AMP_ID_BREDR) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004050 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau17009152012-10-23 15:24:07 -07004051 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004052 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004053 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004054 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07004055 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004056 status = L2CAP_CS_NO_INFO;
4057 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004058 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004059 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004060 result = L2CAP_CR_PEND;
4061 status = L2CAP_CS_AUTHEN_PEND;
4062 }
4063 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004064 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004065 result = L2CAP_CR_PEND;
4066 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004067 }
4068
Linus Torvalds1da177e2005-04-16 15:20:36 -07004069response:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02004070 l2cap_chan_unlock(pchan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004071 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004072
4073sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07004074 rsp.scid = cpu_to_le16(scid);
4075 rsp.dcid = cpu_to_le16(dcid);
4076 rsp.result = cpu_to_le16(result);
4077 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004078 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004079
4080 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
4081 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004082 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004083
4084 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
4085 conn->info_ident = l2cap_get_ident(conn);
4086
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004087 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004088
Gustavo Padovan2d792812012-10-06 10:07:01 +01004089 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
4090 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004091 }
4092
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004093 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01004094 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004095 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004096 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004097 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004098 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004099 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004100 }
Mat Martineau17009152012-10-23 15:24:07 -07004101
4102 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004103}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004104
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004105static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004106 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004107{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05304108 struct hci_dev *hdev = conn->hcon->hdev;
4109 struct hci_conn *hcon = conn->hcon;
4110
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004111 if (cmd_len < sizeof(struct l2cap_conn_req))
4112 return -EPROTO;
4113
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05304114 hci_dev_lock(hdev);
4115 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
4116 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
4117 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
4118 hcon->dst_type, 0, NULL, 0,
4119 hcon->dev_class);
4120 hci_dev_unlock(hdev);
4121
Gustavo Padovan300229f2012-10-12 19:40:40 +08004122 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004123 return 0;
4124}
4125
Mat Martineau5909cf32012-10-23 15:24:08 -07004126static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004127 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4128 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004129{
4130 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
4131 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004132 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004133 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004134 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004135
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004136 if (cmd_len < sizeof(*rsp))
4137 return -EPROTO;
4138
Linus Torvalds1da177e2005-04-16 15:20:36 -07004139 scid = __le16_to_cpu(rsp->scid);
4140 dcid = __le16_to_cpu(rsp->dcid);
4141 result = __le16_to_cpu(rsp->result);
4142 status = __le16_to_cpu(rsp->status);
4143
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02004144 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 +01004145 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004146
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004147 mutex_lock(&conn->chan_lock);
4148
Linus Torvalds1da177e2005-04-16 15:20:36 -07004149 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004150 chan = __l2cap_get_chan_by_scid(conn, scid);
4151 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03004152 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004153 goto unlock;
4154 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004155 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004156 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
4157 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03004158 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004159 goto unlock;
4160 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004161 }
4162
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004163 err = 0;
4164
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004165 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004166
Linus Torvalds1da177e2005-04-16 15:20:36 -07004167 switch (result) {
4168 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03004169 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03004170 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004171 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004172 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004173
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004174 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004175 break;
4176
Linus Torvalds1da177e2005-04-16 15:20:36 -07004177 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004178 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004179 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004180 break;
4181
4182 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004183 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004184 break;
4185
4186 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004187 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004188 break;
4189 }
4190
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004191 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004192
4193unlock:
4194 mutex_unlock(&conn->chan_lock);
4195
4196 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004197}
4198
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004199static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07004200{
4201 /* FCS is enabled only in ERTM or streaming mode, if one or both
4202 * sides request it.
4203 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03004204 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004205 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02004206 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004207 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07004208}
4209
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004210static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
4211 u8 ident, u16 flags)
4212{
4213 struct l2cap_conn *conn = chan->conn;
4214
4215 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
4216 flags);
4217
4218 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
4219 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
4220
4221 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
4222 l2cap_build_conf_rsp(chan, data,
4223 L2CAP_CONF_SUCCESS, flags), data);
4224}
4225
Johan Hedberg662d6522013-10-16 11:20:47 +03004226static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident,
4227 u16 scid, u16 dcid)
4228{
4229 struct l2cap_cmd_rej_cid rej;
4230
4231 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
4232 rej.scid = __cpu_to_le16(scid);
4233 rej.dcid = __cpu_to_le16(dcid);
4234
4235 l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4236}
4237
Gustavo Padovan2d792812012-10-06 10:07:01 +01004238static inline int l2cap_config_req(struct l2cap_conn *conn,
4239 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4240 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004241{
4242 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
4243 u16 dcid, flags;
4244 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004245 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07004246 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004247
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004248 if (cmd_len < sizeof(*req))
4249 return -EPROTO;
4250
Linus Torvalds1da177e2005-04-16 15:20:36 -07004251 dcid = __le16_to_cpu(req->dcid);
4252 flags = __le16_to_cpu(req->flags);
4253
4254 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
4255
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004256 chan = l2cap_get_chan_by_scid(conn, dcid);
Johan Hedberg662d6522013-10-16 11:20:47 +03004257 if (!chan) {
4258 cmd_reject_invalid_cid(conn, cmd->ident, dcid, 0);
4259 return 0;
4260 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004261
David S. Miller033b1142011-07-21 13:38:42 -07004262 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Johan Hedberg662d6522013-10-16 11:20:47 +03004263 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4264 chan->dcid);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004265 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004266 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004267
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004268 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004269 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004270 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004271 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004272 l2cap_build_conf_rsp(chan, rsp,
4273 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004274 goto unlock;
4275 }
4276
4277 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004278 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4279 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004280
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004281 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004282 /* Incomplete config. Send empty response. */
4283 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004284 l2cap_build_conf_rsp(chan, rsp,
4285 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004286 goto unlock;
4287 }
4288
4289 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004290 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004291 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004292 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004293 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004294 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004295
Mat Martineau1500109b2012-10-23 15:24:15 -07004296 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004297 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004298 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004299
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004300 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004301 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004302
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004303 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004304 goto unlock;
4305
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004306 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004307 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004308
Mat Martineau105bdf92012-04-27 16:50:48 -07004309 if (chan->mode == L2CAP_MODE_ERTM ||
4310 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004311 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004312
Mat Martineau3c588192012-04-11 10:48:42 -07004313 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004314 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004315 else
4316 l2cap_chan_ready(chan);
4317
Marcel Holtmann876d9482007-10-20 13:35:42 +02004318 goto unlock;
4319 }
4320
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004321 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004322 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004323 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004324 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004325 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004326 }
4327
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004328 /* Got Conf Rsp PENDING from remote side and asume we sent
4329 Conf Rsp PENDING in the code above */
4330 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004331 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004332
4333 /* check compatibility */
4334
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004335 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004336 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004337 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4338 else
4339 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004340 }
4341
Linus Torvalds1da177e2005-04-16 15:20:36 -07004342unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004343 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004344 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004345}
4346
Gustavo Padovan2d792812012-10-06 10:07:01 +01004347static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004348 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4349 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004350{
4351 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4352 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004353 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004354 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004355 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004356
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004357 if (cmd_len < sizeof(*rsp))
4358 return -EPROTO;
4359
Linus Torvalds1da177e2005-04-16 15:20:36 -07004360 scid = __le16_to_cpu(rsp->scid);
4361 flags = __le16_to_cpu(rsp->flags);
4362 result = __le16_to_cpu(rsp->result);
4363
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004364 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4365 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004366
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004367 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004368 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004369 return 0;
4370
4371 switch (result) {
4372 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004373 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004374 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004375 break;
4376
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004377 case L2CAP_CONF_PENDING:
4378 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4379
4380 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4381 char buf[64];
4382
4383 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004384 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004385 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004386 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004387 goto done;
4388 }
4389
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004390 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004391 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4392 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004393 } else {
4394 if (l2cap_check_efs(chan)) {
4395 amp_create_logical_link(chan);
4396 chan->ident = cmd->ident;
4397 }
4398 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004399 }
4400 goto done;
4401
Linus Torvalds1da177e2005-04-16 15:20:36 -07004402 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004403 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004404 char req[64];
4405
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004406 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004407 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004408 goto done;
4409 }
4410
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004411 /* throw out any old stored conf requests */
4412 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004413 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004414 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004415 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004416 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004417 goto done;
4418 }
4419
4420 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004421 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004422 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004423 if (result != L2CAP_CONF_SUCCESS)
4424 goto done;
4425 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004426 }
4427
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004428 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004429 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004430
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004431 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004432 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004433 goto done;
4434 }
4435
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004436 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004437 goto done;
4438
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004439 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004440
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004441 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004442 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004443
Mat Martineau105bdf92012-04-27 16:50:48 -07004444 if (chan->mode == L2CAP_MODE_ERTM ||
4445 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004446 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004447
Mat Martineau3c588192012-04-11 10:48:42 -07004448 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004449 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004450 else
4451 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004452 }
4453
4454done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004455 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004456 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004457}
4458
Gustavo Padovan2d792812012-10-06 10:07:01 +01004459static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004460 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4461 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004462{
4463 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4464 struct l2cap_disconn_rsp rsp;
4465 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004466 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004467
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004468 if (cmd_len != sizeof(*req))
4469 return -EPROTO;
4470
Linus Torvalds1da177e2005-04-16 15:20:36 -07004471 scid = __le16_to_cpu(req->scid);
4472 dcid = __le16_to_cpu(req->dcid);
4473
4474 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4475
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004476 mutex_lock(&conn->chan_lock);
4477
4478 chan = __l2cap_get_chan_by_scid(conn, dcid);
4479 if (!chan) {
4480 mutex_unlock(&conn->chan_lock);
Johan Hedberg662d6522013-10-16 11:20:47 +03004481 cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid);
4482 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004483 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004484
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004485 l2cap_chan_lock(chan);
4486
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004487 rsp.dcid = cpu_to_le16(chan->scid);
4488 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004489 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4490
Gustavo Padovan5ec1bbe2013-10-15 19:24:48 -03004491 chan->ops->set_shutdown(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004492
Mat Martineau61d6ef32012-04-27 16:50:50 -07004493 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004494 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004495
4496 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004497
Gustavo Padovan80b98022012-05-27 22:27:51 -03004498 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004499 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004500
4501 mutex_unlock(&conn->chan_lock);
4502
Linus Torvalds1da177e2005-04-16 15:20:36 -07004503 return 0;
4504}
4505
Gustavo Padovan2d792812012-10-06 10:07:01 +01004506static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004507 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4508 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004509{
4510 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4511 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004512 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004513
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004514 if (cmd_len != sizeof(*rsp))
4515 return -EPROTO;
4516
Linus Torvalds1da177e2005-04-16 15:20:36 -07004517 scid = __le16_to_cpu(rsp->scid);
4518 dcid = __le16_to_cpu(rsp->dcid);
4519
4520 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4521
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004522 mutex_lock(&conn->chan_lock);
4523
4524 chan = __l2cap_get_chan_by_scid(conn, scid);
4525 if (!chan) {
4526 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004527 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004528 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004529
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004530 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004531
Mat Martineau61d6ef32012-04-27 16:50:50 -07004532 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004533 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004534
4535 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004536
Gustavo Padovan80b98022012-05-27 22:27:51 -03004537 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004538 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004539
4540 mutex_unlock(&conn->chan_lock);
4541
Linus Torvalds1da177e2005-04-16 15:20:36 -07004542 return 0;
4543}
4544
Gustavo Padovan2d792812012-10-06 10:07:01 +01004545static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004546 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4547 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004548{
4549 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004550 u16 type;
4551
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004552 if (cmd_len != sizeof(*req))
4553 return -EPROTO;
4554
Linus Torvalds1da177e2005-04-16 15:20:36 -07004555 type = __le16_to_cpu(req->type);
4556
4557 BT_DBG("type 0x%4.4x", type);
4558
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004559 if (type == L2CAP_IT_FEAT_MASK) {
4560 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004561 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004562 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004563 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4564 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004565 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004566 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004567 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004568 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004569 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004570 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004571
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004572 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004573 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4574 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004575 } else if (type == L2CAP_IT_FIXED_CHAN) {
4576 u8 buf[12];
4577 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004578
Marcel Holtmann848566b2013-10-01 22:59:22 -07004579 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004580 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4581 else
4582 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4583
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004584 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4585 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004586 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004587 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4588 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004589 } else {
4590 struct l2cap_info_rsp rsp;
4591 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004592 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004593 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4594 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004595 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004596
4597 return 0;
4598}
4599
Gustavo Padovan2d792812012-10-06 10:07:01 +01004600static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004601 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4602 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004603{
4604 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4605 u16 type, result;
4606
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304607 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004608 return -EPROTO;
4609
Linus Torvalds1da177e2005-04-16 15:20:36 -07004610 type = __le16_to_cpu(rsp->type);
4611 result = __le16_to_cpu(rsp->result);
4612
4613 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4614
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004615 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4616 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004617 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004618 return 0;
4619
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004620 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004621
Ville Tervoadb08ed2010-08-04 09:43:33 +03004622 if (result != L2CAP_IR_SUCCESS) {
4623 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4624 conn->info_ident = 0;
4625
4626 l2cap_conn_start(conn);
4627
4628 return 0;
4629 }
4630
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004631 switch (type) {
4632 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004633 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004634
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004635 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004636 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004637 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004638
4639 conn->info_ident = l2cap_get_ident(conn);
4640
4641 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004642 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004643 } else {
4644 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4645 conn->info_ident = 0;
4646
4647 l2cap_conn_start(conn);
4648 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004649 break;
4650
4651 case L2CAP_IT_FIXED_CHAN:
4652 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004653 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004654 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004655
4656 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004657 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004658 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004659
Linus Torvalds1da177e2005-04-16 15:20:36 -07004660 return 0;
4661}
4662
Mat Martineau17009152012-10-23 15:24:07 -07004663static int l2cap_create_channel_req(struct l2cap_conn *conn,
4664 struct l2cap_cmd_hdr *cmd,
4665 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004666{
4667 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004668 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004669 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004670 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004671 u16 psm, scid;
4672
4673 if (cmd_len != sizeof(*req))
4674 return -EPROTO;
4675
Marcel Holtmann848566b2013-10-01 22:59:22 -07004676 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004677 return -EINVAL;
4678
4679 psm = le16_to_cpu(req->psm);
4680 scid = le16_to_cpu(req->scid);
4681
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004682 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 -07004683
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004684 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004685 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004686 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4687 req->amp_id);
4688 return 0;
4689 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004690
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004691 /* Validate AMP controller id */
4692 hdev = hci_dev_get(req->amp_id);
4693 if (!hdev)
4694 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004695
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004696 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004697 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004698 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004699 }
4700
4701 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4702 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004703 if (chan) {
4704 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4705 struct hci_conn *hs_hcon;
4706
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004707 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4708 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004709 if (!hs_hcon) {
4710 hci_dev_put(hdev);
Johan Hedberg662d6522013-10-16 11:20:47 +03004711 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4712 chan->dcid);
4713 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004714 }
4715
4716 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4717
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004718 mgr->bredr_chan = chan;
4719 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004720 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004721 conn->mtu = hdev->block_mtu;
4722 }
4723
4724 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004725
4726 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004727
4728error:
4729 rsp.dcid = 0;
4730 rsp.scid = cpu_to_le16(scid);
4731 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4732 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4733
4734 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4735 sizeof(rsp), &rsp);
4736
Johan Hedbergdc280802013-09-16 13:05:13 +03004737 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004738}
4739
Mat Martineau8eb200b2012-10-23 15:24:17 -07004740static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4741{
4742 struct l2cap_move_chan_req req;
4743 u8 ident;
4744
4745 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4746
4747 ident = l2cap_get_ident(chan->conn);
4748 chan->ident = ident;
4749
4750 req.icid = cpu_to_le16(chan->scid);
4751 req.dest_amp_id = dest_amp_id;
4752
4753 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4754 &req);
4755
4756 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4757}
4758
Mat Martineau1500109b2012-10-23 15:24:15 -07004759static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004760{
4761 struct l2cap_move_chan_rsp rsp;
4762
Mat Martineau1500109b2012-10-23 15:24:15 -07004763 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004764
Mat Martineau1500109b2012-10-23 15:24:15 -07004765 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004766 rsp.result = cpu_to_le16(result);
4767
Mat Martineau1500109b2012-10-23 15:24:15 -07004768 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4769 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004770}
4771
Mat Martineau5b155ef2012-10-23 15:24:14 -07004772static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004773{
4774 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004775
Mat Martineau5b155ef2012-10-23 15:24:14 -07004776 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004777
Mat Martineau5b155ef2012-10-23 15:24:14 -07004778 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004779
Mat Martineau5b155ef2012-10-23 15:24:14 -07004780 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004781 cfm.result = cpu_to_le16(result);
4782
Mat Martineau5b155ef2012-10-23 15:24:14 -07004783 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4784 sizeof(cfm), &cfm);
4785
4786 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4787}
4788
4789static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4790{
4791 struct l2cap_move_chan_cfm cfm;
4792
4793 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4794
4795 cfm.icid = cpu_to_le16(icid);
4796 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4797
4798 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4799 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004800}
4801
4802static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004803 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004804{
4805 struct l2cap_move_chan_cfm_rsp rsp;
4806
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004807 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004808
4809 rsp.icid = cpu_to_le16(icid);
4810 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4811}
4812
Mat Martineau5f3847a2012-10-23 15:24:12 -07004813static void __release_logical_link(struct l2cap_chan *chan)
4814{
4815 chan->hs_hchan = NULL;
4816 chan->hs_hcon = NULL;
4817
4818 /* Placeholder - release the logical link */
4819}
4820
Mat Martineau1500109b2012-10-23 15:24:15 -07004821static void l2cap_logical_fail(struct l2cap_chan *chan)
4822{
4823 /* Logical link setup failed */
4824 if (chan->state != BT_CONNECTED) {
4825 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004826 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004827 return;
4828 }
4829
4830 switch (chan->move_role) {
4831 case L2CAP_MOVE_ROLE_RESPONDER:
4832 l2cap_move_done(chan);
4833 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4834 break;
4835 case L2CAP_MOVE_ROLE_INITIATOR:
4836 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4837 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4838 /* Remote has only sent pending or
4839 * success responses, clean up
4840 */
4841 l2cap_move_done(chan);
4842 }
4843
4844 /* Other amp move states imply that the move
4845 * has already aborted
4846 */
4847 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4848 break;
4849 }
4850}
4851
4852static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4853 struct hci_chan *hchan)
4854{
4855 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004856
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004857 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004858 chan->hs_hcon->l2cap_data = chan->conn;
4859
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004860 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004861
4862 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004863 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004864
4865 set_default_fcs(chan);
4866
4867 err = l2cap_ertm_init(chan);
4868 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004869 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004870 else
4871 l2cap_chan_ready(chan);
4872 }
4873}
4874
4875static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4876 struct hci_chan *hchan)
4877{
4878 chan->hs_hcon = hchan->conn;
4879 chan->hs_hcon->l2cap_data = chan->conn;
4880
4881 BT_DBG("move_state %d", chan->move_state);
4882
4883 switch (chan->move_state) {
4884 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4885 /* Move confirm will be sent after a success
4886 * response is received
4887 */
4888 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4889 break;
4890 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4891 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4892 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4893 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4894 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4895 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4896 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4897 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4898 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4899 }
4900 break;
4901 default:
4902 /* Move was not in expected state, free the channel */
4903 __release_logical_link(chan);
4904
4905 chan->move_state = L2CAP_MOVE_STABLE;
4906 }
4907}
4908
4909/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004910void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4911 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004912{
Mat Martineau1500109b2012-10-23 15:24:15 -07004913 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4914
4915 if (status) {
4916 l2cap_logical_fail(chan);
4917 __release_logical_link(chan);
4918 return;
4919 }
4920
4921 if (chan->state != BT_CONNECTED) {
4922 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004923 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004924 l2cap_logical_finish_create(chan, hchan);
4925 } else {
4926 l2cap_logical_finish_move(chan, hchan);
4927 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004928}
4929
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004930void l2cap_move_start(struct l2cap_chan *chan)
4931{
4932 BT_DBG("chan %p", chan);
4933
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004934 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004935 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4936 return;
4937 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4938 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4939 /* Placeholder - start physical link setup */
4940 } else {
4941 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4942 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4943 chan->move_id = 0;
4944 l2cap_move_setup(chan);
4945 l2cap_send_move_chan_req(chan, 0);
4946 }
4947}
4948
Mat Martineau8eb200b2012-10-23 15:24:17 -07004949static void l2cap_do_create(struct l2cap_chan *chan, int result,
4950 u8 local_amp_id, u8 remote_amp_id)
4951{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004952 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4953 local_amp_id, remote_amp_id);
4954
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004955 chan->fcs = L2CAP_FCS_NONE;
4956
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004957 /* Outgoing channel on AMP */
4958 if (chan->state == BT_CONNECT) {
4959 if (result == L2CAP_CR_SUCCESS) {
4960 chan->local_amp_id = local_amp_id;
4961 l2cap_send_create_chan_req(chan, remote_amp_id);
4962 } else {
4963 /* Revert to BR/EDR connect */
4964 l2cap_send_conn_req(chan);
4965 }
4966
4967 return;
4968 }
4969
4970 /* Incoming channel on AMP */
4971 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004972 struct l2cap_conn_rsp rsp;
4973 char buf[128];
4974 rsp.scid = cpu_to_le16(chan->dcid);
4975 rsp.dcid = cpu_to_le16(chan->scid);
4976
Mat Martineau8eb200b2012-10-23 15:24:17 -07004977 if (result == L2CAP_CR_SUCCESS) {
4978 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004979 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4980 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004981 } else {
4982 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004983 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4984 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004985 }
4986
4987 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4988 sizeof(rsp), &rsp);
4989
4990 if (result == L2CAP_CR_SUCCESS) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004991 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004992 set_bit(CONF_REQ_SENT, &chan->conf_state);
4993 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4994 L2CAP_CONF_REQ,
4995 l2cap_build_conf_req(chan, buf), buf);
4996 chan->num_conf_req++;
4997 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004998 }
4999}
5000
5001static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
5002 u8 remote_amp_id)
5003{
5004 l2cap_move_setup(chan);
5005 chan->move_id = local_amp_id;
5006 chan->move_state = L2CAP_MOVE_WAIT_RSP;
5007
5008 l2cap_send_move_chan_req(chan, remote_amp_id);
5009}
5010
5011static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
5012{
5013 struct hci_chan *hchan = NULL;
5014
5015 /* Placeholder - get hci_chan for logical link */
5016
5017 if (hchan) {
5018 if (hchan->state == BT_CONNECTED) {
5019 /* Logical link is ready to go */
5020 chan->hs_hcon = hchan->conn;
5021 chan->hs_hcon->l2cap_data = chan->conn;
5022 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
5023 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
5024
5025 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5026 } else {
5027 /* Wait for logical link to be ready */
5028 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5029 }
5030 } else {
5031 /* Logical link not available */
5032 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
5033 }
5034}
5035
5036static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
5037{
5038 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
5039 u8 rsp_result;
5040 if (result == -EINVAL)
5041 rsp_result = L2CAP_MR_BAD_ID;
5042 else
5043 rsp_result = L2CAP_MR_NOT_ALLOWED;
5044
5045 l2cap_send_move_chan_rsp(chan, rsp_result);
5046 }
5047
5048 chan->move_role = L2CAP_MOVE_ROLE_NONE;
5049 chan->move_state = L2CAP_MOVE_STABLE;
5050
5051 /* Restart data transmission */
5052 l2cap_ertm_send(chan);
5053}
5054
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02005055/* Invoke with locked chan */
5056void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07005057{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02005058 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02005059 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02005060
Mat Martineau8eb200b2012-10-23 15:24:17 -07005061 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
5062 chan, result, local_amp_id, remote_amp_id);
5063
Mat Martineau8eb200b2012-10-23 15:24:17 -07005064 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
5065 l2cap_chan_unlock(chan);
5066 return;
5067 }
5068
5069 if (chan->state != BT_CONNECTED) {
5070 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
5071 } else if (result != L2CAP_MR_SUCCESS) {
5072 l2cap_do_move_cancel(chan, result);
5073 } else {
5074 switch (chan->move_role) {
5075 case L2CAP_MOVE_ROLE_INITIATOR:
5076 l2cap_do_move_initiate(chan, local_amp_id,
5077 remote_amp_id);
5078 break;
5079 case L2CAP_MOVE_ROLE_RESPONDER:
5080 l2cap_do_move_respond(chan, result);
5081 break;
5082 default:
5083 l2cap_do_move_cancel(chan, result);
5084 break;
5085 }
5086 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07005087}
5088
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005089static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005090 struct l2cap_cmd_hdr *cmd,
5091 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005092{
5093 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07005094 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005095 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005096 u16 icid = 0;
5097 u16 result = L2CAP_MR_NOT_ALLOWED;
5098
5099 if (cmd_len != sizeof(*req))
5100 return -EPROTO;
5101
5102 icid = le16_to_cpu(req->icid);
5103
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005104 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005105
Marcel Holtmann848566b2013-10-01 22:59:22 -07005106 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005107 return -EINVAL;
5108
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005109 chan = l2cap_get_chan_by_dcid(conn, icid);
5110 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07005111 rsp.icid = cpu_to_le16(icid);
5112 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
5113 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
5114 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005115 return 0;
5116 }
5117
Mat Martineau1500109b2012-10-23 15:24:15 -07005118 chan->ident = cmd->ident;
5119
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005120 if (chan->scid < L2CAP_CID_DYN_START ||
5121 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
5122 (chan->mode != L2CAP_MODE_ERTM &&
5123 chan->mode != L2CAP_MODE_STREAMING)) {
5124 result = L2CAP_MR_NOT_ALLOWED;
5125 goto send_move_response;
5126 }
5127
5128 if (chan->local_amp_id == req->dest_amp_id) {
5129 result = L2CAP_MR_SAME_ID;
5130 goto send_move_response;
5131 }
5132
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005133 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005134 struct hci_dev *hdev;
5135 hdev = hci_dev_get(req->dest_amp_id);
5136 if (!hdev || hdev->dev_type != HCI_AMP ||
5137 !test_bit(HCI_UP, &hdev->flags)) {
5138 if (hdev)
5139 hci_dev_put(hdev);
5140
5141 result = L2CAP_MR_BAD_ID;
5142 goto send_move_response;
5143 }
5144 hci_dev_put(hdev);
5145 }
5146
5147 /* Detect a move collision. Only send a collision response
5148 * if this side has "lost", otherwise proceed with the move.
5149 * The winner has the larger bd_addr.
5150 */
5151 if ((__chan_is_moving(chan) ||
5152 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07005153 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005154 result = L2CAP_MR_COLLISION;
5155 goto send_move_response;
5156 }
5157
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005158 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5159 l2cap_move_setup(chan);
5160 chan->move_id = req->dest_amp_id;
5161 icid = chan->dcid;
5162
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005163 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005164 /* Moving to BR/EDR */
5165 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5166 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
5167 result = L2CAP_MR_PEND;
5168 } else {
5169 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
5170 result = L2CAP_MR_SUCCESS;
5171 }
5172 } else {
5173 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
5174 /* Placeholder - uncomment when amp functions are available */
5175 /*amp_accept_physical(chan, req->dest_amp_id);*/
5176 result = L2CAP_MR_PEND;
5177 }
5178
5179send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07005180 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005181
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005182 l2cap_chan_unlock(chan);
5183
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005184 return 0;
5185}
5186
Mat Martineau5b155ef2012-10-23 15:24:14 -07005187static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
5188{
5189 struct l2cap_chan *chan;
5190 struct hci_chan *hchan = NULL;
5191
5192 chan = l2cap_get_chan_by_scid(conn, icid);
5193 if (!chan) {
5194 l2cap_send_move_chan_cfm_icid(conn, icid);
5195 return;
5196 }
5197
5198 __clear_chan_timer(chan);
5199 if (result == L2CAP_MR_PEND)
5200 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
5201
5202 switch (chan->move_state) {
5203 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
5204 /* Move confirm will be sent when logical link
5205 * is complete.
5206 */
5207 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5208 break;
5209 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
5210 if (result == L2CAP_MR_PEND) {
5211 break;
5212 } else if (test_bit(CONN_LOCAL_BUSY,
5213 &chan->conn_state)) {
5214 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
5215 } else {
5216 /* Logical link is up or moving to BR/EDR,
5217 * proceed with move
5218 */
5219 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
5220 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5221 }
5222 break;
5223 case L2CAP_MOVE_WAIT_RSP:
5224 /* Moving to AMP */
5225 if (result == L2CAP_MR_SUCCESS) {
5226 /* Remote is ready, send confirm immediately
5227 * after logical link is ready
5228 */
5229 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5230 } else {
5231 /* Both logical link and move success
5232 * are required to confirm
5233 */
5234 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
5235 }
5236
5237 /* Placeholder - get hci_chan for logical link */
5238 if (!hchan) {
5239 /* Logical link not available */
5240 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5241 break;
5242 }
5243
5244 /* If the logical link is not yet connected, do not
5245 * send confirmation.
5246 */
5247 if (hchan->state != BT_CONNECTED)
5248 break;
5249
5250 /* Logical link is already ready to go */
5251
5252 chan->hs_hcon = hchan->conn;
5253 chan->hs_hcon->l2cap_data = chan->conn;
5254
5255 if (result == L2CAP_MR_SUCCESS) {
5256 /* Can confirm now */
5257 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5258 } else {
5259 /* Now only need move success
5260 * to confirm
5261 */
5262 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
5263 }
5264
5265 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5266 break;
5267 default:
5268 /* Any other amp move state means the move failed. */
5269 chan->move_id = chan->local_amp_id;
5270 l2cap_move_done(chan);
5271 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5272 }
5273
5274 l2cap_chan_unlock(chan);
5275}
5276
5277static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5278 u16 result)
5279{
5280 struct l2cap_chan *chan;
5281
5282 chan = l2cap_get_chan_by_ident(conn, ident);
5283 if (!chan) {
5284 /* Could not locate channel, icid is best guess */
5285 l2cap_send_move_chan_cfm_icid(conn, icid);
5286 return;
5287 }
5288
5289 __clear_chan_timer(chan);
5290
5291 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5292 if (result == L2CAP_MR_COLLISION) {
5293 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5294 } else {
5295 /* Cleanup - cancel move */
5296 chan->move_id = chan->local_amp_id;
5297 l2cap_move_done(chan);
5298 }
5299 }
5300
5301 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5302
5303 l2cap_chan_unlock(chan);
5304}
5305
5306static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5307 struct l2cap_cmd_hdr *cmd,
5308 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005309{
5310 struct l2cap_move_chan_rsp *rsp = data;
5311 u16 icid, result;
5312
5313 if (cmd_len != sizeof(*rsp))
5314 return -EPROTO;
5315
5316 icid = le16_to_cpu(rsp->icid);
5317 result = le16_to_cpu(rsp->result);
5318
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005319 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005320
Mat Martineau5b155ef2012-10-23 15:24:14 -07005321 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5322 l2cap_move_continue(conn, icid, result);
5323 else
5324 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005325
5326 return 0;
5327}
5328
Mat Martineau5f3847a2012-10-23 15:24:12 -07005329static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5330 struct l2cap_cmd_hdr *cmd,
5331 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005332{
5333 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005334 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005335 u16 icid, result;
5336
5337 if (cmd_len != sizeof(*cfm))
5338 return -EPROTO;
5339
5340 icid = le16_to_cpu(cfm->icid);
5341 result = le16_to_cpu(cfm->result);
5342
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005343 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005344
Mat Martineau5f3847a2012-10-23 15:24:12 -07005345 chan = l2cap_get_chan_by_dcid(conn, icid);
5346 if (!chan) {
5347 /* Spec requires a response even if the icid was not found */
5348 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5349 return 0;
5350 }
5351
5352 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5353 if (result == L2CAP_MC_CONFIRMED) {
5354 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005355 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005356 __release_logical_link(chan);
5357 } else {
5358 chan->move_id = chan->local_amp_id;
5359 }
5360
5361 l2cap_move_done(chan);
5362 }
5363
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005364 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5365
Mat Martineau5f3847a2012-10-23 15:24:12 -07005366 l2cap_chan_unlock(chan);
5367
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005368 return 0;
5369}
5370
5371static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005372 struct l2cap_cmd_hdr *cmd,
5373 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005374{
5375 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005376 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005377 u16 icid;
5378
5379 if (cmd_len != sizeof(*rsp))
5380 return -EPROTO;
5381
5382 icid = le16_to_cpu(rsp->icid);
5383
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005384 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005385
Mat Martineau3fd71a02012-10-23 15:24:16 -07005386 chan = l2cap_get_chan_by_scid(conn, icid);
5387 if (!chan)
5388 return 0;
5389
5390 __clear_chan_timer(chan);
5391
5392 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5393 chan->local_amp_id = chan->move_id;
5394
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005395 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005396 __release_logical_link(chan);
5397
5398 l2cap_move_done(chan);
5399 }
5400
5401 l2cap_chan_unlock(chan);
5402
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005403 return 0;
5404}
5405
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005406static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005407 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005408{
5409 u16 max_latency;
5410
5411 if (min > max || min < 6 || max > 3200)
5412 return -EINVAL;
5413
5414 if (to_multiplier < 10 || to_multiplier > 3200)
5415 return -EINVAL;
5416
5417 if (max >= to_multiplier * 8)
5418 return -EINVAL;
5419
5420 max_latency = (to_multiplier * 8 / max) - 1;
5421 if (latency > 499 || latency > max_latency)
5422 return -EINVAL;
5423
5424 return 0;
5425}
5426
5427static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005428 struct l2cap_cmd_hdr *cmd,
Johan Hedberg203e6392013-05-15 10:07:15 +03005429 u16 cmd_len, u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005430{
5431 struct hci_conn *hcon = conn->hcon;
5432 struct l2cap_conn_param_update_req *req;
5433 struct l2cap_conn_param_update_rsp rsp;
Johan Hedberg203e6392013-05-15 10:07:15 +03005434 u16 min, max, latency, to_multiplier;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005435 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005436
5437 if (!(hcon->link_mode & HCI_LM_MASTER))
5438 return -EINVAL;
5439
Claudio Takahaside731152011-02-11 19:28:55 -02005440 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5441 return -EPROTO;
5442
5443 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005444 min = __le16_to_cpu(req->min);
5445 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005446 latency = __le16_to_cpu(req->latency);
5447 to_multiplier = __le16_to_cpu(req->to_multiplier);
5448
5449 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 +01005450 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005451
5452 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005453
5454 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5455 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005456 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005457 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005458 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005459
5460 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005461 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005462
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005463 if (!err)
5464 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5465
Claudio Takahaside731152011-02-11 19:28:55 -02005466 return 0;
5467}
5468
Johan Hedbergf1496de2013-05-13 14:15:56 +03005469static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
5470 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5471 u8 *data)
5472{
5473 struct l2cap_le_conn_rsp *rsp = (struct l2cap_le_conn_rsp *) data;
5474 u16 dcid, mtu, mps, credits, result;
5475 struct l2cap_chan *chan;
5476 int err;
5477
5478 if (cmd_len < sizeof(*rsp))
5479 return -EPROTO;
5480
5481 dcid = __le16_to_cpu(rsp->dcid);
5482 mtu = __le16_to_cpu(rsp->mtu);
5483 mps = __le16_to_cpu(rsp->mps);
5484 credits = __le16_to_cpu(rsp->credits);
5485 result = __le16_to_cpu(rsp->result);
5486
5487 if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23))
5488 return -EPROTO;
5489
5490 BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x",
5491 dcid, mtu, mps, credits, result);
5492
5493 mutex_lock(&conn->chan_lock);
5494
5495 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
5496 if (!chan) {
5497 err = -EBADSLT;
5498 goto unlock;
5499 }
5500
5501 err = 0;
5502
5503 l2cap_chan_lock(chan);
5504
5505 switch (result) {
5506 case L2CAP_CR_SUCCESS:
5507 chan->ident = 0;
5508 chan->dcid = dcid;
5509 chan->omtu = mtu;
5510 chan->remote_mps = mps;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005511 chan->tx_credits = credits;
Johan Hedbergf1496de2013-05-13 14:15:56 +03005512 l2cap_chan_ready(chan);
5513 break;
5514
5515 default:
5516 l2cap_chan_del(chan, ECONNREFUSED);
5517 break;
5518 }
5519
5520 l2cap_chan_unlock(chan);
5521
5522unlock:
5523 mutex_unlock(&conn->chan_lock);
5524
5525 return err;
5526}
5527
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005528static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005529 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5530 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005531{
5532 int err = 0;
5533
5534 switch (cmd->code) {
5535 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005536 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005537 break;
5538
5539 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005540 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005541 break;
5542
5543 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005544 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005545 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005546 break;
5547
5548 case L2CAP_CONF_REQ:
5549 err = l2cap_config_req(conn, cmd, cmd_len, data);
5550 break;
5551
5552 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005553 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005554 break;
5555
5556 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005557 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005558 break;
5559
5560 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005561 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005562 break;
5563
5564 case L2CAP_ECHO_REQ:
5565 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5566 break;
5567
5568 case L2CAP_ECHO_RSP:
5569 break;
5570
5571 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005572 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005573 break;
5574
5575 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005576 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005577 break;
5578
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005579 case L2CAP_CREATE_CHAN_REQ:
5580 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5581 break;
5582
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005583 case L2CAP_MOVE_CHAN_REQ:
5584 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5585 break;
5586
5587 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005588 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005589 break;
5590
5591 case L2CAP_MOVE_CHAN_CFM:
5592 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5593 break;
5594
5595 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005596 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005597 break;
5598
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005599 default:
5600 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5601 err = -EINVAL;
5602 break;
5603 }
5604
5605 return err;
5606}
5607
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005608static int l2cap_le_connect_req(struct l2cap_conn *conn,
5609 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5610 u8 *data)
5611{
5612 struct l2cap_le_conn_req *req = (struct l2cap_le_conn_req *) data;
5613 struct l2cap_le_conn_rsp rsp;
5614 struct l2cap_chan *chan, *pchan;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005615 u16 dcid, scid, credits, mtu, mps;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005616 __le16 psm;
5617 u8 result;
5618
5619 if (cmd_len != sizeof(*req))
5620 return -EPROTO;
5621
5622 scid = __le16_to_cpu(req->scid);
5623 mtu = __le16_to_cpu(req->mtu);
5624 mps = __le16_to_cpu(req->mps);
5625 psm = req->psm;
5626 dcid = 0;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005627 credits = 0;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005628
5629 if (mtu < 23 || mps < 23)
5630 return -EPROTO;
5631
5632 BT_DBG("psm 0x%2.2x scid 0x%4.4x mtu %u mps %u", __le16_to_cpu(psm),
5633 scid, mtu, mps);
5634
5635 /* Check if we have socket listening on psm */
5636 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
5637 &conn->hcon->dst, LE_LINK);
5638 if (!pchan) {
5639 result = L2CAP_CR_BAD_PSM;
5640 chan = NULL;
5641 goto response;
5642 }
5643
5644 mutex_lock(&conn->chan_lock);
5645 l2cap_chan_lock(pchan);
5646
5647 if (!smp_sufficient_security(conn->hcon, pchan->sec_level)) {
5648 result = L2CAP_CR_AUTHENTICATION;
5649 chan = NULL;
5650 goto response_unlock;
5651 }
5652
5653 /* Check if we already have channel with that dcid */
5654 if (__l2cap_get_chan_by_dcid(conn, scid)) {
5655 result = L2CAP_CR_NO_MEM;
5656 chan = NULL;
5657 goto response_unlock;
5658 }
5659
5660 chan = pchan->ops->new_connection(pchan);
5661 if (!chan) {
5662 result = L2CAP_CR_NO_MEM;
5663 goto response_unlock;
5664 }
5665
5666 bacpy(&chan->src, &conn->hcon->src);
5667 bacpy(&chan->dst, &conn->hcon->dst);
5668 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
5669 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
5670 chan->psm = psm;
5671 chan->dcid = scid;
5672 chan->omtu = mtu;
5673 chan->remote_mps = mps;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005674 chan->tx_credits = __le16_to_cpu(req->credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005675
5676 __l2cap_chan_add(conn, chan);
5677 dcid = chan->scid;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005678 credits = chan->rx_credits;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005679
5680 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
5681
5682 chan->ident = cmd->ident;
5683
5684 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
5685 l2cap_state_change(chan, BT_CONNECT2);
5686 result = L2CAP_CR_PEND;
5687 chan->ops->defer(chan);
5688 } else {
5689 l2cap_chan_ready(chan);
5690 result = L2CAP_CR_SUCCESS;
5691 }
5692
5693response_unlock:
5694 l2cap_chan_unlock(pchan);
5695 mutex_unlock(&conn->chan_lock);
5696
5697 if (result == L2CAP_CR_PEND)
5698 return 0;
5699
5700response:
5701 if (chan) {
5702 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02005703 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005704 } else {
5705 rsp.mtu = 0;
5706 rsp.mps = 0;
5707 }
5708
5709 rsp.dcid = cpu_to_le16(dcid);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005710 rsp.credits = cpu_to_le16(credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005711 rsp.result = cpu_to_le16(result);
5712
5713 l2cap_send_cmd(conn, cmd->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), &rsp);
5714
5715 return 0;
5716}
5717
Johan Hedbergfad5fc892013-12-05 09:45:01 +02005718static inline int l2cap_le_credits(struct l2cap_conn *conn,
5719 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5720 u8 *data)
5721{
5722 struct l2cap_le_credits *pkt;
5723 struct l2cap_chan *chan;
5724 u16 cid, credits;
5725
5726 if (cmd_len != sizeof(*pkt))
5727 return -EPROTO;
5728
5729 pkt = (struct l2cap_le_credits *) data;
5730 cid = __le16_to_cpu(pkt->cid);
5731 credits = __le16_to_cpu(pkt->credits);
5732
5733 BT_DBG("cid 0x%4.4x credits 0x%4.4x", cid, credits);
5734
5735 chan = l2cap_get_chan_by_dcid(conn, cid);
5736 if (!chan)
5737 return -EBADSLT;
5738
5739 chan->tx_credits += credits;
5740
5741 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
5742 l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
5743 chan->tx_credits--;
5744 }
5745
5746 if (chan->tx_credits)
5747 chan->ops->resume(chan);
5748
5749 l2cap_chan_unlock(chan);
5750
5751 return 0;
5752}
5753
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005754static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Johan Hedberg203e6392013-05-15 10:07:15 +03005755 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5756 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005757{
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005758 int err = 0;
5759
Johan Hedberg3af8ace2013-12-03 09:51:51 +02005760 if (!enable_lecoc) {
5761 switch (cmd->code) {
5762 case L2CAP_LE_CONN_REQ:
5763 case L2CAP_LE_CONN_RSP:
5764 case L2CAP_LE_CREDITS:
5765 case L2CAP_DISCONN_REQ:
5766 case L2CAP_DISCONN_RSP:
5767 return -EINVAL;
5768 }
5769 }
5770
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005771 switch (cmd->code) {
5772 case L2CAP_COMMAND_REJ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005773 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005774
5775 case L2CAP_CONN_PARAM_UPDATE_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005776 err = l2cap_conn_param_update_req(conn, cmd, cmd_len, data);
5777 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005778
5779 case L2CAP_CONN_PARAM_UPDATE_RSP:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005780 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005781
Johan Hedbergf1496de2013-05-13 14:15:56 +03005782 case L2CAP_LE_CONN_RSP:
5783 l2cap_le_connect_rsp(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005784 break;
Johan Hedbergf1496de2013-05-13 14:15:56 +03005785
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005786 case L2CAP_LE_CONN_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005787 err = l2cap_le_connect_req(conn, cmd, cmd_len, data);
5788 break;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005789
Johan Hedbergfad5fc892013-12-05 09:45:01 +02005790 case L2CAP_LE_CREDITS:
5791 err = l2cap_le_credits(conn, cmd, cmd_len, data);
5792 break;
5793
Johan Hedberg3defe012013-05-15 10:16:06 +03005794 case L2CAP_DISCONN_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005795 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
5796 break;
Johan Hedberg3defe012013-05-15 10:16:06 +03005797
5798 case L2CAP_DISCONN_RSP:
5799 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005800 break;
Johan Hedberg3defe012013-05-15 10:16:06 +03005801
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005802 default:
5803 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005804 err = -EINVAL;
5805 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005806 }
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005807
5808 return err;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005809}
5810
Johan Hedbergc5623552013-04-29 19:35:33 +03005811static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5812 struct sk_buff *skb)
5813{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005814 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005815 struct l2cap_cmd_hdr *cmd;
5816 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005817 int err;
5818
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005819 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005820 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005821
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005822 if (skb->len < L2CAP_CMD_HDR_SIZE)
5823 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005824
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005825 cmd = (void *) skb->data;
5826 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005827
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005828 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005829
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005830 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005831
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005832 if (len != skb->len || !cmd->ident) {
5833 BT_DBG("corrupted command");
5834 goto drop;
5835 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005836
Johan Hedberg203e6392013-05-15 10:07:15 +03005837 err = l2cap_le_sig_cmd(conn, cmd, len, skb->data);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005838 if (err) {
5839 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005840
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005841 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005842
Johan Hedberga5211492013-10-16 11:20:49 +03005843 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005844 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5845 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005846 }
5847
Marcel Holtmann3b166292013-10-02 08:28:21 -07005848drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005849 kfree_skb(skb);
5850}
5851
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005852static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005853 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005854{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005855 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005856 u8 *data = skb->data;
5857 int len = skb->len;
5858 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005859 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005860
5861 l2cap_raw_recv(conn, skb);
5862
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005863 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005864 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005865
Linus Torvalds1da177e2005-04-16 15:20:36 -07005866 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005867 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005868 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5869 data += L2CAP_CMD_HDR_SIZE;
5870 len -= L2CAP_CMD_HDR_SIZE;
5871
Al Viro88219a02007-07-29 00:17:25 -07005872 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005873
Gustavo Padovan2d792812012-10-06 10:07:01 +01005874 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5875 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005876
Al Viro88219a02007-07-29 00:17:25 -07005877 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005878 BT_DBG("corrupted command");
5879 break;
5880 }
5881
Johan Hedbergc5623552013-04-29 19:35:33 +03005882 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005883 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005884 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005885
5886 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005887
Johan Hedberga5211492013-10-16 11:20:49 +03005888 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005889 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5890 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005891 }
5892
Al Viro88219a02007-07-29 00:17:25 -07005893 data += cmd_len;
5894 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005895 }
5896
Marcel Holtmann3b166292013-10-02 08:28:21 -07005897drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005898 kfree_skb(skb);
5899}
5900
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005901static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005902{
5903 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005904 int hdr_size;
5905
5906 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5907 hdr_size = L2CAP_EXT_HDR_SIZE;
5908 else
5909 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005910
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005911 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005912 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005913 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5914 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5915
5916 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005917 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005918 }
5919 return 0;
5920}
5921
Mat Martineau6ea00482012-05-17 20:53:52 -07005922static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005923{
Mat Martineaue31f7632012-05-17 20:53:41 -07005924 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005925
Mat Martineaue31f7632012-05-17 20:53:41 -07005926 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005927
Mat Martineaue31f7632012-05-17 20:53:41 -07005928 memset(&control, 0, sizeof(control));
5929 control.sframe = 1;
5930 control.final = 1;
5931 control.reqseq = chan->buffer_seq;
5932 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005933
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005934 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005935 control.super = L2CAP_SUPER_RNR;
5936 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005937 }
5938
Mat Martineaue31f7632012-05-17 20:53:41 -07005939 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5940 chan->unacked_frames > 0)
5941 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005942
Mat Martineaue31f7632012-05-17 20:53:41 -07005943 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005944 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005945
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005946 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005947 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5948 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5949 * send it now.
5950 */
5951 control.super = L2CAP_SUPER_RR;
5952 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005953 }
5954}
5955
Gustavo Padovan2d792812012-10-06 10:07:01 +01005956static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5957 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005958{
Mat Martineau84084a32011-07-22 14:54:00 -07005959 /* skb->len reflects data in skb as well as all fragments
5960 * skb->data_len reflects only data in fragments
5961 */
5962 if (!skb_has_frag_list(skb))
5963 skb_shinfo(skb)->frag_list = new_frag;
5964
5965 new_frag->next = NULL;
5966
5967 (*last_frag)->next = new_frag;
5968 *last_frag = new_frag;
5969
5970 skb->len += new_frag->len;
5971 skb->data_len += new_frag->len;
5972 skb->truesize += new_frag->truesize;
5973}
5974
Mat Martineau4b51dae92012-05-17 20:53:37 -07005975static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5976 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005977{
5978 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005979
Mat Martineau4b51dae92012-05-17 20:53:37 -07005980 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005981 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005982 if (chan->sdu)
5983 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005984
Gustavo Padovan80b98022012-05-27 22:27:51 -03005985 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005986 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005987
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005988 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005989 if (chan->sdu)
5990 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005991
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005992 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005993 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005994
Mat Martineau84084a32011-07-22 14:54:00 -07005995 if (chan->sdu_len > chan->imtu) {
5996 err = -EMSGSIZE;
5997 break;
5998 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005999
Mat Martineau84084a32011-07-22 14:54:00 -07006000 if (skb->len >= chan->sdu_len)
6001 break;
6002
6003 chan->sdu = skb;
6004 chan->sdu_last_frag = skb;
6005
6006 skb = NULL;
6007 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006008 break;
6009
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03006010 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03006011 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07006012 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006013
Mat Martineau84084a32011-07-22 14:54:00 -07006014 append_skb_frag(chan->sdu, skb,
6015 &chan->sdu_last_frag);
6016 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006017
Mat Martineau84084a32011-07-22 14:54:00 -07006018 if (chan->sdu->len >= chan->sdu_len)
6019 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03006020
Mat Martineau84084a32011-07-22 14:54:00 -07006021 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006022 break;
6023
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03006024 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03006025 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07006026 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006027
Mat Martineau84084a32011-07-22 14:54:00 -07006028 append_skb_frag(chan->sdu, skb,
6029 &chan->sdu_last_frag);
6030 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006031
Mat Martineau84084a32011-07-22 14:54:00 -07006032 if (chan->sdu->len != chan->sdu_len)
6033 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006034
Gustavo Padovan80b98022012-05-27 22:27:51 -03006035 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03006036
Mat Martineau84084a32011-07-22 14:54:00 -07006037 if (!err) {
6038 /* Reassembly complete */
6039 chan->sdu = NULL;
6040 chan->sdu_last_frag = NULL;
6041 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03006042 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006043 break;
6044 }
6045
Mat Martineau84084a32011-07-22 14:54:00 -07006046 if (err) {
6047 kfree_skb(skb);
6048 kfree_skb(chan->sdu);
6049 chan->sdu = NULL;
6050 chan->sdu_last_frag = NULL;
6051 chan->sdu_len = 0;
6052 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006053
Mat Martineau84084a32011-07-22 14:54:00 -07006054 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006055}
6056
Mat Martineau32b32732012-10-23 15:24:11 -07006057static int l2cap_resegment(struct l2cap_chan *chan)
6058{
6059 /* Placeholder */
6060 return 0;
6061}
6062
Mat Martineaue3281402011-07-07 09:39:02 -07006063void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03006064{
Mat Martineau61aa4f52012-05-17 20:53:40 -07006065 u8 event;
6066
6067 if (chan->mode != L2CAP_MODE_ERTM)
6068 return;
6069
6070 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03006071 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03006072}
6073
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006074static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
6075{
Mat Martineau63838722012-05-17 20:53:45 -07006076 int err = 0;
6077 /* Pass sequential frames to l2cap_reassemble_sdu()
6078 * until a gap is encountered.
6079 */
6080
6081 BT_DBG("chan %p", chan);
6082
6083 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6084 struct sk_buff *skb;
6085 BT_DBG("Searching for skb with txseq %d (queue len %d)",
6086 chan->buffer_seq, skb_queue_len(&chan->srej_q));
6087
6088 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
6089
6090 if (!skb)
6091 break;
6092
6093 skb_unlink(skb, &chan->srej_q);
6094 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6095 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
6096 if (err)
6097 break;
6098 }
6099
6100 if (skb_queue_empty(&chan->srej_q)) {
6101 chan->rx_state = L2CAP_RX_STATE_RECV;
6102 l2cap_send_ack(chan);
6103 }
6104
6105 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006106}
6107
6108static void l2cap_handle_srej(struct l2cap_chan *chan,
6109 struct l2cap_ctrl *control)
6110{
Mat Martineauf80842a2012-05-17 20:53:46 -07006111 struct sk_buff *skb;
6112
6113 BT_DBG("chan %p, control %p", chan, control);
6114
6115 if (control->reqseq == chan->next_tx_seq) {
6116 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006117 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07006118 return;
6119 }
6120
6121 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
6122
6123 if (skb == NULL) {
6124 BT_DBG("Seq %d not available for retransmission",
6125 control->reqseq);
6126 return;
6127 }
6128
6129 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
6130 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006131 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07006132 return;
6133 }
6134
6135 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6136
6137 if (control->poll) {
6138 l2cap_pass_to_tx(chan, control);
6139
6140 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6141 l2cap_retransmit(chan, control);
6142 l2cap_ertm_send(chan);
6143
6144 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
6145 set_bit(CONN_SREJ_ACT, &chan->conn_state);
6146 chan->srej_save_reqseq = control->reqseq;
6147 }
6148 } else {
6149 l2cap_pass_to_tx_fbit(chan, control);
6150
6151 if (control->final) {
6152 if (chan->srej_save_reqseq != control->reqseq ||
6153 !test_and_clear_bit(CONN_SREJ_ACT,
6154 &chan->conn_state))
6155 l2cap_retransmit(chan, control);
6156 } else {
6157 l2cap_retransmit(chan, control);
6158 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
6159 set_bit(CONN_SREJ_ACT, &chan->conn_state);
6160 chan->srej_save_reqseq = control->reqseq;
6161 }
6162 }
6163 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006164}
6165
6166static void l2cap_handle_rej(struct l2cap_chan *chan,
6167 struct l2cap_ctrl *control)
6168{
Mat Martineaufcd289d2012-05-17 20:53:47 -07006169 struct sk_buff *skb;
6170
6171 BT_DBG("chan %p, control %p", chan, control);
6172
6173 if (control->reqseq == chan->next_tx_seq) {
6174 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006175 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07006176 return;
6177 }
6178
6179 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
6180
6181 if (chan->max_tx && skb &&
6182 bt_cb(skb)->control.retries >= chan->max_tx) {
6183 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006184 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07006185 return;
6186 }
6187
6188 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6189
6190 l2cap_pass_to_tx(chan, control);
6191
6192 if (control->final) {
6193 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
6194 l2cap_retransmit_all(chan, control);
6195 } else {
6196 l2cap_retransmit_all(chan, control);
6197 l2cap_ertm_send(chan);
6198 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
6199 set_bit(CONN_REJ_ACT, &chan->conn_state);
6200 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006201}
6202
Mat Martineau4b51dae92012-05-17 20:53:37 -07006203static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
6204{
6205 BT_DBG("chan %p, txseq %d", chan, txseq);
6206
6207 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
6208 chan->expected_tx_seq);
6209
6210 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
6211 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01006212 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07006213 /* See notes below regarding "double poll" and
6214 * invalid packets.
6215 */
6216 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
6217 BT_DBG("Invalid/Ignore - after SREJ");
6218 return L2CAP_TXSEQ_INVALID_IGNORE;
6219 } else {
6220 BT_DBG("Invalid - in window after SREJ sent");
6221 return L2CAP_TXSEQ_INVALID;
6222 }
6223 }
6224
6225 if (chan->srej_list.head == txseq) {
6226 BT_DBG("Expected SREJ");
6227 return L2CAP_TXSEQ_EXPECTED_SREJ;
6228 }
6229
6230 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
6231 BT_DBG("Duplicate SREJ - txseq already stored");
6232 return L2CAP_TXSEQ_DUPLICATE_SREJ;
6233 }
6234
6235 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
6236 BT_DBG("Unexpected SREJ - not requested");
6237 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
6238 }
6239 }
6240
6241 if (chan->expected_tx_seq == txseq) {
6242 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
6243 chan->tx_win) {
6244 BT_DBG("Invalid - txseq outside tx window");
6245 return L2CAP_TXSEQ_INVALID;
6246 } else {
6247 BT_DBG("Expected");
6248 return L2CAP_TXSEQ_EXPECTED;
6249 }
6250 }
6251
6252 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01006253 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07006254 BT_DBG("Duplicate - expected_tx_seq later than txseq");
6255 return L2CAP_TXSEQ_DUPLICATE;
6256 }
6257
6258 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
6259 /* A source of invalid packets is a "double poll" condition,
6260 * where delays cause us to send multiple poll packets. If
6261 * the remote stack receives and processes both polls,
6262 * sequence numbers can wrap around in such a way that a
6263 * resent frame has a sequence number that looks like new data
6264 * with a sequence gap. This would trigger an erroneous SREJ
6265 * request.
6266 *
6267 * Fortunately, this is impossible with a tx window that's
6268 * less than half of the maximum sequence number, which allows
6269 * invalid frames to be safely ignored.
6270 *
6271 * With tx window sizes greater than half of the tx window
6272 * maximum, the frame is invalid and cannot be ignored. This
6273 * causes a disconnect.
6274 */
6275
6276 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
6277 BT_DBG("Invalid/Ignore - txseq outside tx window");
6278 return L2CAP_TXSEQ_INVALID_IGNORE;
6279 } else {
6280 BT_DBG("Invalid - txseq outside tx window");
6281 return L2CAP_TXSEQ_INVALID;
6282 }
6283 } else {
6284 BT_DBG("Unexpected - txseq indicates missing frames");
6285 return L2CAP_TXSEQ_UNEXPECTED;
6286 }
6287}
6288
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006289static int l2cap_rx_state_recv(struct l2cap_chan *chan,
6290 struct l2cap_ctrl *control,
6291 struct sk_buff *skb, u8 event)
6292{
6293 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006294 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006295
6296 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6297 event);
6298
6299 switch (event) {
6300 case L2CAP_EV_RECV_IFRAME:
6301 switch (l2cap_classify_txseq(chan, control->txseq)) {
6302 case L2CAP_TXSEQ_EXPECTED:
6303 l2cap_pass_to_tx(chan, control);
6304
6305 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6306 BT_DBG("Busy, discarding expected seq %d",
6307 control->txseq);
6308 break;
6309 }
6310
6311 chan->expected_tx_seq = __next_seq(chan,
6312 control->txseq);
6313
6314 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006315 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006316
6317 err = l2cap_reassemble_sdu(chan, skb, control);
6318 if (err)
6319 break;
6320
6321 if (control->final) {
6322 if (!test_and_clear_bit(CONN_REJ_ACT,
6323 &chan->conn_state)) {
6324 control->final = 0;
6325 l2cap_retransmit_all(chan, control);
6326 l2cap_ertm_send(chan);
6327 }
6328 }
6329
6330 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
6331 l2cap_send_ack(chan);
6332 break;
6333 case L2CAP_TXSEQ_UNEXPECTED:
6334 l2cap_pass_to_tx(chan, control);
6335
6336 /* Can't issue SREJ frames in the local busy state.
6337 * Drop this frame, it will be seen as missing
6338 * when local busy is exited.
6339 */
6340 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6341 BT_DBG("Busy, discarding unexpected seq %d",
6342 control->txseq);
6343 break;
6344 }
6345
6346 /* There was a gap in the sequence, so an SREJ
6347 * must be sent for each missing frame. The
6348 * current frame is stored for later use.
6349 */
6350 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006351 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006352 BT_DBG("Queued %p (queue len %d)", skb,
6353 skb_queue_len(&chan->srej_q));
6354
6355 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
6356 l2cap_seq_list_clear(&chan->srej_list);
6357 l2cap_send_srej(chan, control->txseq);
6358
6359 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
6360 break;
6361 case L2CAP_TXSEQ_DUPLICATE:
6362 l2cap_pass_to_tx(chan, control);
6363 break;
6364 case L2CAP_TXSEQ_INVALID_IGNORE:
6365 break;
6366 case L2CAP_TXSEQ_INVALID:
6367 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006368 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006369 break;
6370 }
6371 break;
6372 case L2CAP_EV_RECV_RR:
6373 l2cap_pass_to_tx(chan, control);
6374 if (control->final) {
6375 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6376
Mat Martineaue6a3ee62012-10-23 15:24:22 -07006377 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
6378 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006379 control->final = 0;
6380 l2cap_retransmit_all(chan, control);
6381 }
6382
6383 l2cap_ertm_send(chan);
6384 } else if (control->poll) {
6385 l2cap_send_i_or_rr_or_rnr(chan);
6386 } else {
6387 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6388 &chan->conn_state) &&
6389 chan->unacked_frames)
6390 __set_retrans_timer(chan);
6391
6392 l2cap_ertm_send(chan);
6393 }
6394 break;
6395 case L2CAP_EV_RECV_RNR:
6396 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6397 l2cap_pass_to_tx(chan, control);
6398 if (control && control->poll) {
6399 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6400 l2cap_send_rr_or_rnr(chan, 0);
6401 }
6402 __clear_retrans_timer(chan);
6403 l2cap_seq_list_clear(&chan->retrans_list);
6404 break;
6405 case L2CAP_EV_RECV_REJ:
6406 l2cap_handle_rej(chan, control);
6407 break;
6408 case L2CAP_EV_RECV_SREJ:
6409 l2cap_handle_srej(chan, control);
6410 break;
6411 default:
6412 break;
6413 }
6414
6415 if (skb && !skb_in_use) {
6416 BT_DBG("Freeing %p", skb);
6417 kfree_skb(skb);
6418 }
6419
6420 return err;
6421}
6422
6423static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
6424 struct l2cap_ctrl *control,
6425 struct sk_buff *skb, u8 event)
6426{
6427 int err = 0;
6428 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006429 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006430
6431 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6432 event);
6433
6434 switch (event) {
6435 case L2CAP_EV_RECV_IFRAME:
6436 switch (l2cap_classify_txseq(chan, txseq)) {
6437 case L2CAP_TXSEQ_EXPECTED:
6438 /* Keep frame for reassembly later */
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 chan->expected_tx_seq = __next_seq(chan, txseq);
6446 break;
6447 case L2CAP_TXSEQ_EXPECTED_SREJ:
6448 l2cap_seq_list_pop(&chan->srej_list);
6449
6450 l2cap_pass_to_tx(chan, control);
6451 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006452 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006453 BT_DBG("Queued %p (queue len %d)", skb,
6454 skb_queue_len(&chan->srej_q));
6455
6456 err = l2cap_rx_queued_iframes(chan);
6457 if (err)
6458 break;
6459
6460 break;
6461 case L2CAP_TXSEQ_UNEXPECTED:
6462 /* Got a frame that can't be reassembled yet.
6463 * Save it for later, and send SREJs to cover
6464 * the missing frames.
6465 */
6466 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006467 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006468 BT_DBG("Queued %p (queue len %d)", skb,
6469 skb_queue_len(&chan->srej_q));
6470
6471 l2cap_pass_to_tx(chan, control);
6472 l2cap_send_srej(chan, control->txseq);
6473 break;
6474 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
6475 /* This frame was requested with an SREJ, but
6476 * some expected retransmitted frames are
6477 * missing. Request retransmission of missing
6478 * SREJ'd frames.
6479 */
6480 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006481 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006482 BT_DBG("Queued %p (queue len %d)", skb,
6483 skb_queue_len(&chan->srej_q));
6484
6485 l2cap_pass_to_tx(chan, control);
6486 l2cap_send_srej_list(chan, control->txseq);
6487 break;
6488 case L2CAP_TXSEQ_DUPLICATE_SREJ:
6489 /* We've already queued this frame. Drop this copy. */
6490 l2cap_pass_to_tx(chan, control);
6491 break;
6492 case L2CAP_TXSEQ_DUPLICATE:
6493 /* Expecting a later sequence number, so this frame
6494 * was already received. Ignore it completely.
6495 */
6496 break;
6497 case L2CAP_TXSEQ_INVALID_IGNORE:
6498 break;
6499 case L2CAP_TXSEQ_INVALID:
6500 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006501 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006502 break;
6503 }
6504 break;
6505 case L2CAP_EV_RECV_RR:
6506 l2cap_pass_to_tx(chan, control);
6507 if (control->final) {
6508 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6509
6510 if (!test_and_clear_bit(CONN_REJ_ACT,
6511 &chan->conn_state)) {
6512 control->final = 0;
6513 l2cap_retransmit_all(chan, control);
6514 }
6515
6516 l2cap_ertm_send(chan);
6517 } else if (control->poll) {
6518 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6519 &chan->conn_state) &&
6520 chan->unacked_frames) {
6521 __set_retrans_timer(chan);
6522 }
6523
6524 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6525 l2cap_send_srej_tail(chan);
6526 } else {
6527 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6528 &chan->conn_state) &&
6529 chan->unacked_frames)
6530 __set_retrans_timer(chan);
6531
6532 l2cap_send_ack(chan);
6533 }
6534 break;
6535 case L2CAP_EV_RECV_RNR:
6536 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6537 l2cap_pass_to_tx(chan, control);
6538 if (control->poll) {
6539 l2cap_send_srej_tail(chan);
6540 } else {
6541 struct l2cap_ctrl rr_control;
6542 memset(&rr_control, 0, sizeof(rr_control));
6543 rr_control.sframe = 1;
6544 rr_control.super = L2CAP_SUPER_RR;
6545 rr_control.reqseq = chan->buffer_seq;
6546 l2cap_send_sframe(chan, &rr_control);
6547 }
6548
6549 break;
6550 case L2CAP_EV_RECV_REJ:
6551 l2cap_handle_rej(chan, control);
6552 break;
6553 case L2CAP_EV_RECV_SREJ:
6554 l2cap_handle_srej(chan, control);
6555 break;
6556 }
6557
6558 if (skb && !skb_in_use) {
6559 BT_DBG("Freeing %p", skb);
6560 kfree_skb(skb);
6561 }
6562
6563 return err;
6564}
6565
Mat Martineau32b32732012-10-23 15:24:11 -07006566static int l2cap_finish_move(struct l2cap_chan *chan)
6567{
6568 BT_DBG("chan %p", chan);
6569
6570 chan->rx_state = L2CAP_RX_STATE_RECV;
6571
6572 if (chan->hs_hcon)
6573 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6574 else
6575 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6576
6577 return l2cap_resegment(chan);
6578}
6579
6580static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6581 struct l2cap_ctrl *control,
6582 struct sk_buff *skb, u8 event)
6583{
6584 int err;
6585
6586 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6587 event);
6588
6589 if (!control->poll)
6590 return -EPROTO;
6591
6592 l2cap_process_reqseq(chan, control->reqseq);
6593
6594 if (!skb_queue_empty(&chan->tx_q))
6595 chan->tx_send_head = skb_peek(&chan->tx_q);
6596 else
6597 chan->tx_send_head = NULL;
6598
6599 /* Rewind next_tx_seq to the point expected
6600 * by the receiver.
6601 */
6602 chan->next_tx_seq = control->reqseq;
6603 chan->unacked_frames = 0;
6604
6605 err = l2cap_finish_move(chan);
6606 if (err)
6607 return err;
6608
6609 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6610 l2cap_send_i_or_rr_or_rnr(chan);
6611
6612 if (event == L2CAP_EV_RECV_IFRAME)
6613 return -EPROTO;
6614
6615 return l2cap_rx_state_recv(chan, control, NULL, event);
6616}
6617
6618static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6619 struct l2cap_ctrl *control,
6620 struct sk_buff *skb, u8 event)
6621{
6622 int err;
6623
6624 if (!control->final)
6625 return -EPROTO;
6626
6627 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6628
6629 chan->rx_state = L2CAP_RX_STATE_RECV;
6630 l2cap_process_reqseq(chan, control->reqseq);
6631
6632 if (!skb_queue_empty(&chan->tx_q))
6633 chan->tx_send_head = skb_peek(&chan->tx_q);
6634 else
6635 chan->tx_send_head = NULL;
6636
6637 /* Rewind next_tx_seq to the point expected
6638 * by the receiver.
6639 */
6640 chan->next_tx_seq = control->reqseq;
6641 chan->unacked_frames = 0;
6642
6643 if (chan->hs_hcon)
6644 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6645 else
6646 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6647
6648 err = l2cap_resegment(chan);
6649
6650 if (!err)
6651 err = l2cap_rx_state_recv(chan, control, skb, event);
6652
6653 return err;
6654}
6655
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006656static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6657{
6658 /* Make sure reqseq is for a packet that has been sent but not acked */
6659 u16 unacked;
6660
6661 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6662 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6663}
6664
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006665static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6666 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006667{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006668 int err = 0;
6669
6670 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6671 control, skb, event, chan->rx_state);
6672
6673 if (__valid_reqseq(chan, control->reqseq)) {
6674 switch (chan->rx_state) {
6675 case L2CAP_RX_STATE_RECV:
6676 err = l2cap_rx_state_recv(chan, control, skb, event);
6677 break;
6678 case L2CAP_RX_STATE_SREJ_SENT:
6679 err = l2cap_rx_state_srej_sent(chan, control, skb,
6680 event);
6681 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006682 case L2CAP_RX_STATE_WAIT_P:
6683 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6684 break;
6685 case L2CAP_RX_STATE_WAIT_F:
6686 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6687 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006688 default:
6689 /* shut it down */
6690 break;
6691 }
6692 } else {
6693 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6694 control->reqseq, chan->next_tx_seq,
6695 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006696 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006697 }
6698
6699 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006700}
6701
6702static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6703 struct sk_buff *skb)
6704{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006705 int err = 0;
6706
6707 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6708 chan->rx_state);
6709
6710 if (l2cap_classify_txseq(chan, control->txseq) ==
6711 L2CAP_TXSEQ_EXPECTED) {
6712 l2cap_pass_to_tx(chan, control);
6713
6714 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6715 __next_seq(chan, chan->buffer_seq));
6716
6717 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6718
6719 l2cap_reassemble_sdu(chan, skb, control);
6720 } else {
6721 if (chan->sdu) {
6722 kfree_skb(chan->sdu);
6723 chan->sdu = NULL;
6724 }
6725 chan->sdu_last_frag = NULL;
6726 chan->sdu_len = 0;
6727
6728 if (skb) {
6729 BT_DBG("Freeing %p", skb);
6730 kfree_skb(skb);
6731 }
6732 }
6733
6734 chan->last_acked_seq = control->txseq;
6735 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6736
6737 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006738}
6739
6740static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6741{
6742 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6743 u16 len;
6744 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006745
Mat Martineaub76bbd62012-04-11 10:48:43 -07006746 __unpack_control(chan, skb);
6747
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006748 len = skb->len;
6749
6750 /*
6751 * We can just drop the corrupted I-frame here.
6752 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006753 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006754 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006755 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006756 goto drop;
6757
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006758 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006759 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006760
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006761 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006762 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006763
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006764 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006765 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006766 goto drop;
6767 }
6768
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006769 if (!control->sframe) {
6770 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006771
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006772 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6773 control->sar, control->reqseq, control->final,
6774 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006775
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006776 /* Validate F-bit - F=0 always valid, F=1 only
6777 * valid in TX WAIT_F
6778 */
6779 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006780 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006781
6782 if (chan->mode != L2CAP_MODE_STREAMING) {
6783 event = L2CAP_EV_RECV_IFRAME;
6784 err = l2cap_rx(chan, control, skb, event);
6785 } else {
6786 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006787 }
6788
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006789 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006790 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006791 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006792 const u8 rx_func_to_event[4] = {
6793 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6794 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6795 };
6796
6797 /* Only I-frames are expected in streaming mode */
6798 if (chan->mode == L2CAP_MODE_STREAMING)
6799 goto drop;
6800
6801 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6802 control->reqseq, control->final, control->poll,
6803 control->super);
6804
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006805 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006806 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006807 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006808 goto drop;
6809 }
6810
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006811 /* Validate F and P bits */
6812 if (control->final && (control->poll ||
6813 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6814 goto drop;
6815
6816 event = rx_func_to_event[control->super];
6817 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006818 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006819 }
6820
6821 return 0;
6822
6823drop:
6824 kfree_skb(skb);
6825 return 0;
6826}
6827
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006828static void l2cap_chan_le_send_credits(struct l2cap_chan *chan)
6829{
6830 struct l2cap_conn *conn = chan->conn;
6831 struct l2cap_le_credits pkt;
6832 u16 return_credits;
6833
6834 /* We return more credits to the sender only after the amount of
6835 * credits falls below half of the initial amount.
6836 */
Johan Hedbergf15b8ec2013-12-03 15:08:25 +02006837 if (chan->rx_credits >= (le_max_credits + 1) / 2)
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006838 return;
6839
Johan Hedbergf15b8ec2013-12-03 15:08:25 +02006840 return_credits = le_max_credits - chan->rx_credits;
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006841
6842 BT_DBG("chan %p returning %u credits to sender", chan, return_credits);
6843
6844 chan->rx_credits += return_credits;
6845
6846 pkt.cid = cpu_to_le16(chan->scid);
6847 pkt.credits = cpu_to_le16(return_credits);
6848
6849 chan->ident = l2cap_get_ident(conn);
6850
6851 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CREDITS, sizeof(pkt), &pkt);
6852}
6853
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006854static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6855{
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006856 int err;
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006857
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006858 if (!chan->rx_credits) {
6859 BT_ERR("No credits to receive LE L2CAP data");
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006860 return -ENOBUFS;
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006861 }
6862
6863 if (chan->imtu < skb->len) {
6864 BT_ERR("Too big LE L2CAP PDU");
6865 return -ENOBUFS;
6866 }
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006867
6868 chan->rx_credits--;
6869 BT_DBG("rx_credits %u -> %u", chan->rx_credits + 1, chan->rx_credits);
6870
6871 l2cap_chan_le_send_credits(chan);
6872
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006873 err = 0;
6874
6875 if (!chan->sdu) {
6876 u16 sdu_len;
6877
6878 sdu_len = get_unaligned_le16(skb->data);
6879 skb_pull(skb, L2CAP_SDULEN_SIZE);
6880
6881 BT_DBG("Start of new SDU. sdu_len %u skb->len %u imtu %u",
6882 sdu_len, skb->len, chan->imtu);
6883
6884 if (sdu_len > chan->imtu) {
6885 BT_ERR("Too big LE L2CAP SDU length received");
6886 err = -EMSGSIZE;
6887 goto failed;
6888 }
6889
6890 if (skb->len > sdu_len) {
6891 BT_ERR("Too much LE L2CAP data received");
6892 err = -EINVAL;
6893 goto failed;
6894 }
6895
6896 if (skb->len == sdu_len)
6897 return chan->ops->recv(chan, skb);
6898
6899 chan->sdu = skb;
6900 chan->sdu_len = sdu_len;
6901 chan->sdu_last_frag = skb;
6902
6903 return 0;
6904 }
6905
6906 BT_DBG("SDU fragment. chan->sdu->len %u skb->len %u chan->sdu_len %u",
6907 chan->sdu->len, skb->len, chan->sdu_len);
6908
6909 if (chan->sdu->len + skb->len > chan->sdu_len) {
6910 BT_ERR("Too much LE L2CAP data received");
6911 err = -EINVAL;
6912 goto failed;
6913 }
6914
6915 append_skb_frag(chan->sdu, skb, &chan->sdu_last_frag);
6916 skb = NULL;
6917
6918 if (chan->sdu->len == chan->sdu_len) {
6919 err = chan->ops->recv(chan, chan->sdu);
6920 if (!err) {
6921 chan->sdu = NULL;
6922 chan->sdu_last_frag = NULL;
6923 chan->sdu_len = 0;
6924 }
6925 }
6926
6927failed:
6928 if (err) {
6929 kfree_skb(skb);
6930 kfree_skb(chan->sdu);
6931 chan->sdu = NULL;
6932 chan->sdu_last_frag = NULL;
6933 chan->sdu_len = 0;
6934 }
6935
6936 /* We can't return an error here since we took care of the skb
6937 * freeing internally. An error return would cause the caller to
6938 * do a double-free of the skb.
6939 */
6940 return 0;
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006941}
6942
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006943static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6944 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006945{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006946 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006947
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006948 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006949 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006950 if (cid == L2CAP_CID_A2MP) {
6951 chan = a2mp_channel_create(conn, skb);
6952 if (!chan) {
6953 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006954 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006955 }
6956
6957 l2cap_chan_lock(chan);
6958 } else {
6959 BT_DBG("unknown cid 0x%4.4x", cid);
6960 /* Drop packet and return */
6961 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006962 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006963 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006964 }
6965
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006966 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006967
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006968 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006969 goto drop;
6970
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006971 switch (chan->mode) {
Johan Hedberg38319712013-05-17 12:49:23 +03006972 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006973 if (l2cap_le_data_rcv(chan, skb) < 0)
6974 goto drop;
6975
6976 goto done;
6977
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006978 case L2CAP_MODE_BASIC:
6979 /* If socket recv buffers overflows we drop data here
6980 * which is *bad* because L2CAP has to be reliable.
6981 * But we don't have any other choice. L2CAP doesn't
6982 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006983
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006984 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006985 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006986
Gustavo Padovan80b98022012-05-27 22:27:51 -03006987 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006988 goto done;
6989 break;
6990
6991 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006992 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006993 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006994 goto done;
6995
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006996 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006997 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006998 break;
6999 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007000
7001drop:
7002 kfree_skb(skb);
7003
7004done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007005 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007006}
7007
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03007008static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
7009 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007010{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07007011 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007012 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007013
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07007014 if (hcon->type != ACL_LINK)
7015 goto drop;
7016
Johan Hedbergbf20fd42013-05-14 13:23:13 +03007017 chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst,
7018 ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007019 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007020 goto drop;
7021
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02007022 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007023
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007024 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007025 goto drop;
7026
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03007027 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007028 goto drop;
7029
Marcel Holtmann2edf8702013-10-13 12:55:29 -07007030 /* Store remote BD_ADDR and PSM for msg_name */
Marcel Holtmann06ae3312013-10-18 03:43:00 -07007031 bacpy(&bt_cb(skb)->bdaddr, &hcon->dst);
Marcel Holtmann2edf8702013-10-13 12:55:29 -07007032 bt_cb(skb)->psm = psm;
7033
Gustavo Padovan80b98022012-05-27 22:27:51 -03007034 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03007035 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007036
7037drop:
7038 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007039}
7040
Marcel Holtmann72f78352013-04-23 00:59:00 -07007041static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03007042 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007043{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07007044 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007045 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007046
Marcel Holtmannb99707d2013-10-03 02:54:11 -07007047 if (hcon->type != LE_LINK)
7048 goto drop;
7049
Johan Hedbergaf1c0132013-04-29 19:35:42 +03007050 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann06ae3312013-10-18 03:43:00 -07007051 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007052 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007053 goto drop;
7054
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02007055 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007056
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07007057 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, hcon->dst_type))
7058 goto drop;
7059
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03007060 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007061 goto drop;
7062
Gustavo Padovan80b98022012-05-27 22:27:51 -03007063 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03007064 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007065
7066drop:
7067 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007068}
7069
Linus Torvalds1da177e2005-04-16 15:20:36 -07007070static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
7071{
7072 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07007073 u16 cid, len;
7074 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007075
7076 skb_pull(skb, L2CAP_HDR_SIZE);
7077 cid = __le16_to_cpu(lh->cid);
7078 len = __le16_to_cpu(lh->len);
7079
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03007080 if (len != skb->len) {
7081 kfree_skb(skb);
7082 return;
7083 }
7084
Linus Torvalds1da177e2005-04-16 15:20:36 -07007085 BT_DBG("len %d, cid 0x%4.4x", len, cid);
7086
7087 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03007088 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007089 l2cap_sig_channel(conn, skb);
7090 break;
7091
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03007092 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02007093 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03007094 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007095 l2cap_conless_channel(conn, psm, skb);
7096 break;
7097
Johan Hedberg073d1cf2013-04-29 19:35:35 +03007098 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07007099 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007100 break;
7101
Marcel Holtmanna2877622013-10-02 23:46:54 -07007102 case L2CAP_CID_LE_SIGNALING:
7103 l2cap_le_sig_channel(conn, skb);
7104 break;
7105
Anderson Brigliab501d6a2011-06-07 18:46:31 -03007106 case L2CAP_CID_SMP:
7107 if (smp_sig_channel(conn, skb))
7108 l2cap_conn_del(conn->hcon, EACCES);
7109 break;
7110
Linus Torvalds1da177e2005-04-16 15:20:36 -07007111 default:
7112 l2cap_data_channel(conn, cid, skb);
7113 break;
7114 }
7115}
7116
7117/* ---- L2CAP interface with lower layer (HCI) ---- */
7118
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007119int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007120{
7121 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007122 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007123
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03007124 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007125
7126 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007127 read_lock(&chan_list_lock);
7128 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007129 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007130 continue;
7131
Marcel Holtmann7eafc592013-10-13 08:12:47 -07007132 if (!bacmp(&c->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007133 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03007134 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007135 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007136 exact++;
Marcel Holtmann7eafc592013-10-13 08:12:47 -07007137 } else if (!bacmp(&c->src, BDADDR_ANY)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007138 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03007139 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007140 lm2 |= HCI_LM_MASTER;
7141 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007142 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007143 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007144
7145 return exact ? lm1 : lm2;
7146}
7147
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03007148void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007149{
Marcel Holtmann01394182006-07-03 10:02:46 +02007150 struct l2cap_conn *conn;
7151
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03007152 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007153
Linus Torvalds1da177e2005-04-16 15:20:36 -07007154 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03007155 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007156 if (conn)
7157 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02007158 } else {
Joe Perchese1750722011-06-29 18:18:29 -07007159 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02007160 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007161}
7162
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007163int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01007164{
7165 struct l2cap_conn *conn = hcon->l2cap_data;
7166
7167 BT_DBG("hcon %p", hcon);
7168
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007169 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02007170 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01007171 return conn->disc_reason;
7172}
7173
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03007174void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007175{
7176 BT_DBG("hcon %p reason %d", hcon, reason);
7177
Joe Perchese1750722011-06-29 18:18:29 -07007178 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007179}
7180
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007181static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007182{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03007183 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01007184 return;
7185
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007186 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007187 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007188 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007189 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03007190 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007191 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007192 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03007193 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007194 }
7195}
7196
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007197int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007198{
Marcel Holtmann40be4922008-07-14 20:13:50 +02007199 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03007200 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007201
Marcel Holtmann01394182006-07-03 10:02:46 +02007202 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007203 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02007204
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03007205 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007206
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03007207 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05307208 if (!status && encrypt)
7209 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02007210 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03007211 }
7212
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007213 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007214
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007215 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007216 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007217
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03007218 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
7219 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007220
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03007221 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
7222 l2cap_chan_unlock(chan);
7223 continue;
7224 }
7225
Johan Hedberg073d1cf2013-04-29 19:35:35 +03007226 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007227 if (!status && encrypt) {
7228 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02007229 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007230 }
7231
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007232 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007233 continue;
7234 }
7235
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02007236 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007237 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01007238 continue;
7239 }
7240
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007241 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01007242 chan->state == BT_CONFIG)) {
Marcel Holtmannd97c8992013-10-14 02:53:54 -07007243 chan->ops->resume(chan);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007244 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007245 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02007246 continue;
7247 }
7248
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007249 if (chan->state == BT_CONNECT) {
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02007250 if (!status)
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03007251 l2cap_start_connection(chan);
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02007252 else
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007253 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007254 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007255 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007256 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007257
7258 if (!status) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07007259 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007260 res = L2CAP_CR_PEND;
7261 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08007262 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007263 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02007264 l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007265 res = L2CAP_CR_SUCCESS;
7266 stat = L2CAP_CS_NO_INFO;
7267 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007268 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02007269 l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007270 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007271 res = L2CAP_CR_SEC_BLOCK;
7272 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007273 }
7274
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03007275 rsp.scid = cpu_to_le16(chan->dcid);
7276 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007277 rsp.result = cpu_to_le16(res);
7278 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03007279 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01007280 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07007281
7282 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
7283 res == L2CAP_CR_SUCCESS) {
7284 char buf[128];
7285 set_bit(CONF_REQ_SENT, &chan->conf_state);
7286 l2cap_send_cmd(conn, l2cap_get_ident(conn),
7287 L2CAP_CONF_REQ,
7288 l2cap_build_conf_req(chan, buf),
7289 buf);
7290 chan->num_conf_req++;
7291 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007292 }
7293
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007294 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007295 }
7296
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007297 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007298
Linus Torvalds1da177e2005-04-16 15:20:36 -07007299 return 0;
7300}
7301
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007302int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007303{
7304 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007305 struct l2cap_hdr *hdr;
7306 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007307
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03007308 /* For AMP controller do not create l2cap conn */
7309 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
7310 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007311
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02007312 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03007313 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02007314
7315 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007316 goto drop;
7317
7318 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
7319
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007320 switch (flags) {
7321 case ACL_START:
7322 case ACL_START_NO_FLUSH:
7323 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007324 if (conn->rx_len) {
7325 BT_ERR("Unexpected start frame (len %d)", skb->len);
7326 kfree_skb(conn->rx_skb);
7327 conn->rx_skb = NULL;
7328 conn->rx_len = 0;
7329 l2cap_conn_unreliable(conn, ECOMM);
7330 }
7331
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03007332 /* Start fragment always begin with Basic L2CAP header */
7333 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007334 BT_ERR("Frame is too short (len %d)", skb->len);
7335 l2cap_conn_unreliable(conn, ECOMM);
7336 goto drop;
7337 }
7338
7339 hdr = (struct l2cap_hdr *) skb->data;
7340 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
7341
7342 if (len == skb->len) {
7343 /* Complete frame received */
7344 l2cap_recv_frame(conn, skb);
7345 return 0;
7346 }
7347
7348 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
7349
7350 if (skb->len > len) {
7351 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007352 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007353 l2cap_conn_unreliable(conn, ECOMM);
7354 goto drop;
7355 }
7356
7357 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03007358 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03007359 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007360 goto drop;
7361
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007362 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007363 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007364 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007365 break;
7366
7367 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007368 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
7369
7370 if (!conn->rx_len) {
7371 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
7372 l2cap_conn_unreliable(conn, ECOMM);
7373 goto drop;
7374 }
7375
7376 if (skb->len > conn->rx_len) {
7377 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007378 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007379 kfree_skb(conn->rx_skb);
7380 conn->rx_skb = NULL;
7381 conn->rx_len = 0;
7382 l2cap_conn_unreliable(conn, ECOMM);
7383 goto drop;
7384 }
7385
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007386 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007387 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007388 conn->rx_len -= skb->len;
7389
7390 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007391 /* Complete frame received. l2cap_recv_frame
7392 * takes ownership of the skb so set the global
7393 * rx_skb pointer to NULL first.
7394 */
7395 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007396 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007397 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007398 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007399 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007400 }
7401
7402drop:
7403 kfree_skb(skb);
7404 return 0;
7405}
7406
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007407static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007408{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007409 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007410
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007411 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007412
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007413 list_for_each_entry(c, &chan_list, global_l) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007414 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 -07007415 &c->src, &c->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007416 c->state, __le16_to_cpu(c->psm),
7417 c->scid, c->dcid, c->imtu, c->omtu,
7418 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02007419 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007420
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007421 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007422
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007423 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007424}
7425
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007426static int l2cap_debugfs_open(struct inode *inode, struct file *file)
7427{
7428 return single_open(file, l2cap_debugfs_show, inode->i_private);
7429}
7430
7431static const struct file_operations l2cap_debugfs_fops = {
7432 .open = l2cap_debugfs_open,
7433 .read = seq_read,
7434 .llseek = seq_lseek,
7435 .release = single_release,
7436};
7437
7438static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007439
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007440int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007441{
7442 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007443
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007444 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007445 if (err < 0)
7446 return err;
7447
Marcel Holtmann1120e4b2013-10-17 17:24:16 -07007448 if (IS_ERR_OR_NULL(bt_debugfs))
7449 return 0;
7450
7451 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
7452 NULL, &l2cap_debugfs_fops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007453
Johan Hedbergf15b8ec2013-12-03 15:08:25 +02007454 debugfs_create_u16("l2cap_le_max_credits", 0466, bt_debugfs,
7455 &le_max_credits);
7456 debugfs_create_u16("l2cap_le_default_mps", 0466, bt_debugfs,
7457 &le_default_mps);
7458
Linus Torvalds1da177e2005-04-16 15:20:36 -07007459 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007460}
7461
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007462void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007463{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007464 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007465 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007466}
7467
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03007468module_param(disable_ertm, bool, 0644);
7469MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");