blob: 4af3821df880f70dd17cd36161eff766c3e49334 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
Gustavo F. Padovance5706b2010-07-13 11:57:11 -03004 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
Gustavo F. Padovan5d8868f2010-07-16 16:18:39 -03005 Copyright (C) 2010 Google Inc.
Gustavo F. Padovan590051d2011-12-18 13:39:33 -02006 Copyright (C) 2011 ProFUSION Embedded Systems
Mat Martineau422e9252012-04-27 16:50:55 -07007 Copyright (c) 2012 Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07008
9 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License version 2 as
13 published by the Free Software Foundation;
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
18 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090019 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090024 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
25 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 SOFTWARE IS DISCLAIMED.
27*/
28
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020029/* Bluetooth L2CAP core. */
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/module.h>
32
Marcel Holtmannaef7d972010-03-21 05:27:45 +010033#include <linux/debugfs.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030034#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#include <net/bluetooth/bluetooth.h>
37#include <net/bluetooth/hci_core.h>
38#include <net/bluetooth/l2cap.h>
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070039
Marcel Holtmannac4b7232013-10-10 14:54:16 -070040#include "smp.h"
Marcel Holtmann70247282013-10-10 14:54:15 -070041#include "a2mp.h"
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070042#include "amp.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
Mat Martineaud1de6d42012-05-17 20:53:55 -070044bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020045
Marcel Holtmann547d1032013-10-12 08:18:19 -070046static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN | L2CAP_FEAT_UCD;
Marcel Holtmannd40bffb2013-10-12 08:18:18 -070047static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP | L2CAP_FC_CONNLESS, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Johannes Bergb5ad8b72011-06-01 08:54:45 +020049static LIST_HEAD(chan_list);
50static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Linus Torvalds1da177e2005-04-16 15:20:36 -070052static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010053 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030054static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010055 void *data);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -030056static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +020057static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
Gustavo Padovand6603662012-05-21 13:58:22 -030059static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010060 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070061
Marcel Holtmann4f1654e2013-10-13 08:50:41 -070062static inline __u8 bdaddr_type(struct hci_conn *hcon, __u8 type)
63{
64 if (hcon->type == LE_LINK) {
65 if (type == ADDR_LE_DEV_PUBLIC)
66 return BDADDR_LE_PUBLIC;
67 else
68 return BDADDR_LE_RANDOM;
69 }
70
71 return BDADDR_BREDR;
72}
73
Marcel Holtmann01394182006-07-03 10:02:46 +020074/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030075
Gustavo Padovan2d792812012-10-06 10:07:01 +010076static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
77 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020078{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020079 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030080
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020081 list_for_each_entry(c, &conn->chan_l, list) {
82 if (c->dcid == cid)
83 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020084 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020085 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020086}
87
Gustavo Padovan2d792812012-10-06 10:07:01 +010088static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
89 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020090{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020091 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030092
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020093 list_for_each_entry(c, &conn->chan_l, list) {
94 if (c->scid == cid)
95 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020096 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020097 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020098}
99
100/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -0700101 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +0100102static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
103 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +0200104{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300105 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300106
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200107 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300108 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -0700109 if (c)
110 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200111 mutex_unlock(&conn->chan_lock);
112
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300113 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200114}
115
Mat Martineaub1a130b2012-10-23 15:24:09 -0700116/* Find channel with given DCID.
117 * Returns locked channel.
118 */
119static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
120 u16 cid)
121{
122 struct l2cap_chan *c;
123
124 mutex_lock(&conn->chan_lock);
125 c = __l2cap_get_chan_by_dcid(conn, cid);
126 if (c)
127 l2cap_chan_lock(c);
128 mutex_unlock(&conn->chan_lock);
129
130 return c;
131}
132
Gustavo Padovan2d792812012-10-06 10:07:01 +0100133static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
134 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200135{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200136 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300137
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200138 list_for_each_entry(c, &conn->chan_l, list) {
139 if (c->ident == ident)
140 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200141 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200142 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200143}
144
Mat Martineau5b155ef2012-10-23 15:24:14 -0700145static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
146 u8 ident)
147{
148 struct l2cap_chan *c;
149
150 mutex_lock(&conn->chan_lock);
151 c = __l2cap_get_chan_by_ident(conn, ident);
152 if (c)
153 l2cap_chan_lock(c);
154 mutex_unlock(&conn->chan_lock);
155
156 return c;
157}
158
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300159static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300160{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300161 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300162
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300163 list_for_each_entry(c, &chan_list, global_l) {
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700164 if (c->sport == psm && !bacmp(&c->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100165 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300166 }
Szymon Janc250938c2011-11-16 09:32:22 +0100167 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300168}
169
170int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
171{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300172 int err;
173
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200174 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300175
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300176 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300177 err = -EADDRINUSE;
178 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300179 }
180
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300181 if (psm) {
182 chan->psm = psm;
183 chan->sport = psm;
184 err = 0;
185 } else {
186 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300187
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300188 err = -EINVAL;
189 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300190 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300191 chan->psm = cpu_to_le16(p);
192 chan->sport = cpu_to_le16(p);
193 err = 0;
194 break;
195 }
196 }
197
198done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200199 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300200 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300201}
202
203int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
204{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200205 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300206
207 chan->scid = scid;
208
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200209 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300210
211 return 0;
212}
213
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300214static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200215{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300216 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200217
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300218 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300219 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200220 return cid;
221 }
222
223 return 0;
224}
225
Gustavo Padovanf93fa272013-10-21 14:21:40 -0200226static void l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300227{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200228 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100229 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200230
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300231 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300232 chan->ops->state_change(chan, state, 0);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300233}
234
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300235static inline void l2cap_state_change_and_error(struct l2cap_chan *chan,
236 int state, int err)
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200237{
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300238 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300239 chan->ops->state_change(chan, chan->state, err);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200240}
241
242static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
243{
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300244 chan->ops->state_change(chan, chan->state, err);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200245}
246
Mat Martineau4239d162012-05-17 20:53:49 -0700247static void __set_retrans_timer(struct l2cap_chan *chan)
248{
249 if (!delayed_work_pending(&chan->monitor_timer) &&
250 chan->retrans_timeout) {
251 l2cap_set_timer(chan, &chan->retrans_timer,
252 msecs_to_jiffies(chan->retrans_timeout));
253 }
254}
255
256static void __set_monitor_timer(struct l2cap_chan *chan)
257{
258 __clear_retrans_timer(chan);
259 if (chan->monitor_timeout) {
260 l2cap_set_timer(chan, &chan->monitor_timer,
261 msecs_to_jiffies(chan->monitor_timeout));
262 }
263}
264
Mat Martineau608bcc62012-05-17 20:53:32 -0700265static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
266 u16 seq)
267{
268 struct sk_buff *skb;
269
270 skb_queue_walk(head, skb) {
271 if (bt_cb(skb)->control.txseq == seq)
272 return skb;
273 }
274
275 return NULL;
276}
277
Mat Martineau3c588192012-04-11 10:48:42 -0700278/* ---- L2CAP sequence number lists ---- */
279
280/* For ERTM, ordered lists of sequence numbers must be tracked for
281 * SREJ requests that are received and for frames that are to be
282 * retransmitted. These seq_list functions implement a singly-linked
283 * list in an array, where membership in the list can also be checked
284 * in constant time. Items can also be added to the tail of the list
285 * and removed from the head in constant time, without further memory
286 * allocs or frees.
287 */
288
289static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
290{
291 size_t alloc_size, i;
292
293 /* Allocated size is a power of 2 to map sequence numbers
294 * (which may be up to 14 bits) in to a smaller array that is
295 * sized for the negotiated ERTM transmit windows.
296 */
297 alloc_size = roundup_pow_of_two(size);
298
299 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
300 if (!seq_list->list)
301 return -ENOMEM;
302
303 seq_list->mask = alloc_size - 1;
304 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
305 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
306 for (i = 0; i < alloc_size; i++)
307 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
308
309 return 0;
310}
311
312static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
313{
314 kfree(seq_list->list);
315}
316
317static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
318 u16 seq)
319{
320 /* Constant-time check for list membership */
321 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
322}
323
324static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
325{
326 u16 mask = seq_list->mask;
327
328 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
329 /* In case someone tries to pop the head of an empty list */
330 return L2CAP_SEQ_LIST_CLEAR;
331 } else if (seq_list->head == seq) {
332 /* Head can be removed in constant time */
333 seq_list->head = seq_list->list[seq & mask];
334 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
335
336 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
337 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
338 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
339 }
340 } else {
341 /* Walk the list to find the sequence number */
342 u16 prev = seq_list->head;
343 while (seq_list->list[prev & mask] != seq) {
344 prev = seq_list->list[prev & mask];
345 if (prev == L2CAP_SEQ_LIST_TAIL)
346 return L2CAP_SEQ_LIST_CLEAR;
347 }
348
349 /* Unlink the number from the list and clear it */
350 seq_list->list[prev & mask] = seq_list->list[seq & mask];
351 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
352 if (seq_list->tail == seq)
353 seq_list->tail = prev;
354 }
355 return seq;
356}
357
358static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
359{
360 /* Remove the head in constant time */
361 return l2cap_seq_list_remove(seq_list, seq_list->head);
362}
363
364static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
365{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300366 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700367
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300368 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
369 return;
370
371 for (i = 0; i <= seq_list->mask; i++)
372 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
373
374 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
375 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700376}
377
378static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
379{
380 u16 mask = seq_list->mask;
381
382 /* All appends happen in constant time */
383
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300384 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
385 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700386
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300387 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
388 seq_list->head = seq;
389 else
390 seq_list->list[seq_list->tail & mask] = seq;
391
392 seq_list->tail = seq;
393 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700394}
395
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300396static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300397{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300398 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100399 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200400 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300401 int reason;
402
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200403 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300404
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200405 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200406 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300407
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300408 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300409 reason = ECONNREFUSED;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300410 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100411 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300412 reason = ECONNREFUSED;
413 else
414 reason = ETIMEDOUT;
415
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300416 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300417
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200418 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300419
Gustavo Padovan80b98022012-05-27 22:27:51 -0300420 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200421 mutex_unlock(&conn->chan_lock);
422
Ulisses Furquim371fd832011-12-21 20:02:36 -0200423 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300424}
425
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300426struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200427{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300428 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200429
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300430 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
431 if (!chan)
432 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200433
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200434 mutex_init(&chan->lock);
435
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200436 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300437 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200438 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300439
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300440 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300441
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300442 chan->state = BT_OPEN;
443
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530444 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300445
Mat Martineau28270112012-05-17 21:14:09 -0700446 /* This flag is cleared in l2cap_chan_ready() */
447 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
448
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300449 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100450
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300451 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200452}
453
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530454static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300455{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530456 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
457
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530458 BT_DBG("chan %p", chan);
459
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200460 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300461 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200462 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300463
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530464 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300465}
466
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530467void l2cap_chan_hold(struct l2cap_chan *c)
468{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530469 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530470
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530471 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530472}
473
474void l2cap_chan_put(struct l2cap_chan *c)
475{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530476 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530477
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530478 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530479}
480
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300481void l2cap_chan_set_defaults(struct l2cap_chan *chan)
482{
483 chan->fcs = L2CAP_FCS_CRC16;
484 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
485 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
486 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700487 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300488 chan->sec_level = BT_SECURITY_LOW;
489
490 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
491}
492
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300493void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200494{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300495 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200496 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200497
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200498 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100499
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300500 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200501
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200502 switch (chan->chan_type) {
503 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300504 if (conn->hcon->type == LE_LINK) {
505 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300506 chan->omtu = L2CAP_DEFAULT_MTU;
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300507 if (chan->dcid == L2CAP_CID_ATT)
508 chan->scid = L2CAP_CID_ATT;
509 else
510 chan->scid = l2cap_alloc_cid(conn);
Ville Tervob62f3282011-02-10 22:38:50 -0300511 } else {
512 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300513 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300514 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300515 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200516 break;
517
518 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200519 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300520 chan->scid = L2CAP_CID_CONN_LESS;
521 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300522 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200523 break;
524
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300525 case L2CAP_CHAN_CONN_FIX_A2MP:
526 chan->scid = L2CAP_CID_A2MP;
527 chan->dcid = L2CAP_CID_A2MP;
528 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
529 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
530 break;
531
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200532 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200533 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300534 chan->scid = L2CAP_CID_SIGNALING;
535 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300536 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200537 }
538
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300539 chan->local_id = L2CAP_BESTEFFORT_ID;
540 chan->local_stype = L2CAP_SERV_BESTEFFORT;
541 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
542 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
543 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300544 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300545
Ulisses Furquim371fd832011-12-21 20:02:36 -0200546 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300547
Johan Hedberg5ee98912013-04-29 19:35:43 +0300548 hci_conn_hold(conn->hcon);
549
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200550 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200551}
552
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300553void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200554{
555 mutex_lock(&conn->chan_lock);
556 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200557 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200558}
559
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300560void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200561{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300562 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200563
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300564 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200565
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300566 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200567
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900568 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300569 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300570 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200571 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200572
Ulisses Furquim371fd832011-12-21 20:02:36 -0200573 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300574
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300575 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300576
577 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200578 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300579
580 if (mgr && mgr->bredr_chan == chan)
581 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200582 }
583
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200584 if (chan->hs_hchan) {
585 struct hci_chan *hs_hchan = chan->hs_hchan;
586
587 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
588 amp_disconnect_logical_link(hs_hchan);
589 }
590
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100591 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200592
Mat Martineau28270112012-05-17 21:14:09 -0700593 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300594 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300595
Gustavo Padovanee556f62012-05-18 20:22:38 -0300596 switch(chan->mode) {
597 case L2CAP_MODE_BASIC:
598 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300599
Gustavo Padovanee556f62012-05-18 20:22:38 -0300600 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300601 __clear_retrans_timer(chan);
602 __clear_monitor_timer(chan);
603 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300604
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300605 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300606
Mat Martineau3c588192012-04-11 10:48:42 -0700607 l2cap_seq_list_free(&chan->srej_list);
608 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300609
610 /* fall through */
611
612 case L2CAP_MODE_STREAMING:
613 skb_queue_purge(&chan->tx_q);
614 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300615 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300616
617 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200618}
619
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300620void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300621{
622 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300623
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700624 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300625
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300626 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300627 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100628 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300629 break;
630
631 case BT_CONNECTED:
632 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300633 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100634 conn->hcon->type == ACL_LINK) {
Gustavo Padovan8d836d72013-10-15 19:24:47 -0300635 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200636 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300637 } else
638 l2cap_chan_del(chan, reason);
639 break;
640
641 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300642 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100643 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300644 struct l2cap_conn_rsp rsp;
645 __u16 result;
646
Marcel Holtmannbdc25782013-10-14 02:45:34 -0700647 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300648 result = L2CAP_CR_SEC_BLOCK;
649 else
650 result = L2CAP_CR_BAD_PSM;
Marcel Holtmannbdc25782013-10-14 02:45:34 -0700651
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300652 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300653
654 rsp.scid = cpu_to_le16(chan->dcid);
655 rsp.dcid = cpu_to_le16(chan->scid);
656 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300657 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300658 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100659 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300660 }
661
662 l2cap_chan_del(chan, reason);
663 break;
664
665 case BT_CONNECT:
666 case BT_DISCONN:
667 l2cap_chan_del(chan, reason);
668 break;
669
670 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100671 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300672 break;
673 }
674}
675
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300676static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530677{
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700678 switch (chan->chan_type) {
679 case L2CAP_CHAN_RAW:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300680 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530681 case BT_SECURITY_HIGH:
682 return HCI_AT_DEDICATED_BONDING_MITM;
683 case BT_SECURITY_MEDIUM:
684 return HCI_AT_DEDICATED_BONDING;
685 default:
686 return HCI_AT_NO_BONDING;
687 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700688 break;
Marcel Holtmann3124b842013-10-12 07:19:32 -0700689 case L2CAP_CHAN_CONN_LESS:
690 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_3DSP)) {
691 if (chan->sec_level == BT_SECURITY_LOW)
692 chan->sec_level = BT_SECURITY_SDP;
693 }
694 if (chan->sec_level == BT_SECURITY_HIGH)
695 return HCI_AT_NO_BONDING_MITM;
696 else
697 return HCI_AT_NO_BONDING;
698 break;
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700699 case L2CAP_CHAN_CONN_ORIENTED:
700 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
701 if (chan->sec_level == BT_SECURITY_LOW)
702 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530703
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700704 if (chan->sec_level == BT_SECURITY_HIGH)
705 return HCI_AT_NO_BONDING_MITM;
706 else
707 return HCI_AT_NO_BONDING;
708 }
709 /* fall through */
710 default:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300711 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530712 case BT_SECURITY_HIGH:
713 return HCI_AT_GENERAL_BONDING_MITM;
714 case BT_SECURITY_MEDIUM:
715 return HCI_AT_GENERAL_BONDING;
716 default:
717 return HCI_AT_NO_BONDING;
718 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700719 break;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530720 }
721}
722
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200723/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200724int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200725{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300726 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100727 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200728
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300729 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100730
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300731 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200732}
733
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200734static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200735{
736 u8 id;
737
738 /* Get next available identificator.
739 * 1 - 128 are used by kernel.
740 * 129 - 199 are reserved.
741 * 200 - 254 are used by utilities like l2ping, etc.
742 */
743
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200744 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200745
746 if (++conn->tx_ident > 128)
747 conn->tx_ident = 1;
748
749 id = conn->tx_ident;
750
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200751 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200752
753 return id;
754}
755
Gustavo Padovan2d792812012-10-06 10:07:01 +0100756static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
757 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200758{
759 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200760 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200761
762 BT_DBG("code 0x%2.2x", code);
763
764 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300765 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200766
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200767 if (lmp_no_flush_capable(conn->hcon->hdev))
768 flags = ACL_START_NO_FLUSH;
769 else
770 flags = ACL_START;
771
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700772 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200773 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700774
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200775 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200776}
777
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700778static bool __chan_is_moving(struct l2cap_chan *chan)
779{
780 return chan->move_state != L2CAP_MOVE_STABLE &&
781 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
782}
783
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200784static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
785{
786 struct hci_conn *hcon = chan->conn->hcon;
787 u16 flags;
788
789 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100790 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200791
Mat Martineaud5f8a752012-10-23 15:24:18 -0700792 if (chan->hs_hcon && !__chan_is_moving(chan)) {
793 if (chan->hs_hchan)
794 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
795 else
796 kfree_skb(skb);
797
798 return;
799 }
800
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200801 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100802 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200803 flags = ACL_START_NO_FLUSH;
804 else
805 flags = ACL_START;
806
807 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
808 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809}
810
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700811static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
812{
813 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
814 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
815
816 if (enh & L2CAP_CTRL_FRAME_TYPE) {
817 /* S-Frame */
818 control->sframe = 1;
819 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
820 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
821
822 control->sar = 0;
823 control->txseq = 0;
824 } else {
825 /* I-Frame */
826 control->sframe = 0;
827 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
828 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
829
830 control->poll = 0;
831 control->super = 0;
832 }
833}
834
835static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
836{
837 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
838 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
839
840 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
841 /* S-Frame */
842 control->sframe = 1;
843 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
844 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
845
846 control->sar = 0;
847 control->txseq = 0;
848 } else {
849 /* I-Frame */
850 control->sframe = 0;
851 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
852 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
853
854 control->poll = 0;
855 control->super = 0;
856 }
857}
858
859static inline void __unpack_control(struct l2cap_chan *chan,
860 struct sk_buff *skb)
861{
862 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
863 __unpack_extended_control(get_unaligned_le32(skb->data),
864 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700865 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700866 } else {
867 __unpack_enhanced_control(get_unaligned_le16(skb->data),
868 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700869 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700870 }
871}
872
873static u32 __pack_extended_control(struct l2cap_ctrl *control)
874{
875 u32 packed;
876
877 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
878 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
879
880 if (control->sframe) {
881 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
882 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
883 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
884 } else {
885 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
886 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
887 }
888
889 return packed;
890}
891
892static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
893{
894 u16 packed;
895
896 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
897 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
898
899 if (control->sframe) {
900 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
901 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
902 packed |= L2CAP_CTRL_FRAME_TYPE;
903 } else {
904 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
905 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
906 }
907
908 return packed;
909}
910
911static inline void __pack_control(struct l2cap_chan *chan,
912 struct l2cap_ctrl *control,
913 struct sk_buff *skb)
914{
915 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
916 put_unaligned_le32(__pack_extended_control(control),
917 skb->data + L2CAP_HDR_SIZE);
918 } else {
919 put_unaligned_le16(__pack_enhanced_control(control),
920 skb->data + L2CAP_HDR_SIZE);
921 }
922}
923
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300924static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
925{
926 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
927 return L2CAP_EXT_HDR_SIZE;
928 else
929 return L2CAP_ENH_HDR_SIZE;
930}
931
Mat Martineaua67d7f62012-05-17 20:53:35 -0700932static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
933 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300934{
935 struct sk_buff *skb;
936 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300937 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300938
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300939 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300940 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300941
Mat Martineaua67d7f62012-05-17 20:53:35 -0700942 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300943
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300944 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700945 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300946
947 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300948 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300949 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300950
Mat Martineaua67d7f62012-05-17 20:53:35 -0700951 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
952 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
953 else
954 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300955
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300956 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700957 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300958 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300959 }
960
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200961 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700962 return skb;
963}
964
965static void l2cap_send_sframe(struct l2cap_chan *chan,
966 struct l2cap_ctrl *control)
967{
968 struct sk_buff *skb;
969 u32 control_field;
970
971 BT_DBG("chan %p, control %p", chan, control);
972
973 if (!control->sframe)
974 return;
975
Mat Martineaub99e13a2012-10-23 15:24:19 -0700976 if (__chan_is_moving(chan))
977 return;
978
Mat Martineaua67d7f62012-05-17 20:53:35 -0700979 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
980 !control->poll)
981 control->final = 1;
982
983 if (control->super == L2CAP_SUPER_RR)
984 clear_bit(CONN_RNR_SENT, &chan->conn_state);
985 else if (control->super == L2CAP_SUPER_RNR)
986 set_bit(CONN_RNR_SENT, &chan->conn_state);
987
988 if (control->super != L2CAP_SUPER_SREJ) {
989 chan->last_acked_seq = control->reqseq;
990 __clear_ack_timer(chan);
991 }
992
993 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
994 control->final, control->poll, control->super);
995
996 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
997 control_field = __pack_extended_control(control);
998 else
999 control_field = __pack_enhanced_control(control);
1000
1001 skb = l2cap_create_sframe_pdu(chan, control_field);
1002 if (!IS_ERR(skb))
1003 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001004}
1005
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001006static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001007{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001008 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001009
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001010 BT_DBG("chan %p, poll %d", chan, poll);
1011
1012 memset(&control, 0, sizeof(control));
1013 control.sframe = 1;
1014 control.poll = poll;
1015
1016 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1017 control.super = L2CAP_SUPER_RNR;
1018 else
1019 control.super = L2CAP_SUPER_RR;
1020
1021 control.reqseq = chan->buffer_seq;
1022 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001023}
1024
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001025static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001026{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001027 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001028}
1029
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001030static bool __amp_capable(struct l2cap_chan *chan)
1031{
1032 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001033 struct hci_dev *hdev;
1034 bool amp_available = false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001035
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001036 if (!conn->hs_enabled)
1037 return false;
1038
1039 if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
1040 return false;
1041
1042 read_lock(&hci_dev_list_lock);
1043 list_for_each_entry(hdev, &hci_dev_list, list) {
1044 if (hdev->amp_type != AMP_TYPE_BREDR &&
1045 test_bit(HCI_UP, &hdev->flags)) {
1046 amp_available = true;
1047 break;
1048 }
1049 }
1050 read_unlock(&hci_dev_list_lock);
1051
1052 if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED)
1053 return amp_available;
Marcel Holtmann848566b2013-10-01 22:59:22 -07001054
1055 return false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001056}
1057
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001058static bool l2cap_check_efs(struct l2cap_chan *chan)
1059{
1060 /* Check EFS parameters */
1061 return true;
1062}
1063
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001064void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001065{
1066 struct l2cap_conn *conn = chan->conn;
1067 struct l2cap_conn_req req;
1068
1069 req.scid = cpu_to_le16(chan->scid);
1070 req.psm = chan->psm;
1071
1072 chan->ident = l2cap_get_ident(conn);
1073
1074 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1075
1076 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1077}
1078
Mat Martineau8eb200b2012-10-23 15:24:17 -07001079static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1080{
1081 struct l2cap_create_chan_req req;
1082 req.scid = cpu_to_le16(chan->scid);
1083 req.psm = chan->psm;
1084 req.amp_id = amp_id;
1085
1086 chan->ident = l2cap_get_ident(chan->conn);
1087
1088 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1089 sizeof(req), &req);
1090}
1091
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001092static void l2cap_move_setup(struct l2cap_chan *chan)
1093{
1094 struct sk_buff *skb;
1095
1096 BT_DBG("chan %p", chan);
1097
1098 if (chan->mode != L2CAP_MODE_ERTM)
1099 return;
1100
1101 __clear_retrans_timer(chan);
1102 __clear_monitor_timer(chan);
1103 __clear_ack_timer(chan);
1104
1105 chan->retry_count = 0;
1106 skb_queue_walk(&chan->tx_q, skb) {
1107 if (bt_cb(skb)->control.retries)
1108 bt_cb(skb)->control.retries = 1;
1109 else
1110 break;
1111 }
1112
1113 chan->expected_tx_seq = chan->buffer_seq;
1114
1115 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1116 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1117 l2cap_seq_list_clear(&chan->retrans_list);
1118 l2cap_seq_list_clear(&chan->srej_list);
1119 skb_queue_purge(&chan->srej_q);
1120
1121 chan->tx_state = L2CAP_TX_STATE_XMIT;
1122 chan->rx_state = L2CAP_RX_STATE_MOVE;
1123
1124 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1125}
1126
Mat Martineau5f3847a2012-10-23 15:24:12 -07001127static void l2cap_move_done(struct l2cap_chan *chan)
1128{
1129 u8 move_role = chan->move_role;
1130 BT_DBG("chan %p", chan);
1131
1132 chan->move_state = L2CAP_MOVE_STABLE;
1133 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1134
1135 if (chan->mode != L2CAP_MODE_ERTM)
1136 return;
1137
1138 switch (move_role) {
1139 case L2CAP_MOVE_ROLE_INITIATOR:
1140 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1141 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1142 break;
1143 case L2CAP_MOVE_ROLE_RESPONDER:
1144 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1145 break;
1146 }
1147}
1148
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001149static void l2cap_chan_ready(struct l2cap_chan *chan)
1150{
Mat Martineau28270112012-05-17 21:14:09 -07001151 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001152 chan->conf_state = 0;
1153 __clear_chan_timer(chan);
1154
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001155 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001156
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001157 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001158}
1159
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001160static void l2cap_start_connection(struct l2cap_chan *chan)
1161{
1162 if (__amp_capable(chan)) {
1163 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1164 a2mp_discover_amp(chan);
1165 } else {
1166 l2cap_send_conn_req(chan);
1167 }
1168}
1169
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001170static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001171{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001172 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001173
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001174 if (conn->hcon->type == LE_LINK) {
1175 l2cap_chan_ready(chan);
1176 return;
1177 }
1178
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001179 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001180 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1181 return;
1182
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001183 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001184 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001185 l2cap_start_connection(chan);
1186 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001187 } else {
1188 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001189 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001190
1191 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1192 conn->info_ident = l2cap_get_ident(conn);
1193
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001194 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001195
Gustavo Padovan2d792812012-10-06 10:07:01 +01001196 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1197 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001198 }
1199}
1200
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001201static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1202{
1203 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001204 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001205 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1206
1207 switch (mode) {
1208 case L2CAP_MODE_ERTM:
1209 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1210 case L2CAP_MODE_STREAMING:
1211 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1212 default:
1213 return 0x00;
1214 }
1215}
1216
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001217static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001218{
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001219 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001220 struct l2cap_disconn_req req;
1221
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001222 if (!conn)
1223 return;
1224
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001225 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001226 __clear_retrans_timer(chan);
1227 __clear_monitor_timer(chan);
1228 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001229 }
1230
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001231 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001232 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001233 return;
1234 }
1235
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001236 req.dcid = cpu_to_le16(chan->dcid);
1237 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001238 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1239 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001240
Gustavo Padovanf8e73012013-10-15 19:24:46 -03001241 l2cap_state_change_and_error(chan, BT_DISCONN, err);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001242}
1243
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001245static void l2cap_conn_start(struct l2cap_conn *conn)
1246{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001247 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001248
1249 BT_DBG("conn %p", conn);
1250
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001251 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001252
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001253 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001254 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001255
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001256 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001257 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001258 continue;
1259 }
1260
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001261 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001262 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001263 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001264 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001265 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001266 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001267
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001268 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001269 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001270 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001271 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001272 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001273 continue;
1274 }
1275
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001276 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001277
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001278 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001279 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001280 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001281 rsp.scid = cpu_to_le16(chan->dcid);
1282 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001283
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001284 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07001285 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001286 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1287 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001288 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001289
1290 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02001291 l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001292 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1293 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001294 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001295 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001296 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1297 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001298 }
1299
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001300 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001301 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001302
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001303 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001304 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001305 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001306 continue;
1307 }
1308
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001309 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001310 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001311 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001312 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001313 }
1314
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001315 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001316 }
1317
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001318 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001319}
1320
Ido Yarivc2287682012-04-20 15:46:07 -03001321/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001322 * Returns closest match, locked.
1323 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001324static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001325 bdaddr_t *src,
1326 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001327{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001328 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001329
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001330 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001331
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001332 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001333 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001334 continue;
1335
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001336 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001337 int src_match, dst_match;
1338 int src_any, dst_any;
1339
Ville Tervob62f3282011-02-10 22:38:50 -03001340 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001341 src_match = !bacmp(&c->src, src);
1342 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001343 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001344 read_unlock(&chan_list_lock);
1345 return c;
1346 }
Ville Tervob62f3282011-02-10 22:38:50 -03001347
1348 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001349 src_any = !bacmp(&c->src, BDADDR_ANY);
1350 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001351 if ((src_match && dst_any) || (src_any && dst_match) ||
1352 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001353 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001354 }
1355 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001356
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001357 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001358
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001359 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001360}
1361
1362static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1363{
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001364 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001365 struct l2cap_chan *chan, *pchan;
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001366 u8 dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001367
1368 BT_DBG("");
1369
1370 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001371 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001372 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001373 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001374 return;
1375
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001376 /* Client ATT sockets should override the server one */
1377 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1378 return;
1379
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001380 dst_type = bdaddr_type(hcon, hcon->dst_type);
1381
1382 /* If device is blocked, do not create a channel for it */
1383 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, dst_type))
1384 return;
1385
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001386 l2cap_chan_lock(pchan);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001387
Gustavo Padovan80b98022012-05-27 22:27:51 -03001388 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001389 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001390 goto clean;
1391
Johan Hedberg9f22398c2013-04-29 19:35:38 +03001392 chan->dcid = L2CAP_CID_ATT;
1393
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001394 bacpy(&chan->src, &hcon->src);
1395 bacpy(&chan->dst, &hcon->dst);
1396 chan->src_type = bdaddr_type(hcon, hcon->src_type);
1397 chan->dst_type = dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001398
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001399 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001400
Ville Tervob62f3282011-02-10 22:38:50 -03001401clean:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001402 l2cap_chan_unlock(pchan);
Ville Tervob62f3282011-02-10 22:38:50 -03001403}
1404
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001405static void l2cap_conn_ready(struct l2cap_conn *conn)
1406{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001407 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001408 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001409
1410 BT_DBG("conn %p", conn);
1411
Johan Hedbergd8729922013-04-29 19:35:39 +03001412 /* For outgoing pairing which doesn't necessarily have an
1413 * associated socket (e.g. mgmt_pair_device).
1414 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001415 if (hcon->out && hcon->type == LE_LINK)
1416 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001417
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001418 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001419
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001420 if (hcon->type == LE_LINK)
1421 l2cap_le_conn_ready(conn);
1422
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001423 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001424
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001425 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001426
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001427 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1428 l2cap_chan_unlock(chan);
1429 continue;
1430 }
1431
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001432 if (hcon->type == LE_LINK) {
1433 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001434 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001435
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001436 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo Padovan74e75742013-10-15 19:24:51 -03001437 l2cap_chan_ready(chan);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001438
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001439 } else if (chan->state == BT_CONNECT) {
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001440 l2cap_do_start(chan);
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001441 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001442
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001443 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001444 }
1445
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001446 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001447}
1448
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001449/* Notify sockets that we cannot guaranty reliability anymore */
1450static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1451{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001452 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001453
1454 BT_DBG("conn %p", conn);
1455
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001456 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001457
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001458 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001459 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001460 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001461 }
1462
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001463 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001464}
1465
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001466static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001467{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001468 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001469 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001470
Marcel Holtmann984947d2009-02-06 23:35:19 +01001471 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001472 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001473
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001474 l2cap_conn_start(conn);
1475}
1476
David Herrmann2c8e1412013-04-06 20:28:45 +02001477/*
1478 * l2cap_user
1479 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1480 * callback is called during registration. The ->remove callback is called
1481 * during unregistration.
1482 * An l2cap_user object can either be explicitly unregistered or when the
1483 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1484 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1485 * External modules must own a reference to the l2cap_conn object if they intend
1486 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1487 * any time if they don't.
1488 */
1489
1490int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1491{
1492 struct hci_dev *hdev = conn->hcon->hdev;
1493 int ret;
1494
1495 /* We need to check whether l2cap_conn is registered. If it is not, we
1496 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1497 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1498 * relies on the parent hci_conn object to be locked. This itself relies
1499 * on the hci_dev object to be locked. So we must lock the hci device
1500 * here, too. */
1501
1502 hci_dev_lock(hdev);
1503
1504 if (user->list.next || user->list.prev) {
1505 ret = -EINVAL;
1506 goto out_unlock;
1507 }
1508
1509 /* conn->hchan is NULL after l2cap_conn_del() was called */
1510 if (!conn->hchan) {
1511 ret = -ENODEV;
1512 goto out_unlock;
1513 }
1514
1515 ret = user->probe(conn, user);
1516 if (ret)
1517 goto out_unlock;
1518
1519 list_add(&user->list, &conn->users);
1520 ret = 0;
1521
1522out_unlock:
1523 hci_dev_unlock(hdev);
1524 return ret;
1525}
1526EXPORT_SYMBOL(l2cap_register_user);
1527
1528void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1529{
1530 struct hci_dev *hdev = conn->hcon->hdev;
1531
1532 hci_dev_lock(hdev);
1533
1534 if (!user->list.next || !user->list.prev)
1535 goto out_unlock;
1536
1537 list_del(&user->list);
1538 user->list.next = NULL;
1539 user->list.prev = NULL;
1540 user->remove(conn, user);
1541
1542out_unlock:
1543 hci_dev_unlock(hdev);
1544}
1545EXPORT_SYMBOL(l2cap_unregister_user);
1546
1547static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1548{
1549 struct l2cap_user *user;
1550
1551 while (!list_empty(&conn->users)) {
1552 user = list_first_entry(&conn->users, struct l2cap_user, list);
1553 list_del(&user->list);
1554 user->list.next = NULL;
1555 user->list.prev = NULL;
1556 user->remove(conn, user);
1557 }
1558}
1559
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001560static void l2cap_conn_del(struct hci_conn *hcon, int err)
1561{
1562 struct l2cap_conn *conn = hcon->l2cap_data;
1563 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001564
1565 if (!conn)
1566 return;
1567
1568 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1569
1570 kfree_skb(conn->rx_skb);
1571
David Herrmann2c8e1412013-04-06 20:28:45 +02001572 l2cap_unregister_all_users(conn);
1573
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001574 mutex_lock(&conn->chan_lock);
1575
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001576 /* Kill channels */
1577 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001578 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001579 l2cap_chan_lock(chan);
1580
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001581 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001582
1583 l2cap_chan_unlock(chan);
1584
Gustavo Padovan80b98022012-05-27 22:27:51 -03001585 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001586 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001587 }
1588
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001589 mutex_unlock(&conn->chan_lock);
1590
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001591 hci_chan_del(conn->hchan);
1592
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001593 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001594 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001595
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001596 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001597 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001598 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001599 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001600
1601 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001602 conn->hchan = NULL;
1603 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001604}
1605
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001606static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001607{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001608 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001609 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001610
Johan Hedbergd06cc412012-06-06 18:44:11 +08001611 BT_DBG("conn %p", conn);
1612
1613 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1614 smp_chan_destroy(conn);
1615 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1616 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001617}
1618
Claudio Takahasibaf43252013-04-11 13:55:50 -03001619static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620{
Marcel Holtmann01394182006-07-03 10:02:46 +02001621 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001622 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623
Claudio Takahasibaf43252013-04-11 13:55:50 -03001624 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625 return conn;
1626
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001627 hchan = hci_chan_create(hcon);
1628 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001631 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001632 if (!conn) {
1633 hci_chan_del(hchan);
1634 return NULL;
1635 }
1636
David Herrmann9c903e32013-04-06 20:28:44 +02001637 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638 hcon->l2cap_data = conn;
1639 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001640 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001641 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001643 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001644
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001645 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001646 case LE_LINK:
1647 if (hcon->hdev->le_mtu) {
1648 conn->mtu = hcon->hdev->le_mtu;
1649 break;
1650 }
1651 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001652 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001653 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001654 break;
1655 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001656
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001657 conn->feat_mask = 0;
1658
Marcel Holtmann848566b2013-10-01 22:59:22 -07001659 if (hcon->type == ACL_LINK)
1660 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
1661 &hcon->hdev->dev_flags);
1662
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001664 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001665
1666 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001667 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001669 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001670 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001671 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001672 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001673
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001674 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001675
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 return conn;
1677}
1678
David Herrmann9c903e32013-04-06 20:28:44 +02001679static void l2cap_conn_free(struct kref *ref)
1680{
1681 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1682
1683 hci_conn_put(conn->hcon);
1684 kfree(conn);
1685}
1686
1687void l2cap_conn_get(struct l2cap_conn *conn)
1688{
1689 kref_get(&conn->ref);
1690}
1691EXPORT_SYMBOL(l2cap_conn_get);
1692
1693void l2cap_conn_put(struct l2cap_conn *conn)
1694{
1695 kref_put(&conn->ref, l2cap_conn_free);
1696}
1697EXPORT_SYMBOL(l2cap_conn_put);
1698
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700
Ido Yarivc2287682012-04-20 15:46:07 -03001701/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702 * Returns closest match.
1703 */
Ido Yarivc2287682012-04-20 15:46:07 -03001704static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1705 bdaddr_t *src,
1706 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001708 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001710 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001711
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001712 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001713 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 continue;
1715
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001716 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001717 int src_match, dst_match;
1718 int src_any, dst_any;
1719
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001721 src_match = !bacmp(&c->src, src);
1722 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001723 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001724 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001725 return c;
1726 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727
1728 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001729 src_any = !bacmp(&c->src, BDADDR_ANY);
1730 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001731 if ((src_match && dst_any) || (src_any && dst_match) ||
1732 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001733 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734 }
1735 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001737 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001738
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001739 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740}
1741
Andre Guedes8e9f9892012-04-24 21:02:55 -03001742int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1743 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 struct l2cap_conn *conn;
1746 struct hci_conn *hcon;
1747 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001748 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001749 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001751 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301752 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001754 hdev = hci_get_route(dst, &chan->src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001755 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 return -EHOSTUNREACH;
1757
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001758 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001760 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001761
1762 /* PSM must be odd and lsb of upper byte must be 0 */
1763 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001764 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001765 err = -EINVAL;
1766 goto done;
1767 }
1768
1769 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1770 err = -EINVAL;
1771 goto done;
1772 }
1773
1774 switch (chan->mode) {
1775 case L2CAP_MODE_BASIC:
1776 break;
1777 case L2CAP_MODE_ERTM:
1778 case L2CAP_MODE_STREAMING:
1779 if (!disable_ertm)
1780 break;
1781 /* fall through */
1782 default:
1783 err = -ENOTSUPP;
1784 goto done;
1785 }
1786
Gustavo Padovan0797e012012-05-27 22:27:54 -03001787 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001788 case BT_CONNECT:
1789 case BT_CONNECT2:
1790 case BT_CONFIG:
1791 /* Already connecting */
1792 err = 0;
1793 goto done;
1794
1795 case BT_CONNECTED:
1796 /* Already connected */
1797 err = -EISCONN;
1798 goto done;
1799
1800 case BT_OPEN:
1801 case BT_BOUND:
1802 /* Can connect */
1803 break;
1804
1805 default:
1806 err = -EBADFD;
1807 goto done;
1808 }
1809
1810 /* Set destination address and psm */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001811 bacpy(&chan->dst, dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001812 chan->dst_type = dst_type;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001813
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001814 chan->psm = psm;
1815 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001817 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001818
Johan Hedbergf224ca52013-04-29 19:35:36 +03001819 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001820 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001821 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001822 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001823 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001824 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001825
Ville Tervo30e76272011-02-22 16:10:53 -03001826 if (IS_ERR(hcon)) {
1827 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001829 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830
Claudio Takahasibaf43252013-04-11 13:55:50 -03001831 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001833 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001834 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835 goto done;
1836 }
1837
Johan Hedberg141d5702013-04-29 19:35:37 +03001838 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1839 hci_conn_drop(hcon);
1840 err = -EBUSY;
1841 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001842 }
1843
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844 /* Update source addr of the socket */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001845 bacpy(&chan->src, &hcon->src);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001846 chan->src_type = bdaddr_type(hcon, hcon->src_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001848 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001849 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001850 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001851
Johan Hedberg5ee98912013-04-29 19:35:43 +03001852 /* l2cap_chan_add takes its own ref so we can drop this one */
1853 hci_conn_drop(hcon);
1854
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001855 l2cap_state_change(chan, BT_CONNECT);
Gustavo Padovan8d836d72013-10-15 19:24:47 -03001856 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857
1858 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001859 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001860 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001861 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001862 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001863 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001864 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 }
1866
Ville Tervo30e76272011-02-22 16:10:53 -03001867 err = 0;
1868
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001870 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001871 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001872 hci_dev_put(hdev);
1873 return err;
1874}
1875
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001876static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001877{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001878 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001879 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001880
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001881 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001882
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001883 l2cap_chan_lock(chan);
1884
Mat Martineau80909e02012-05-17 20:53:50 -07001885 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001886 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001887 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001888 return;
1889 }
1890
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001891 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001892
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001893 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001894 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001895}
1896
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001897static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001898{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001899 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001900 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001901
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001902 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001903
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001904 l2cap_chan_lock(chan);
1905
Mat Martineau80909e02012-05-17 20:53:50 -07001906 if (!chan->conn) {
1907 l2cap_chan_unlock(chan);
1908 l2cap_chan_put(chan);
1909 return;
1910 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001911
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001912 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001913 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001914 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001915}
1916
Gustavo Padovand6603662012-05-21 13:58:22 -03001917static void l2cap_streaming_send(struct l2cap_chan *chan,
1918 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001919{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001920 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001921 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001922
Mat Martineau37339372012-05-17 20:53:33 -07001923 BT_DBG("chan %p, skbs %p", chan, skbs);
1924
Mat Martineaub99e13a2012-10-23 15:24:19 -07001925 if (__chan_is_moving(chan))
1926 return;
1927
Mat Martineau37339372012-05-17 20:53:33 -07001928 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1929
1930 while (!skb_queue_empty(&chan->tx_q)) {
1931
1932 skb = skb_dequeue(&chan->tx_q);
1933
1934 bt_cb(skb)->control.retries = 1;
1935 control = &bt_cb(skb)->control;
1936
1937 control->reqseq = 0;
1938 control->txseq = chan->next_tx_seq;
1939
1940 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001941
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001942 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001943 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1944 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001945 }
1946
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001947 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001948
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001949 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001950
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001951 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001952 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001953 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001954}
1955
Szymon Janc67c9e842011-07-28 16:24:33 +02001956static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001957{
1958 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001959 struct l2cap_ctrl *control;
1960 int sent = 0;
1961
1962 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001963
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001964 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001965 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001966
Mat Martineau94122bb2012-05-02 09:42:02 -07001967 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1968 return 0;
1969
Mat Martineaub99e13a2012-10-23 15:24:19 -07001970 if (__chan_is_moving(chan))
1971 return 0;
1972
Mat Martineau18a48e72012-05-17 20:53:34 -07001973 while (chan->tx_send_head &&
1974 chan->unacked_frames < chan->remote_tx_win &&
1975 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001976
Mat Martineau18a48e72012-05-17 20:53:34 -07001977 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001978
Mat Martineau18a48e72012-05-17 20:53:34 -07001979 bt_cb(skb)->control.retries = 1;
1980 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001981
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001982 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001983 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001984
Mat Martineau18a48e72012-05-17 20:53:34 -07001985 control->reqseq = chan->buffer_seq;
1986 chan->last_acked_seq = chan->buffer_seq;
1987 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001988
Mat Martineau18a48e72012-05-17 20:53:34 -07001989 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001990
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001991 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001992 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1993 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001994 }
1995
Mat Martineau18a48e72012-05-17 20:53:34 -07001996 /* Clone after data has been modified. Data is assumed to be
1997 read-only (for locking purposes) on cloned sk_buffs.
1998 */
1999 tx_skb = skb_clone(skb, GFP_KERNEL);
2000
2001 if (!tx_skb)
2002 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002003
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002004 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002005
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002006 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002007 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002008 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002009 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002010
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002011 if (skb_queue_is_last(&chan->tx_q, skb))
2012 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002013 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002014 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002015
2016 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002017 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002018 }
2019
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002020 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2021 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002022
2023 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002024}
2025
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002026static void l2cap_ertm_resend(struct l2cap_chan *chan)
2027{
2028 struct l2cap_ctrl control;
2029 struct sk_buff *skb;
2030 struct sk_buff *tx_skb;
2031 u16 seq;
2032
2033 BT_DBG("chan %p", chan);
2034
2035 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2036 return;
2037
Mat Martineaub99e13a2012-10-23 15:24:19 -07002038 if (__chan_is_moving(chan))
2039 return;
2040
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002041 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2042 seq = l2cap_seq_list_pop(&chan->retrans_list);
2043
2044 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2045 if (!skb) {
2046 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002047 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002048 continue;
2049 }
2050
2051 bt_cb(skb)->control.retries++;
2052 control = bt_cb(skb)->control;
2053
2054 if (chan->max_tx != 0 &&
2055 bt_cb(skb)->control.retries > chan->max_tx) {
2056 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002057 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002058 l2cap_seq_list_clear(&chan->retrans_list);
2059 break;
2060 }
2061
2062 control.reqseq = chan->buffer_seq;
2063 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2064 control.final = 1;
2065 else
2066 control.final = 0;
2067
2068 if (skb_cloned(skb)) {
2069 /* Cloned sk_buffs are read-only, so we need a
2070 * writeable copy
2071 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002072 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002073 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002074 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002075 }
2076
2077 if (!tx_skb) {
2078 l2cap_seq_list_clear(&chan->retrans_list);
2079 break;
2080 }
2081
2082 /* Update skb contents */
2083 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2084 put_unaligned_le32(__pack_extended_control(&control),
2085 tx_skb->data + L2CAP_HDR_SIZE);
2086 } else {
2087 put_unaligned_le16(__pack_enhanced_control(&control),
2088 tx_skb->data + L2CAP_HDR_SIZE);
2089 }
2090
2091 if (chan->fcs == L2CAP_FCS_CRC16) {
2092 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2093 put_unaligned_le16(fcs, skb_put(tx_skb,
2094 L2CAP_FCS_SIZE));
2095 }
2096
2097 l2cap_do_send(chan, tx_skb);
2098
2099 BT_DBG("Resent txseq %d", control.txseq);
2100
2101 chan->last_acked_seq = chan->buffer_seq;
2102 }
2103}
2104
Mat Martineauf80842a2012-05-17 20:53:46 -07002105static void l2cap_retransmit(struct l2cap_chan *chan,
2106 struct l2cap_ctrl *control)
2107{
2108 BT_DBG("chan %p, control %p", chan, control);
2109
2110 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2111 l2cap_ertm_resend(chan);
2112}
2113
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002114static void l2cap_retransmit_all(struct l2cap_chan *chan,
2115 struct l2cap_ctrl *control)
2116{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002117 struct sk_buff *skb;
2118
2119 BT_DBG("chan %p, control %p", chan, control);
2120
2121 if (control->poll)
2122 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2123
2124 l2cap_seq_list_clear(&chan->retrans_list);
2125
2126 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2127 return;
2128
2129 if (chan->unacked_frames) {
2130 skb_queue_walk(&chan->tx_q, skb) {
2131 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002132 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002133 break;
2134 }
2135
2136 skb_queue_walk_from(&chan->tx_q, skb) {
2137 if (skb == chan->tx_send_head)
2138 break;
2139
2140 l2cap_seq_list_append(&chan->retrans_list,
2141 bt_cb(skb)->control.txseq);
2142 }
2143
2144 l2cap_ertm_resend(chan);
2145 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002146}
2147
Szymon Jancb17e73b2012-01-11 10:59:47 +01002148static void l2cap_send_ack(struct l2cap_chan *chan)
2149{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002150 struct l2cap_ctrl control;
2151 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2152 chan->last_acked_seq);
2153 int threshold;
2154
2155 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2156 chan, chan->last_acked_seq, chan->buffer_seq);
2157
2158 memset(&control, 0, sizeof(control));
2159 control.sframe = 1;
2160
2161 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2162 chan->rx_state == L2CAP_RX_STATE_RECV) {
2163 __clear_ack_timer(chan);
2164 control.super = L2CAP_SUPER_RNR;
2165 control.reqseq = chan->buffer_seq;
2166 l2cap_send_sframe(chan, &control);
2167 } else {
2168 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2169 l2cap_ertm_send(chan);
2170 /* If any i-frames were sent, they included an ack */
2171 if (chan->buffer_seq == chan->last_acked_seq)
2172 frames_to_ack = 0;
2173 }
2174
Mat Martineauc20f8e32012-07-10 05:47:07 -07002175 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002176 * Calculate without mul or div
2177 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002178 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002179 threshold += threshold << 1;
2180 threshold >>= 2;
2181
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002182 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002183 threshold);
2184
2185 if (frames_to_ack >= threshold) {
2186 __clear_ack_timer(chan);
2187 control.super = L2CAP_SUPER_RR;
2188 control.reqseq = chan->buffer_seq;
2189 l2cap_send_sframe(chan, &control);
2190 frames_to_ack = 0;
2191 }
2192
2193 if (frames_to_ack)
2194 __set_ack_timer(chan);
2195 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002196}
2197
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002198static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2199 struct msghdr *msg, int len,
2200 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002201{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002202 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002203 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002204 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002205
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002206 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002207 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208
2209 sent += count;
2210 len -= count;
2211
2212 /* Continuation fragments (no L2CAP header) */
2213 frag = &skb_shinfo(skb)->frag_list;
2214 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002215 struct sk_buff *tmp;
2216
Linus Torvalds1da177e2005-04-16 15:20:36 -07002217 count = min_t(unsigned int, conn->mtu, len);
2218
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002219 tmp = chan->ops->alloc_skb(chan, count,
2220 msg->msg_flags & MSG_DONTWAIT);
2221 if (IS_ERR(tmp))
2222 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002223
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002224 *frag = tmp;
2225
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002226 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2227 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002229 (*frag)->priority = skb->priority;
2230
Linus Torvalds1da177e2005-04-16 15:20:36 -07002231 sent += count;
2232 len -= count;
2233
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002234 skb->len += (*frag)->len;
2235 skb->data_len += (*frag)->len;
2236
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237 frag = &(*frag)->next;
2238 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239
2240 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002241}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002242
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002243static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002244 struct msghdr *msg, size_t len,
2245 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002246{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002247 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002248 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002249 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002250 struct l2cap_hdr *lh;
2251
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002252 BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
2253 __le16_to_cpu(chan->psm), len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002254
2255 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002256
2257 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002258 msg->msg_flags & MSG_DONTWAIT);
2259 if (IS_ERR(skb))
2260 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002261
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002262 skb->priority = priority;
2263
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002264 /* Create L2CAP header */
2265 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002266 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002267 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002268 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002269
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002270 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002271 if (unlikely(err < 0)) {
2272 kfree_skb(skb);
2273 return ERR_PTR(err);
2274 }
2275 return skb;
2276}
2277
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002278static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002279 struct msghdr *msg, size_t len,
2280 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002281{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002282 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002283 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002284 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002285 struct l2cap_hdr *lh;
2286
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002287 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002288
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002289 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002290
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002291 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002292 msg->msg_flags & MSG_DONTWAIT);
2293 if (IS_ERR(skb))
2294 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002295
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002296 skb->priority = priority;
2297
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002298 /* Create L2CAP header */
2299 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002300 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002301 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002302
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002303 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002304 if (unlikely(err < 0)) {
2305 kfree_skb(skb);
2306 return ERR_PTR(err);
2307 }
2308 return skb;
2309}
2310
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002311static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002312 struct msghdr *msg, size_t len,
2313 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002314{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002315 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002316 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002317 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002318 struct l2cap_hdr *lh;
2319
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002320 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002321
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002322 if (!conn)
2323 return ERR_PTR(-ENOTCONN);
2324
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002325 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002326
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002327 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002328 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002329
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002330 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002331 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002332
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002333 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002334
2335 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002336 msg->msg_flags & MSG_DONTWAIT);
2337 if (IS_ERR(skb))
2338 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002339
2340 /* Create L2CAP header */
2341 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002342 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002343 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002344
Mat Martineau18a48e72012-05-17 20:53:34 -07002345 /* Control header is populated later */
2346 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2347 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2348 else
2349 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002350
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002351 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002352 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002353
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002354 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002355 if (unlikely(err < 0)) {
2356 kfree_skb(skb);
2357 return ERR_PTR(err);
2358 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002359
Mat Martineau18a48e72012-05-17 20:53:34 -07002360 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002361 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002362 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002363}
2364
Mat Martineau94122bb2012-05-02 09:42:02 -07002365static int l2cap_segment_sdu(struct l2cap_chan *chan,
2366 struct sk_buff_head *seg_queue,
2367 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002368{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002369 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002370 u16 sdu_len;
2371 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002372 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002373
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002374 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002375
Mat Martineau94122bb2012-05-02 09:42:02 -07002376 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2377 * so fragmented skbs are not used. The HCI layer's handling
2378 * of fragmented skbs is not compatible with ERTM's queueing.
2379 */
2380
2381 /* PDU size is derived from the HCI MTU */
2382 pdu_len = chan->conn->mtu;
2383
Mat Martineaua5495742012-10-23 15:24:21 -07002384 /* Constrain PDU size for BR/EDR connections */
2385 if (!chan->hs_hcon)
2386 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002387
2388 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002389 if (chan->fcs)
2390 pdu_len -= L2CAP_FCS_SIZE;
2391
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002392 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002393
2394 /* Remote device may have requested smaller PDUs */
2395 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2396
2397 if (len <= pdu_len) {
2398 sar = L2CAP_SAR_UNSEGMENTED;
2399 sdu_len = 0;
2400 pdu_len = len;
2401 } else {
2402 sar = L2CAP_SAR_START;
2403 sdu_len = len;
2404 pdu_len -= L2CAP_SDULEN_SIZE;
2405 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002406
2407 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002408 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002409
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002410 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002411 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002412 return PTR_ERR(skb);
2413 }
2414
Mat Martineau94122bb2012-05-02 09:42:02 -07002415 bt_cb(skb)->control.sar = sar;
2416 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002417
Mat Martineau94122bb2012-05-02 09:42:02 -07002418 len -= pdu_len;
2419 if (sdu_len) {
2420 sdu_len = 0;
2421 pdu_len += L2CAP_SDULEN_SIZE;
2422 }
2423
2424 if (len <= pdu_len) {
2425 sar = L2CAP_SAR_END;
2426 pdu_len = len;
2427 } else {
2428 sar = L2CAP_SAR_CONTINUE;
2429 }
2430 }
2431
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002432 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002433}
2434
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002435int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002436 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002437{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002438 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002439 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002440 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002441
Seung-Woo Kim31e8ce82013-11-05 18:46:33 +09002442 if (!chan->conn)
2443 return -ENOTCONN;
2444
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002445 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002446 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002447 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002448 if (IS_ERR(skb))
2449 return PTR_ERR(skb);
2450
2451 l2cap_do_send(chan, skb);
2452 return len;
2453 }
2454
2455 switch (chan->mode) {
2456 case L2CAP_MODE_BASIC:
2457 /* Check outgoing MTU */
2458 if (len > chan->omtu)
2459 return -EMSGSIZE;
2460
2461 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002462 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002463 if (IS_ERR(skb))
2464 return PTR_ERR(skb);
2465
2466 l2cap_do_send(chan, skb);
2467 err = len;
2468 break;
2469
2470 case L2CAP_MODE_ERTM:
2471 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002472 /* Check outgoing MTU */
2473 if (len > chan->omtu) {
2474 err = -EMSGSIZE;
2475 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002476 }
2477
Mat Martineau94122bb2012-05-02 09:42:02 -07002478 __skb_queue_head_init(&seg_queue);
2479
2480 /* Do segmentation before calling in to the state machine,
2481 * since it's possible to block while waiting for memory
2482 * allocation.
2483 */
2484 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2485
2486 /* The channel could have been closed while segmenting,
2487 * check that it is still connected.
2488 */
2489 if (chan->state != BT_CONNECTED) {
2490 __skb_queue_purge(&seg_queue);
2491 err = -ENOTCONN;
2492 }
2493
2494 if (err)
2495 break;
2496
Mat Martineau37339372012-05-17 20:53:33 -07002497 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002498 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002499 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002500 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002501
Gustavo Padovand6603662012-05-21 13:58:22 -03002502 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002503
Mat Martineau94122bb2012-05-02 09:42:02 -07002504 /* If the skbs were not queued for sending, they'll still be in
2505 * seg_queue and need to be purged.
2506 */
2507 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002508 break;
2509
2510 default:
2511 BT_DBG("bad state %1.1x", chan->mode);
2512 err = -EBADFD;
2513 }
2514
2515 return err;
2516}
2517
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002518static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2519{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002520 struct l2cap_ctrl control;
2521 u16 seq;
2522
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002523 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002524
2525 memset(&control, 0, sizeof(control));
2526 control.sframe = 1;
2527 control.super = L2CAP_SUPER_SREJ;
2528
2529 for (seq = chan->expected_tx_seq; seq != txseq;
2530 seq = __next_seq(chan, seq)) {
2531 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2532 control.reqseq = seq;
2533 l2cap_send_sframe(chan, &control);
2534 l2cap_seq_list_append(&chan->srej_list, seq);
2535 }
2536 }
2537
2538 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002539}
2540
2541static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2542{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002543 struct l2cap_ctrl control;
2544
2545 BT_DBG("chan %p", chan);
2546
2547 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2548 return;
2549
2550 memset(&control, 0, sizeof(control));
2551 control.sframe = 1;
2552 control.super = L2CAP_SUPER_SREJ;
2553 control.reqseq = chan->srej_list.tail;
2554 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002555}
2556
2557static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2558{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002559 struct l2cap_ctrl control;
2560 u16 initial_head;
2561 u16 seq;
2562
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002563 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002564
2565 memset(&control, 0, sizeof(control));
2566 control.sframe = 1;
2567 control.super = L2CAP_SUPER_SREJ;
2568
2569 /* Capture initial list head to allow only one pass through the list. */
2570 initial_head = chan->srej_list.head;
2571
2572 do {
2573 seq = l2cap_seq_list_pop(&chan->srej_list);
2574 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2575 break;
2576
2577 control.reqseq = seq;
2578 l2cap_send_sframe(chan, &control);
2579 l2cap_seq_list_append(&chan->srej_list, seq);
2580 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002581}
2582
Mat Martineau608bcc62012-05-17 20:53:32 -07002583static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2584{
2585 struct sk_buff *acked_skb;
2586 u16 ackseq;
2587
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002588 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002589
2590 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2591 return;
2592
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002593 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002594 chan->expected_ack_seq, chan->unacked_frames);
2595
2596 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2597 ackseq = __next_seq(chan, ackseq)) {
2598
2599 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2600 if (acked_skb) {
2601 skb_unlink(acked_skb, &chan->tx_q);
2602 kfree_skb(acked_skb);
2603 chan->unacked_frames--;
2604 }
2605 }
2606
2607 chan->expected_ack_seq = reqseq;
2608
2609 if (chan->unacked_frames == 0)
2610 __clear_retrans_timer(chan);
2611
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002612 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002613}
2614
2615static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2616{
2617 BT_DBG("chan %p", chan);
2618
2619 chan->expected_tx_seq = chan->buffer_seq;
2620 l2cap_seq_list_clear(&chan->srej_list);
2621 skb_queue_purge(&chan->srej_q);
2622 chan->rx_state = L2CAP_RX_STATE_RECV;
2623}
2624
Gustavo Padovand6603662012-05-21 13:58:22 -03002625static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2626 struct l2cap_ctrl *control,
2627 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002628{
Mat Martineau608bcc62012-05-17 20:53:32 -07002629 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2630 event);
2631
2632 switch (event) {
2633 case L2CAP_EV_DATA_REQUEST:
2634 if (chan->tx_send_head == NULL)
2635 chan->tx_send_head = skb_peek(skbs);
2636
2637 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2638 l2cap_ertm_send(chan);
2639 break;
2640 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2641 BT_DBG("Enter LOCAL_BUSY");
2642 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2643
2644 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2645 /* The SREJ_SENT state must be aborted if we are to
2646 * enter the LOCAL_BUSY state.
2647 */
2648 l2cap_abort_rx_srej_sent(chan);
2649 }
2650
2651 l2cap_send_ack(chan);
2652
2653 break;
2654 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2655 BT_DBG("Exit LOCAL_BUSY");
2656 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2657
2658 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2659 struct l2cap_ctrl local_control;
2660
2661 memset(&local_control, 0, sizeof(local_control));
2662 local_control.sframe = 1;
2663 local_control.super = L2CAP_SUPER_RR;
2664 local_control.poll = 1;
2665 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002666 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002667
2668 chan->retry_count = 1;
2669 __set_monitor_timer(chan);
2670 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2671 }
2672 break;
2673 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2674 l2cap_process_reqseq(chan, control->reqseq);
2675 break;
2676 case L2CAP_EV_EXPLICIT_POLL:
2677 l2cap_send_rr_or_rnr(chan, 1);
2678 chan->retry_count = 1;
2679 __set_monitor_timer(chan);
2680 __clear_ack_timer(chan);
2681 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2682 break;
2683 case L2CAP_EV_RETRANS_TO:
2684 l2cap_send_rr_or_rnr(chan, 1);
2685 chan->retry_count = 1;
2686 __set_monitor_timer(chan);
2687 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2688 break;
2689 case L2CAP_EV_RECV_FBIT:
2690 /* Nothing to process */
2691 break;
2692 default:
2693 break;
2694 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002695}
2696
Gustavo Padovand6603662012-05-21 13:58:22 -03002697static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2698 struct l2cap_ctrl *control,
2699 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002700{
Mat Martineau608bcc62012-05-17 20:53:32 -07002701 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2702 event);
2703
2704 switch (event) {
2705 case L2CAP_EV_DATA_REQUEST:
2706 if (chan->tx_send_head == NULL)
2707 chan->tx_send_head = skb_peek(skbs);
2708 /* Queue data, but don't send. */
2709 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2710 break;
2711 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2712 BT_DBG("Enter LOCAL_BUSY");
2713 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2714
2715 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2716 /* The SREJ_SENT state must be aborted if we are to
2717 * enter the LOCAL_BUSY state.
2718 */
2719 l2cap_abort_rx_srej_sent(chan);
2720 }
2721
2722 l2cap_send_ack(chan);
2723
2724 break;
2725 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2726 BT_DBG("Exit LOCAL_BUSY");
2727 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2728
2729 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2730 struct l2cap_ctrl local_control;
2731 memset(&local_control, 0, sizeof(local_control));
2732 local_control.sframe = 1;
2733 local_control.super = L2CAP_SUPER_RR;
2734 local_control.poll = 1;
2735 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002736 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002737
2738 chan->retry_count = 1;
2739 __set_monitor_timer(chan);
2740 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2741 }
2742 break;
2743 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2744 l2cap_process_reqseq(chan, control->reqseq);
2745
2746 /* Fall through */
2747
2748 case L2CAP_EV_RECV_FBIT:
2749 if (control && control->final) {
2750 __clear_monitor_timer(chan);
2751 if (chan->unacked_frames > 0)
2752 __set_retrans_timer(chan);
2753 chan->retry_count = 0;
2754 chan->tx_state = L2CAP_TX_STATE_XMIT;
2755 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2756 }
2757 break;
2758 case L2CAP_EV_EXPLICIT_POLL:
2759 /* Ignore */
2760 break;
2761 case L2CAP_EV_MONITOR_TO:
2762 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2763 l2cap_send_rr_or_rnr(chan, 1);
2764 __set_monitor_timer(chan);
2765 chan->retry_count++;
2766 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002767 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002768 }
2769 break;
2770 default:
2771 break;
2772 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002773}
2774
Gustavo Padovand6603662012-05-21 13:58:22 -03002775static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2776 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002777{
Mat Martineau608bcc62012-05-17 20:53:32 -07002778 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2779 chan, control, skbs, event, chan->tx_state);
2780
2781 switch (chan->tx_state) {
2782 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002783 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002784 break;
2785 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002786 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002787 break;
2788 default:
2789 /* Ignore event */
2790 break;
2791 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002792}
2793
Mat Martineau4b51dae92012-05-17 20:53:37 -07002794static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2795 struct l2cap_ctrl *control)
2796{
2797 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002798 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002799}
2800
Mat Martineauf80842a2012-05-17 20:53:46 -07002801static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2802 struct l2cap_ctrl *control)
2803{
2804 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002805 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002806}
2807
Linus Torvalds1da177e2005-04-16 15:20:36 -07002808/* Copy frame to all raw sockets on that connection */
2809static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2810{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002811 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002812 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002813
2814 BT_DBG("conn %p", conn);
2815
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002816 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002817
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002818 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002819 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002820 continue;
2821
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02002822 /* Don't send frame to the channel it came from */
2823 if (bt_cb(skb)->chan == chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002824 continue;
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02002825
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002826 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002827 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002828 continue;
Gustavo Padovan80b98022012-05-27 22:27:51 -03002829 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002830 kfree_skb(nskb);
2831 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002832
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002833 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834}
2835
2836/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002837static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2838 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002839{
2840 struct sk_buff *skb, **frag;
2841 struct l2cap_cmd_hdr *cmd;
2842 struct l2cap_hdr *lh;
2843 int len, count;
2844
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002845 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2846 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002847
Anderson Lizardo300b9622013-06-02 16:30:40 -04002848 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2849 return NULL;
2850
Linus Torvalds1da177e2005-04-16 15:20:36 -07002851 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2852 count = min_t(unsigned int, conn->mtu, len);
2853
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002854 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002855 if (!skb)
2856 return NULL;
2857
2858 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002859 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002860
2861 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002862 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002863 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002864 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865
2866 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2867 cmd->code = code;
2868 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002869 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002870
2871 if (dlen) {
2872 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2873 memcpy(skb_put(skb, count), data, count);
2874 data += count;
2875 }
2876
2877 len -= skb->len;
2878
2879 /* Continuation fragments (no L2CAP header) */
2880 frag = &skb_shinfo(skb)->frag_list;
2881 while (len) {
2882 count = min_t(unsigned int, conn->mtu, len);
2883
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002884 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002885 if (!*frag)
2886 goto fail;
2887
2888 memcpy(skb_put(*frag, count), data, count);
2889
2890 len -= count;
2891 data += count;
2892
2893 frag = &(*frag)->next;
2894 }
2895
2896 return skb;
2897
2898fail:
2899 kfree_skb(skb);
2900 return NULL;
2901}
2902
Gustavo Padovan2d792812012-10-06 10:07:01 +01002903static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2904 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002905{
2906 struct l2cap_conf_opt *opt = *ptr;
2907 int len;
2908
2909 len = L2CAP_CONF_OPT_SIZE + opt->len;
2910 *ptr += len;
2911
2912 *type = opt->type;
2913 *olen = opt->len;
2914
2915 switch (opt->len) {
2916 case 1:
2917 *val = *((u8 *) opt->val);
2918 break;
2919
2920 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002921 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922 break;
2923
2924 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002925 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926 break;
2927
2928 default:
2929 *val = (unsigned long) opt->val;
2930 break;
2931 }
2932
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002933 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002934 return len;
2935}
2936
Linus Torvalds1da177e2005-04-16 15:20:36 -07002937static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2938{
2939 struct l2cap_conf_opt *opt = *ptr;
2940
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002941 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002942
2943 opt->type = type;
2944 opt->len = len;
2945
2946 switch (len) {
2947 case 1:
2948 *((u8 *) opt->val) = val;
2949 break;
2950
2951 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002952 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953 break;
2954
2955 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002956 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002957 break;
2958
2959 default:
2960 memcpy(opt->val, (void *) val, len);
2961 break;
2962 }
2963
2964 *ptr += L2CAP_CONF_OPT_SIZE + len;
2965}
2966
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002967static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2968{
2969 struct l2cap_conf_efs efs;
2970
Szymon Janc1ec918c2011-11-16 09:32:21 +01002971 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002972 case L2CAP_MODE_ERTM:
2973 efs.id = chan->local_id;
2974 efs.stype = chan->local_stype;
2975 efs.msdu = cpu_to_le16(chan->local_msdu);
2976 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002977 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002978 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002979 break;
2980
2981 case L2CAP_MODE_STREAMING:
2982 efs.id = 1;
2983 efs.stype = L2CAP_SERV_BESTEFFORT;
2984 efs.msdu = cpu_to_le16(chan->local_msdu);
2985 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2986 efs.acc_lat = 0;
2987 efs.flush_to = 0;
2988 break;
2989
2990 default:
2991 return;
2992 }
2993
2994 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002995 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002996}
2997
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002998static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002999{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003000 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003001 ack_timer.work);
3002 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003003
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003004 BT_DBG("chan %p", chan);
3005
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003006 l2cap_chan_lock(chan);
3007
Mat Martineau03625202012-05-17 20:53:51 -07003008 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3009 chan->last_acked_seq);
3010
3011 if (frames_to_ack)
3012 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003013
3014 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003015 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003016}
3017
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003018int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003019{
Mat Martineau3c588192012-04-11 10:48:42 -07003020 int err;
3021
Mat Martineau105bdf92012-04-27 16:50:48 -07003022 chan->next_tx_seq = 0;
3023 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003024 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003025 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003026 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003027 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003028 chan->last_acked_seq = 0;
3029 chan->sdu = NULL;
3030 chan->sdu_last_frag = NULL;
3031 chan->sdu_len = 0;
3032
Mat Martineaud34c34f2012-05-14 14:49:27 -07003033 skb_queue_head_init(&chan->tx_q);
3034
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003035 chan->local_amp_id = AMP_ID_BREDR;
3036 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003037 chan->move_state = L2CAP_MOVE_STABLE;
3038 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3039
Mat Martineau105bdf92012-04-27 16:50:48 -07003040 if (chan->mode != L2CAP_MODE_ERTM)
3041 return 0;
3042
3043 chan->rx_state = L2CAP_RX_STATE_RECV;
3044 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003045
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003046 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3047 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3048 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003049
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003050 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003051
Mat Martineau3c588192012-04-11 10:48:42 -07003052 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3053 if (err < 0)
3054 return err;
3055
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003056 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3057 if (err < 0)
3058 l2cap_seq_list_free(&chan->srej_list);
3059
3060 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003061}
3062
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003063static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3064{
3065 switch (mode) {
3066 case L2CAP_MODE_STREAMING:
3067 case L2CAP_MODE_ERTM:
3068 if (l2cap_mode_supported(mode, remote_feat_mask))
3069 return mode;
3070 /* fall through */
3071 default:
3072 return L2CAP_MODE_BASIC;
3073 }
3074}
3075
Marcel Holtmann848566b2013-10-01 22:59:22 -07003076static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003077{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003078 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003079}
3080
Marcel Holtmann848566b2013-10-01 22:59:22 -07003081static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003082{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003083 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003084}
3085
Mat Martineau36c86c82012-10-23 15:24:20 -07003086static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3087 struct l2cap_conf_rfc *rfc)
3088{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003089 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003090 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3091
3092 /* Class 1 devices have must have ERTM timeouts
3093 * exceeding the Link Supervision Timeout. The
3094 * default Link Supervision Timeout for AMP
3095 * controllers is 10 seconds.
3096 *
3097 * Class 1 devices use 0xffffffff for their
3098 * best-effort flush timeout, so the clamping logic
3099 * will result in a timeout that meets the above
3100 * requirement. ERTM timeouts are 16-bit values, so
3101 * the maximum timeout is 65.535 seconds.
3102 */
3103
3104 /* Convert timeout to milliseconds and round */
3105 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3106
3107 /* This is the recommended formula for class 2 devices
3108 * that start ERTM timers when packets are sent to the
3109 * controller.
3110 */
3111 ertm_to = 3 * ertm_to + 500;
3112
3113 if (ertm_to > 0xffff)
3114 ertm_to = 0xffff;
3115
3116 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3117 rfc->monitor_timeout = rfc->retrans_timeout;
3118 } else {
3119 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3120 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3121 }
3122}
3123
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003124static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3125{
3126 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003127 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003128 /* use extended control field */
3129 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003130 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3131 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003132 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003133 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003134 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3135 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003136 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003137}
3138
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003139static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003140{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003141 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003142 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003143 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003144 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003145
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003146 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003147
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003148 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003149 goto done;
3150
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003151 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003152 case L2CAP_MODE_STREAMING:
3153 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003154 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003155 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003156
Marcel Holtmann848566b2013-10-01 22:59:22 -07003157 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003158 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3159
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003160 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003161 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003162 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003163 break;
3164 }
3165
3166done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003167 if (chan->imtu != L2CAP_DEFAULT_MTU)
3168 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003169
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003170 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003171 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003172 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003173 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003174 break;
3175
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003176 rfc.mode = L2CAP_MODE_BASIC;
3177 rfc.txwin_size = 0;
3178 rfc.max_transmit = 0;
3179 rfc.retrans_timeout = 0;
3180 rfc.monitor_timeout = 0;
3181 rfc.max_pdu_size = 0;
3182
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003183 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003184 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003185 break;
3186
3187 case L2CAP_MODE_ERTM:
3188 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003189 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003190
3191 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003192
3193 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003194 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3195 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003196 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003197
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003198 l2cap_txwin_setup(chan);
3199
3200 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003201 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003202
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003203 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003204 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003205
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003206 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3207 l2cap_add_opt_efs(&ptr, chan);
3208
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003209 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3210 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003211 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003212
3213 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3214 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003215 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003216 chan->fcs = L2CAP_FCS_NONE;
3217 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3218 chan->fcs);
3219 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003220 break;
3221
3222 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003223 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003224 rfc.mode = L2CAP_MODE_STREAMING;
3225 rfc.txwin_size = 0;
3226 rfc.max_transmit = 0;
3227 rfc.retrans_timeout = 0;
3228 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003229
3230 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003231 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3232 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003233 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003234
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003235 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003236 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003237
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003238 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3239 l2cap_add_opt_efs(&ptr, chan);
3240
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003241 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3242 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003243 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003244 chan->fcs = L2CAP_FCS_NONE;
3245 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3246 chan->fcs);
3247 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003248 break;
3249 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003250
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003251 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003252 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003253
3254 return ptr - data;
3255}
3256
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003257static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003258{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003259 struct l2cap_conf_rsp *rsp = data;
3260 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003261 void *req = chan->conf_req;
3262 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003263 int type, hint, olen;
3264 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003265 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003266 struct l2cap_conf_efs efs;
3267 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003268 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003269 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003270 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003271
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003272 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003273
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003274 while (len >= L2CAP_CONF_OPT_SIZE) {
3275 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003276
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003277 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003278 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003279
3280 switch (type) {
3281 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003282 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003283 break;
3284
3285 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003286 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003287 break;
3288
3289 case L2CAP_CONF_QOS:
3290 break;
3291
Marcel Holtmann6464f352007-10-20 13:39:51 +02003292 case L2CAP_CONF_RFC:
3293 if (olen == sizeof(rfc))
3294 memcpy(&rfc, (void *) val, olen);
3295 break;
3296
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003297 case L2CAP_CONF_FCS:
3298 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003299 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003300 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003301
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003302 case L2CAP_CONF_EFS:
3303 remote_efs = 1;
3304 if (olen == sizeof(efs))
3305 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003306 break;
3307
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003308 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003309 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003310 return -ECONNREFUSED;
3311
3312 set_bit(FLAG_EXT_CTRL, &chan->flags);
3313 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003314 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003315 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003316 break;
3317
3318 default:
3319 if (hint)
3320 break;
3321
3322 result = L2CAP_CONF_UNKNOWN;
3323 *((u8 *) ptr++) = type;
3324 break;
3325 }
3326 }
3327
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003328 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003329 goto done;
3330
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003331 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003332 case L2CAP_MODE_STREAMING:
3333 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003334 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003335 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003336 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003337 break;
3338 }
3339
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003340 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003341 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003342 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3343 else
3344 return -ECONNREFUSED;
3345 }
3346
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003347 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003348 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003349
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003350 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003351 }
3352
3353done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003354 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003355 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003356 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003357
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003358 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003359 return -ECONNREFUSED;
3360
Gustavo Padovan2d792812012-10-06 10:07:01 +01003361 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3362 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003363 }
3364
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003365 if (result == L2CAP_CONF_SUCCESS) {
3366 /* Configure output options and let the other side know
3367 * which ones we don't like. */
3368
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003369 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3370 result = L2CAP_CONF_UNACCEPT;
3371 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003372 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003373 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003374 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003375 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003376
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003377 if (remote_efs) {
3378 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003379 efs.stype != L2CAP_SERV_NOTRAFIC &&
3380 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003381
3382 result = L2CAP_CONF_UNACCEPT;
3383
3384 if (chan->num_conf_req >= 1)
3385 return -ECONNREFUSED;
3386
3387 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003388 sizeof(efs),
3389 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003390 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003391 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003392 result = L2CAP_CONF_PENDING;
3393 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003394 }
3395 }
3396
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003397 switch (rfc.mode) {
3398 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003399 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003400 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003401 break;
3402
3403 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003404 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3405 chan->remote_tx_win = rfc.txwin_size;
3406 else
3407 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3408
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003409 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003410
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003411 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003412 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3413 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003414 rfc.max_pdu_size = cpu_to_le16(size);
3415 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003416
Mat Martineau36c86c82012-10-23 15:24:20 -07003417 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003418
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003419 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003420
3421 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003422 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003423
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003424 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3425 chan->remote_id = efs.id;
3426 chan->remote_stype = efs.stype;
3427 chan->remote_msdu = le16_to_cpu(efs.msdu);
3428 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003429 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003430 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003431 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003432 chan->remote_sdu_itime =
3433 le32_to_cpu(efs.sdu_itime);
3434 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003435 sizeof(efs),
3436 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003437 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003438 break;
3439
3440 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003441 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003442 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3443 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003444 rfc.max_pdu_size = cpu_to_le16(size);
3445 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003446
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003447 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003448
Gustavo Padovan2d792812012-10-06 10:07:01 +01003449 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3450 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003451
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003452 break;
3453
3454 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003455 result = L2CAP_CONF_UNACCEPT;
3456
3457 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003458 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003459 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003460
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003461 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003462 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003463 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003464 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003465 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003466 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003467
3468 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003469}
3470
Gustavo Padovan2d792812012-10-06 10:07:01 +01003471static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3472 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003473{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003474 struct l2cap_conf_req *req = data;
3475 void *ptr = req->data;
3476 int type, olen;
3477 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003478 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003479 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003480
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003481 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003482
3483 while (len >= L2CAP_CONF_OPT_SIZE) {
3484 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3485
3486 switch (type) {
3487 case L2CAP_CONF_MTU:
3488 if (val < L2CAP_DEFAULT_MIN_MTU) {
3489 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003490 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003491 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003492 chan->imtu = val;
3493 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003494 break;
3495
3496 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003497 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003498 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003499 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003500 break;
3501
3502 case L2CAP_CONF_RFC:
3503 if (olen == sizeof(rfc))
3504 memcpy(&rfc, (void *)val, olen);
3505
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003506 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003507 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003508 return -ECONNREFUSED;
3509
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003510 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003511
3512 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003513 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003514 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003515
3516 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003517 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003518 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003519 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003520 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003521
3522 case L2CAP_CONF_EFS:
3523 if (olen == sizeof(efs))
3524 memcpy(&efs, (void *)val, olen);
3525
3526 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003527 efs.stype != L2CAP_SERV_NOTRAFIC &&
3528 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003529 return -ECONNREFUSED;
3530
Gustavo Padovan2d792812012-10-06 10:07:01 +01003531 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3532 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003533 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003534
3535 case L2CAP_CONF_FCS:
3536 if (*result == L2CAP_CONF_PENDING)
3537 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003538 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003539 &chan->conf_state);
3540 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003541 }
3542 }
3543
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003544 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003545 return -ECONNREFUSED;
3546
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003547 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003548
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003549 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003550 switch (rfc.mode) {
3551 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003552 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3553 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3554 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003555 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3556 chan->ack_win = min_t(u16, chan->ack_win,
3557 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003558
3559 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3560 chan->local_msdu = le16_to_cpu(efs.msdu);
3561 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003562 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003563 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3564 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003565 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003566 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003567 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003568
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003569 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003570 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003571 }
3572 }
3573
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003574 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003575 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003576
3577 return ptr - data;
3578}
3579
Gustavo Padovan2d792812012-10-06 10:07:01 +01003580static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3581 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003582{
3583 struct l2cap_conf_rsp *rsp = data;
3584 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003585
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003586 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003587
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003588 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003589 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003590 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003591
3592 return ptr - data;
3593}
3594
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003595void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003596{
3597 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003598 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003599 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003600 u8 rsp_code;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003601
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003602 rsp.scid = cpu_to_le16(chan->dcid);
3603 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003604 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3605 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003606
3607 if (chan->hs_hcon)
3608 rsp_code = L2CAP_CREATE_CHAN_RSP;
3609 else
3610 rsp_code = L2CAP_CONN_RSP;
3611
3612 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3613
3614 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003615
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003616 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003617 return;
3618
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003619 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003620 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003621 chan->num_conf_req++;
3622}
3623
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003624static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003625{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003626 int type, olen;
3627 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003628 /* Use sane default values in case a misbehaving remote device
3629 * did not send an RFC or extended window size option.
3630 */
3631 u16 txwin_ext = chan->ack_win;
3632 struct l2cap_conf_rfc rfc = {
3633 .mode = chan->mode,
3634 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3635 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3636 .max_pdu_size = cpu_to_le16(chan->imtu),
3637 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3638 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003639
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003640 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003641
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003642 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003643 return;
3644
3645 while (len >= L2CAP_CONF_OPT_SIZE) {
3646 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3647
Mat Martineauc20f8e32012-07-10 05:47:07 -07003648 switch (type) {
3649 case L2CAP_CONF_RFC:
3650 if (olen == sizeof(rfc))
3651 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003652 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003653 case L2CAP_CONF_EWS:
3654 txwin_ext = val;
3655 break;
3656 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003657 }
3658
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003659 switch (rfc.mode) {
3660 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003661 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3662 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003663 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3664 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3665 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3666 else
3667 chan->ack_win = min_t(u16, chan->ack_win,
3668 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003669 break;
3670 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003671 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003672 }
3673}
3674
Gustavo Padovan2d792812012-10-06 10:07:01 +01003675static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003676 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3677 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003678{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003679 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003680
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003681 if (cmd_len < sizeof(*rej))
3682 return -EPROTO;
3683
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003684 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003685 return 0;
3686
3687 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003688 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003689 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003690
3691 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003692 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003693
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003694 l2cap_conn_start(conn);
3695 }
3696
3697 return 0;
3698}
3699
Mat Martineau17009152012-10-23 15:24:07 -07003700static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3701 struct l2cap_cmd_hdr *cmd,
3702 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003703{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003704 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3705 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003706 struct l2cap_chan *chan = NULL, *pchan;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003707 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003708
3709 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003710 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003711
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003712 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003713
3714 /* Check if we have socket listening on psm */
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003715 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07003716 &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003717 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003718 result = L2CAP_CR_BAD_PSM;
3719 goto sendresp;
3720 }
3721
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003722 mutex_lock(&conn->chan_lock);
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003723 l2cap_chan_lock(pchan);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003724
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003725 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003726 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003727 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003728 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003729 result = L2CAP_CR_SEC_BLOCK;
3730 goto response;
3731 }
3732
Linus Torvalds1da177e2005-04-16 15:20:36 -07003733 result = L2CAP_CR_NO_MEM;
3734
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003735 /* Check if we already have channel with that dcid */
3736 if (__l2cap_get_chan_by_dcid(conn, scid))
3737 goto response;
3738
Gustavo Padovan80b98022012-05-27 22:27:51 -03003739 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003740 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003741 goto response;
3742
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09003743 /* For certain devices (ex: HID mouse), support for authentication,
3744 * pairing and bonding is optional. For such devices, inorder to avoid
3745 * the ACL alive for too long after L2CAP disconnection, reset the ACL
3746 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
3747 */
3748 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3749
Marcel Holtmann7eafc592013-10-13 08:12:47 -07003750 bacpy(&chan->src, &conn->hcon->src);
3751 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07003752 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
3753 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003754 chan->psm = psm;
3755 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003756 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003757
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003758 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003759
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003760 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003761
Gustavo Padovan8d836d72013-10-15 19:24:47 -03003762 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003763
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003764 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003765
Marcel Holtmann984947d2009-02-06 23:35:19 +01003766 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003767 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07003768 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003769 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003770 result = L2CAP_CR_PEND;
3771 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003772 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003773 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003774 /* Force pending result for AMP controllers.
3775 * The connection will succeed after the
3776 * physical link is up.
3777 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003778 if (amp_id == AMP_ID_BREDR) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003779 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau17009152012-10-23 15:24:07 -07003780 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003781 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003782 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003783 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07003784 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003785 status = L2CAP_CS_NO_INFO;
3786 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003787 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003788 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003789 result = L2CAP_CR_PEND;
3790 status = L2CAP_CS_AUTHEN_PEND;
3791 }
3792 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003793 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003794 result = L2CAP_CR_PEND;
3795 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003796 }
3797
Linus Torvalds1da177e2005-04-16 15:20:36 -07003798response:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003799 l2cap_chan_unlock(pchan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003800 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003801
3802sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003803 rsp.scid = cpu_to_le16(scid);
3804 rsp.dcid = cpu_to_le16(dcid);
3805 rsp.result = cpu_to_le16(result);
3806 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003807 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003808
3809 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3810 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003811 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003812
3813 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3814 conn->info_ident = l2cap_get_ident(conn);
3815
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003816 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003817
Gustavo Padovan2d792812012-10-06 10:07:01 +01003818 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3819 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003820 }
3821
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003822 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003823 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003824 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003825 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003826 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003827 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003828 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003829 }
Mat Martineau17009152012-10-23 15:24:07 -07003830
3831 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003832}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003833
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003834static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003835 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003836{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303837 struct hci_dev *hdev = conn->hcon->hdev;
3838 struct hci_conn *hcon = conn->hcon;
3839
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003840 if (cmd_len < sizeof(struct l2cap_conn_req))
3841 return -EPROTO;
3842
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303843 hci_dev_lock(hdev);
3844 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3845 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3846 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3847 hcon->dst_type, 0, NULL, 0,
3848 hcon->dev_class);
3849 hci_dev_unlock(hdev);
3850
Gustavo Padovan300229f2012-10-12 19:40:40 +08003851 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003852 return 0;
3853}
3854
Mat Martineau5909cf32012-10-23 15:24:08 -07003855static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003856 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3857 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003858{
3859 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3860 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003861 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003862 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003863 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003864
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003865 if (cmd_len < sizeof(*rsp))
3866 return -EPROTO;
3867
Linus Torvalds1da177e2005-04-16 15:20:36 -07003868 scid = __le16_to_cpu(rsp->scid);
3869 dcid = __le16_to_cpu(rsp->dcid);
3870 result = __le16_to_cpu(rsp->result);
3871 status = __le16_to_cpu(rsp->status);
3872
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003873 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 +01003874 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003875
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003876 mutex_lock(&conn->chan_lock);
3877
Linus Torvalds1da177e2005-04-16 15:20:36 -07003878 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003879 chan = __l2cap_get_chan_by_scid(conn, scid);
3880 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003881 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003882 goto unlock;
3883 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003884 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003885 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3886 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003887 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003888 goto unlock;
3889 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003890 }
3891
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003892 err = 0;
3893
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003894 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003895
Linus Torvalds1da177e2005-04-16 15:20:36 -07003896 switch (result) {
3897 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003898 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003899 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003900 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003901 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003902
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003903 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003904 break;
3905
Linus Torvalds1da177e2005-04-16 15:20:36 -07003906 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003907 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003908 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003909 break;
3910
3911 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003912 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003913 break;
3914
3915 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003916 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917 break;
3918 }
3919
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003920 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003921
3922unlock:
3923 mutex_unlock(&conn->chan_lock);
3924
3925 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003926}
3927
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003928static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003929{
3930 /* FCS is enabled only in ERTM or streaming mode, if one or both
3931 * sides request it.
3932 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003933 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003934 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003935 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003936 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003937}
3938
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003939static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3940 u8 ident, u16 flags)
3941{
3942 struct l2cap_conn *conn = chan->conn;
3943
3944 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3945 flags);
3946
3947 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3948 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3949
3950 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3951 l2cap_build_conf_rsp(chan, data,
3952 L2CAP_CONF_SUCCESS, flags), data);
3953}
3954
Johan Hedberg662d6522013-10-16 11:20:47 +03003955static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident,
3956 u16 scid, u16 dcid)
3957{
3958 struct l2cap_cmd_rej_cid rej;
3959
3960 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
3961 rej.scid = __cpu_to_le16(scid);
3962 rej.dcid = __cpu_to_le16(dcid);
3963
3964 l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3965}
3966
Gustavo Padovan2d792812012-10-06 10:07:01 +01003967static inline int l2cap_config_req(struct l2cap_conn *conn,
3968 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3969 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003970{
3971 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3972 u16 dcid, flags;
3973 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003974 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003975 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003976
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003977 if (cmd_len < sizeof(*req))
3978 return -EPROTO;
3979
Linus Torvalds1da177e2005-04-16 15:20:36 -07003980 dcid = __le16_to_cpu(req->dcid);
3981 flags = __le16_to_cpu(req->flags);
3982
3983 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3984
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003985 chan = l2cap_get_chan_by_scid(conn, dcid);
Johan Hedberg662d6522013-10-16 11:20:47 +03003986 if (!chan) {
3987 cmd_reject_invalid_cid(conn, cmd->ident, dcid, 0);
3988 return 0;
3989 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003990
David S. Miller033b1142011-07-21 13:38:42 -07003991 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Johan Hedberg662d6522013-10-16 11:20:47 +03003992 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
3993 chan->dcid);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003994 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003995 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003996
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003997 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003998 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003999 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004000 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004001 l2cap_build_conf_rsp(chan, rsp,
4002 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004003 goto unlock;
4004 }
4005
4006 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004007 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4008 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004009
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004010 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004011 /* Incomplete config. Send empty response. */
4012 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004013 l2cap_build_conf_rsp(chan, rsp,
4014 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004015 goto unlock;
4016 }
4017
4018 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004019 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004020 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004021 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004022 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004023 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004024
Mat Martineau1500109b2012-10-23 15:24:15 -07004025 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004026 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004027 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004028
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004029 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004030 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004031
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004032 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004033 goto unlock;
4034
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004035 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004036 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004037
Mat Martineau105bdf92012-04-27 16:50:48 -07004038 if (chan->mode == L2CAP_MODE_ERTM ||
4039 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004040 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004041
Mat Martineau3c588192012-04-11 10:48:42 -07004042 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004043 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004044 else
4045 l2cap_chan_ready(chan);
4046
Marcel Holtmann876d9482007-10-20 13:35:42 +02004047 goto unlock;
4048 }
4049
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004050 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004051 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004052 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004053 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004054 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004055 }
4056
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004057 /* Got Conf Rsp PENDING from remote side and asume we sent
4058 Conf Rsp PENDING in the code above */
4059 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004060 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004061
4062 /* check compatibility */
4063
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004064 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004065 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004066 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4067 else
4068 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004069 }
4070
Linus Torvalds1da177e2005-04-16 15:20:36 -07004071unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004072 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004073 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004074}
4075
Gustavo Padovan2d792812012-10-06 10:07:01 +01004076static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004077 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4078 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004079{
4080 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4081 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004082 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004083 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004084 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004085
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004086 if (cmd_len < sizeof(*rsp))
4087 return -EPROTO;
4088
Linus Torvalds1da177e2005-04-16 15:20:36 -07004089 scid = __le16_to_cpu(rsp->scid);
4090 flags = __le16_to_cpu(rsp->flags);
4091 result = __le16_to_cpu(rsp->result);
4092
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004093 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4094 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004095
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004096 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004097 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004098 return 0;
4099
4100 switch (result) {
4101 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004102 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004103 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004104 break;
4105
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004106 case L2CAP_CONF_PENDING:
4107 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4108
4109 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4110 char buf[64];
4111
4112 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004113 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004114 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004115 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004116 goto done;
4117 }
4118
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004119 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004120 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4121 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004122 } else {
4123 if (l2cap_check_efs(chan)) {
4124 amp_create_logical_link(chan);
4125 chan->ident = cmd->ident;
4126 }
4127 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004128 }
4129 goto done;
4130
Linus Torvalds1da177e2005-04-16 15:20:36 -07004131 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004132 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004133 char req[64];
4134
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004135 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004136 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004137 goto done;
4138 }
4139
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004140 /* throw out any old stored conf requests */
4141 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004142 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004143 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004144 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004145 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004146 goto done;
4147 }
4148
4149 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004150 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004151 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004152 if (result != L2CAP_CONF_SUCCESS)
4153 goto done;
4154 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004155 }
4156
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004157 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004158 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004159
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004160 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004161 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004162 goto done;
4163 }
4164
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004165 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004166 goto done;
4167
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004168 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004169
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004170 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004171 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004172
Mat Martineau105bdf92012-04-27 16:50:48 -07004173 if (chan->mode == L2CAP_MODE_ERTM ||
4174 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004175 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004176
Mat Martineau3c588192012-04-11 10:48:42 -07004177 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004178 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004179 else
4180 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004181 }
4182
4183done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004184 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004185 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004186}
4187
Gustavo Padovan2d792812012-10-06 10:07:01 +01004188static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004189 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4190 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004191{
4192 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4193 struct l2cap_disconn_rsp rsp;
4194 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004195 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004196
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004197 if (cmd_len != sizeof(*req))
4198 return -EPROTO;
4199
Linus Torvalds1da177e2005-04-16 15:20:36 -07004200 scid = __le16_to_cpu(req->scid);
4201 dcid = __le16_to_cpu(req->dcid);
4202
4203 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4204
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004205 mutex_lock(&conn->chan_lock);
4206
4207 chan = __l2cap_get_chan_by_scid(conn, dcid);
4208 if (!chan) {
4209 mutex_unlock(&conn->chan_lock);
Johan Hedberg662d6522013-10-16 11:20:47 +03004210 cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid);
4211 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004212 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004213
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004214 l2cap_chan_lock(chan);
4215
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004216 rsp.dcid = cpu_to_le16(chan->scid);
4217 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004218 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4219
Gustavo Padovan5ec1bbe2013-10-15 19:24:48 -03004220 chan->ops->set_shutdown(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004221
Mat Martineau61d6ef32012-04-27 16:50:50 -07004222 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004223 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004224
4225 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004226
Gustavo Padovan80b98022012-05-27 22:27:51 -03004227 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004228 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004229
4230 mutex_unlock(&conn->chan_lock);
4231
Linus Torvalds1da177e2005-04-16 15:20:36 -07004232 return 0;
4233}
4234
Gustavo Padovan2d792812012-10-06 10:07:01 +01004235static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004236 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4237 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004238{
4239 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4240 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004241 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004242
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004243 if (cmd_len != sizeof(*rsp))
4244 return -EPROTO;
4245
Linus Torvalds1da177e2005-04-16 15:20:36 -07004246 scid = __le16_to_cpu(rsp->scid);
4247 dcid = __le16_to_cpu(rsp->dcid);
4248
4249 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4250
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004251 mutex_lock(&conn->chan_lock);
4252
4253 chan = __l2cap_get_chan_by_scid(conn, scid);
4254 if (!chan) {
4255 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004256 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004257 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004258
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004259 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004260
Mat Martineau61d6ef32012-04-27 16:50:50 -07004261 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004262 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004263
4264 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004265
Gustavo Padovan80b98022012-05-27 22:27:51 -03004266 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004267 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004268
4269 mutex_unlock(&conn->chan_lock);
4270
Linus Torvalds1da177e2005-04-16 15:20:36 -07004271 return 0;
4272}
4273
Gustavo Padovan2d792812012-10-06 10:07:01 +01004274static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004275 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4276 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004277{
4278 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004279 u16 type;
4280
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004281 if (cmd_len != sizeof(*req))
4282 return -EPROTO;
4283
Linus Torvalds1da177e2005-04-16 15:20:36 -07004284 type = __le16_to_cpu(req->type);
4285
4286 BT_DBG("type 0x%4.4x", type);
4287
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004288 if (type == L2CAP_IT_FEAT_MASK) {
4289 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004290 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004291 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004292 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4293 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004294 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004295 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004296 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004297 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004298 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004299 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004300
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004301 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004302 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4303 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004304 } else if (type == L2CAP_IT_FIXED_CHAN) {
4305 u8 buf[12];
4306 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004307
Marcel Holtmann848566b2013-10-01 22:59:22 -07004308 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004309 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4310 else
4311 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4312
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004313 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4314 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004315 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004316 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4317 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004318 } else {
4319 struct l2cap_info_rsp rsp;
4320 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004321 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004322 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4323 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004324 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004325
4326 return 0;
4327}
4328
Gustavo Padovan2d792812012-10-06 10:07:01 +01004329static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004330 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4331 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004332{
4333 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4334 u16 type, result;
4335
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304336 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004337 return -EPROTO;
4338
Linus Torvalds1da177e2005-04-16 15:20:36 -07004339 type = __le16_to_cpu(rsp->type);
4340 result = __le16_to_cpu(rsp->result);
4341
4342 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4343
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004344 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4345 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004346 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004347 return 0;
4348
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004349 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004350
Ville Tervoadb08ed2010-08-04 09:43:33 +03004351 if (result != L2CAP_IR_SUCCESS) {
4352 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4353 conn->info_ident = 0;
4354
4355 l2cap_conn_start(conn);
4356
4357 return 0;
4358 }
4359
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004360 switch (type) {
4361 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004362 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004363
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004364 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004365 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004366 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004367
4368 conn->info_ident = l2cap_get_ident(conn);
4369
4370 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004371 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004372 } else {
4373 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4374 conn->info_ident = 0;
4375
4376 l2cap_conn_start(conn);
4377 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004378 break;
4379
4380 case L2CAP_IT_FIXED_CHAN:
4381 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004382 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004383 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004384
4385 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004386 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004387 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004388
Linus Torvalds1da177e2005-04-16 15:20:36 -07004389 return 0;
4390}
4391
Mat Martineau17009152012-10-23 15:24:07 -07004392static int l2cap_create_channel_req(struct l2cap_conn *conn,
4393 struct l2cap_cmd_hdr *cmd,
4394 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004395{
4396 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004397 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004398 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004399 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004400 u16 psm, scid;
4401
4402 if (cmd_len != sizeof(*req))
4403 return -EPROTO;
4404
Marcel Holtmann848566b2013-10-01 22:59:22 -07004405 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004406 return -EINVAL;
4407
4408 psm = le16_to_cpu(req->psm);
4409 scid = le16_to_cpu(req->scid);
4410
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004411 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 -07004412
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004413 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004414 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004415 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4416 req->amp_id);
4417 return 0;
4418 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004419
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004420 /* Validate AMP controller id */
4421 hdev = hci_dev_get(req->amp_id);
4422 if (!hdev)
4423 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004424
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004425 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004426 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004427 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004428 }
4429
4430 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4431 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004432 if (chan) {
4433 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4434 struct hci_conn *hs_hcon;
4435
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004436 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4437 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004438 if (!hs_hcon) {
4439 hci_dev_put(hdev);
Johan Hedberg662d6522013-10-16 11:20:47 +03004440 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4441 chan->dcid);
4442 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004443 }
4444
4445 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4446
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004447 mgr->bredr_chan = chan;
4448 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004449 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004450 conn->mtu = hdev->block_mtu;
4451 }
4452
4453 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004454
4455 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004456
4457error:
4458 rsp.dcid = 0;
4459 rsp.scid = cpu_to_le16(scid);
4460 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4461 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4462
4463 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4464 sizeof(rsp), &rsp);
4465
Johan Hedbergdc280802013-09-16 13:05:13 +03004466 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004467}
4468
Mat Martineau8eb200b2012-10-23 15:24:17 -07004469static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4470{
4471 struct l2cap_move_chan_req req;
4472 u8 ident;
4473
4474 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4475
4476 ident = l2cap_get_ident(chan->conn);
4477 chan->ident = ident;
4478
4479 req.icid = cpu_to_le16(chan->scid);
4480 req.dest_amp_id = dest_amp_id;
4481
4482 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4483 &req);
4484
4485 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4486}
4487
Mat Martineau1500109b2012-10-23 15:24:15 -07004488static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004489{
4490 struct l2cap_move_chan_rsp rsp;
4491
Mat Martineau1500109b2012-10-23 15:24:15 -07004492 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004493
Mat Martineau1500109b2012-10-23 15:24:15 -07004494 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004495 rsp.result = cpu_to_le16(result);
4496
Mat Martineau1500109b2012-10-23 15:24:15 -07004497 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4498 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004499}
4500
Mat Martineau5b155ef2012-10-23 15:24:14 -07004501static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004502{
4503 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004504
Mat Martineau5b155ef2012-10-23 15:24:14 -07004505 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004506
Mat Martineau5b155ef2012-10-23 15:24:14 -07004507 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004508
Mat Martineau5b155ef2012-10-23 15:24:14 -07004509 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004510 cfm.result = cpu_to_le16(result);
4511
Mat Martineau5b155ef2012-10-23 15:24:14 -07004512 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4513 sizeof(cfm), &cfm);
4514
4515 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4516}
4517
4518static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4519{
4520 struct l2cap_move_chan_cfm cfm;
4521
4522 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4523
4524 cfm.icid = cpu_to_le16(icid);
4525 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4526
4527 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4528 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004529}
4530
4531static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004532 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004533{
4534 struct l2cap_move_chan_cfm_rsp rsp;
4535
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004536 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004537
4538 rsp.icid = cpu_to_le16(icid);
4539 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4540}
4541
Mat Martineau5f3847a2012-10-23 15:24:12 -07004542static void __release_logical_link(struct l2cap_chan *chan)
4543{
4544 chan->hs_hchan = NULL;
4545 chan->hs_hcon = NULL;
4546
4547 /* Placeholder - release the logical link */
4548}
4549
Mat Martineau1500109b2012-10-23 15:24:15 -07004550static void l2cap_logical_fail(struct l2cap_chan *chan)
4551{
4552 /* Logical link setup failed */
4553 if (chan->state != BT_CONNECTED) {
4554 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004555 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004556 return;
4557 }
4558
4559 switch (chan->move_role) {
4560 case L2CAP_MOVE_ROLE_RESPONDER:
4561 l2cap_move_done(chan);
4562 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4563 break;
4564 case L2CAP_MOVE_ROLE_INITIATOR:
4565 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4566 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4567 /* Remote has only sent pending or
4568 * success responses, clean up
4569 */
4570 l2cap_move_done(chan);
4571 }
4572
4573 /* Other amp move states imply that the move
4574 * has already aborted
4575 */
4576 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4577 break;
4578 }
4579}
4580
4581static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4582 struct hci_chan *hchan)
4583{
4584 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004585
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004586 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004587 chan->hs_hcon->l2cap_data = chan->conn;
4588
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004589 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004590
4591 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004592 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004593
4594 set_default_fcs(chan);
4595
4596 err = l2cap_ertm_init(chan);
4597 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004598 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004599 else
4600 l2cap_chan_ready(chan);
4601 }
4602}
4603
4604static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4605 struct hci_chan *hchan)
4606{
4607 chan->hs_hcon = hchan->conn;
4608 chan->hs_hcon->l2cap_data = chan->conn;
4609
4610 BT_DBG("move_state %d", chan->move_state);
4611
4612 switch (chan->move_state) {
4613 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4614 /* Move confirm will be sent after a success
4615 * response is received
4616 */
4617 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4618 break;
4619 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4620 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4621 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4622 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4623 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4624 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4625 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4626 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4627 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4628 }
4629 break;
4630 default:
4631 /* Move was not in expected state, free the channel */
4632 __release_logical_link(chan);
4633
4634 chan->move_state = L2CAP_MOVE_STABLE;
4635 }
4636}
4637
4638/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004639void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4640 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004641{
Mat Martineau1500109b2012-10-23 15:24:15 -07004642 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4643
4644 if (status) {
4645 l2cap_logical_fail(chan);
4646 __release_logical_link(chan);
4647 return;
4648 }
4649
4650 if (chan->state != BT_CONNECTED) {
4651 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004652 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004653 l2cap_logical_finish_create(chan, hchan);
4654 } else {
4655 l2cap_logical_finish_move(chan, hchan);
4656 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004657}
4658
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004659void l2cap_move_start(struct l2cap_chan *chan)
4660{
4661 BT_DBG("chan %p", chan);
4662
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004663 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004664 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4665 return;
4666 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4667 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4668 /* Placeholder - start physical link setup */
4669 } else {
4670 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4671 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4672 chan->move_id = 0;
4673 l2cap_move_setup(chan);
4674 l2cap_send_move_chan_req(chan, 0);
4675 }
4676}
4677
Mat Martineau8eb200b2012-10-23 15:24:17 -07004678static void l2cap_do_create(struct l2cap_chan *chan, int result,
4679 u8 local_amp_id, u8 remote_amp_id)
4680{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004681 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4682 local_amp_id, remote_amp_id);
4683
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004684 chan->fcs = L2CAP_FCS_NONE;
4685
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004686 /* Outgoing channel on AMP */
4687 if (chan->state == BT_CONNECT) {
4688 if (result == L2CAP_CR_SUCCESS) {
4689 chan->local_amp_id = local_amp_id;
4690 l2cap_send_create_chan_req(chan, remote_amp_id);
4691 } else {
4692 /* Revert to BR/EDR connect */
4693 l2cap_send_conn_req(chan);
4694 }
4695
4696 return;
4697 }
4698
4699 /* Incoming channel on AMP */
4700 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004701 struct l2cap_conn_rsp rsp;
4702 char buf[128];
4703 rsp.scid = cpu_to_le16(chan->dcid);
4704 rsp.dcid = cpu_to_le16(chan->scid);
4705
Mat Martineau8eb200b2012-10-23 15:24:17 -07004706 if (result == L2CAP_CR_SUCCESS) {
4707 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004708 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4709 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004710 } else {
4711 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004712 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4713 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004714 }
4715
4716 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4717 sizeof(rsp), &rsp);
4718
4719 if (result == L2CAP_CR_SUCCESS) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004720 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004721 set_bit(CONF_REQ_SENT, &chan->conf_state);
4722 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4723 L2CAP_CONF_REQ,
4724 l2cap_build_conf_req(chan, buf), buf);
4725 chan->num_conf_req++;
4726 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004727 }
4728}
4729
4730static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4731 u8 remote_amp_id)
4732{
4733 l2cap_move_setup(chan);
4734 chan->move_id = local_amp_id;
4735 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4736
4737 l2cap_send_move_chan_req(chan, remote_amp_id);
4738}
4739
4740static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4741{
4742 struct hci_chan *hchan = NULL;
4743
4744 /* Placeholder - get hci_chan for logical link */
4745
4746 if (hchan) {
4747 if (hchan->state == BT_CONNECTED) {
4748 /* Logical link is ready to go */
4749 chan->hs_hcon = hchan->conn;
4750 chan->hs_hcon->l2cap_data = chan->conn;
4751 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4752 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4753
4754 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4755 } else {
4756 /* Wait for logical link to be ready */
4757 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4758 }
4759 } else {
4760 /* Logical link not available */
4761 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4762 }
4763}
4764
4765static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4766{
4767 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4768 u8 rsp_result;
4769 if (result == -EINVAL)
4770 rsp_result = L2CAP_MR_BAD_ID;
4771 else
4772 rsp_result = L2CAP_MR_NOT_ALLOWED;
4773
4774 l2cap_send_move_chan_rsp(chan, rsp_result);
4775 }
4776
4777 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4778 chan->move_state = L2CAP_MOVE_STABLE;
4779
4780 /* Restart data transmission */
4781 l2cap_ertm_send(chan);
4782}
4783
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004784/* Invoke with locked chan */
4785void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004786{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004787 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004788 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004789
Mat Martineau8eb200b2012-10-23 15:24:17 -07004790 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4791 chan, result, local_amp_id, remote_amp_id);
4792
Mat Martineau8eb200b2012-10-23 15:24:17 -07004793 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4794 l2cap_chan_unlock(chan);
4795 return;
4796 }
4797
4798 if (chan->state != BT_CONNECTED) {
4799 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4800 } else if (result != L2CAP_MR_SUCCESS) {
4801 l2cap_do_move_cancel(chan, result);
4802 } else {
4803 switch (chan->move_role) {
4804 case L2CAP_MOVE_ROLE_INITIATOR:
4805 l2cap_do_move_initiate(chan, local_amp_id,
4806 remote_amp_id);
4807 break;
4808 case L2CAP_MOVE_ROLE_RESPONDER:
4809 l2cap_do_move_respond(chan, result);
4810 break;
4811 default:
4812 l2cap_do_move_cancel(chan, result);
4813 break;
4814 }
4815 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004816}
4817
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004818static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004819 struct l2cap_cmd_hdr *cmd,
4820 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004821{
4822 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004823 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004824 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004825 u16 icid = 0;
4826 u16 result = L2CAP_MR_NOT_ALLOWED;
4827
4828 if (cmd_len != sizeof(*req))
4829 return -EPROTO;
4830
4831 icid = le16_to_cpu(req->icid);
4832
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004833 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004834
Marcel Holtmann848566b2013-10-01 22:59:22 -07004835 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004836 return -EINVAL;
4837
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004838 chan = l2cap_get_chan_by_dcid(conn, icid);
4839 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004840 rsp.icid = cpu_to_le16(icid);
4841 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4842 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4843 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004844 return 0;
4845 }
4846
Mat Martineau1500109b2012-10-23 15:24:15 -07004847 chan->ident = cmd->ident;
4848
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004849 if (chan->scid < L2CAP_CID_DYN_START ||
4850 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4851 (chan->mode != L2CAP_MODE_ERTM &&
4852 chan->mode != L2CAP_MODE_STREAMING)) {
4853 result = L2CAP_MR_NOT_ALLOWED;
4854 goto send_move_response;
4855 }
4856
4857 if (chan->local_amp_id == req->dest_amp_id) {
4858 result = L2CAP_MR_SAME_ID;
4859 goto send_move_response;
4860 }
4861
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004862 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004863 struct hci_dev *hdev;
4864 hdev = hci_dev_get(req->dest_amp_id);
4865 if (!hdev || hdev->dev_type != HCI_AMP ||
4866 !test_bit(HCI_UP, &hdev->flags)) {
4867 if (hdev)
4868 hci_dev_put(hdev);
4869
4870 result = L2CAP_MR_BAD_ID;
4871 goto send_move_response;
4872 }
4873 hci_dev_put(hdev);
4874 }
4875
4876 /* Detect a move collision. Only send a collision response
4877 * if this side has "lost", otherwise proceed with the move.
4878 * The winner has the larger bd_addr.
4879 */
4880 if ((__chan_is_moving(chan) ||
4881 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07004882 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004883 result = L2CAP_MR_COLLISION;
4884 goto send_move_response;
4885 }
4886
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004887 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4888 l2cap_move_setup(chan);
4889 chan->move_id = req->dest_amp_id;
4890 icid = chan->dcid;
4891
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004892 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004893 /* Moving to BR/EDR */
4894 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4895 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4896 result = L2CAP_MR_PEND;
4897 } else {
4898 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4899 result = L2CAP_MR_SUCCESS;
4900 }
4901 } else {
4902 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4903 /* Placeholder - uncomment when amp functions are available */
4904 /*amp_accept_physical(chan, req->dest_amp_id);*/
4905 result = L2CAP_MR_PEND;
4906 }
4907
4908send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004909 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004910
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004911 l2cap_chan_unlock(chan);
4912
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004913 return 0;
4914}
4915
Mat Martineau5b155ef2012-10-23 15:24:14 -07004916static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4917{
4918 struct l2cap_chan *chan;
4919 struct hci_chan *hchan = NULL;
4920
4921 chan = l2cap_get_chan_by_scid(conn, icid);
4922 if (!chan) {
4923 l2cap_send_move_chan_cfm_icid(conn, icid);
4924 return;
4925 }
4926
4927 __clear_chan_timer(chan);
4928 if (result == L2CAP_MR_PEND)
4929 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4930
4931 switch (chan->move_state) {
4932 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4933 /* Move confirm will be sent when logical link
4934 * is complete.
4935 */
4936 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4937 break;
4938 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4939 if (result == L2CAP_MR_PEND) {
4940 break;
4941 } else if (test_bit(CONN_LOCAL_BUSY,
4942 &chan->conn_state)) {
4943 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4944 } else {
4945 /* Logical link is up or moving to BR/EDR,
4946 * proceed with move
4947 */
4948 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4949 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4950 }
4951 break;
4952 case L2CAP_MOVE_WAIT_RSP:
4953 /* Moving to AMP */
4954 if (result == L2CAP_MR_SUCCESS) {
4955 /* Remote is ready, send confirm immediately
4956 * after logical link is ready
4957 */
4958 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4959 } else {
4960 /* Both logical link and move success
4961 * are required to confirm
4962 */
4963 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4964 }
4965
4966 /* Placeholder - get hci_chan for logical link */
4967 if (!hchan) {
4968 /* Logical link not available */
4969 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4970 break;
4971 }
4972
4973 /* If the logical link is not yet connected, do not
4974 * send confirmation.
4975 */
4976 if (hchan->state != BT_CONNECTED)
4977 break;
4978
4979 /* Logical link is already ready to go */
4980
4981 chan->hs_hcon = hchan->conn;
4982 chan->hs_hcon->l2cap_data = chan->conn;
4983
4984 if (result == L2CAP_MR_SUCCESS) {
4985 /* Can confirm now */
4986 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4987 } else {
4988 /* Now only need move success
4989 * to confirm
4990 */
4991 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4992 }
4993
4994 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4995 break;
4996 default:
4997 /* Any other amp move state means the move failed. */
4998 chan->move_id = chan->local_amp_id;
4999 l2cap_move_done(chan);
5000 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5001 }
5002
5003 l2cap_chan_unlock(chan);
5004}
5005
5006static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5007 u16 result)
5008{
5009 struct l2cap_chan *chan;
5010
5011 chan = l2cap_get_chan_by_ident(conn, ident);
5012 if (!chan) {
5013 /* Could not locate channel, icid is best guess */
5014 l2cap_send_move_chan_cfm_icid(conn, icid);
5015 return;
5016 }
5017
5018 __clear_chan_timer(chan);
5019
5020 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5021 if (result == L2CAP_MR_COLLISION) {
5022 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5023 } else {
5024 /* Cleanup - cancel move */
5025 chan->move_id = chan->local_amp_id;
5026 l2cap_move_done(chan);
5027 }
5028 }
5029
5030 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5031
5032 l2cap_chan_unlock(chan);
5033}
5034
5035static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5036 struct l2cap_cmd_hdr *cmd,
5037 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005038{
5039 struct l2cap_move_chan_rsp *rsp = data;
5040 u16 icid, result;
5041
5042 if (cmd_len != sizeof(*rsp))
5043 return -EPROTO;
5044
5045 icid = le16_to_cpu(rsp->icid);
5046 result = le16_to_cpu(rsp->result);
5047
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005048 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005049
Mat Martineau5b155ef2012-10-23 15:24:14 -07005050 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5051 l2cap_move_continue(conn, icid, result);
5052 else
5053 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005054
5055 return 0;
5056}
5057
Mat Martineau5f3847a2012-10-23 15:24:12 -07005058static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5059 struct l2cap_cmd_hdr *cmd,
5060 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005061{
5062 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005063 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005064 u16 icid, result;
5065
5066 if (cmd_len != sizeof(*cfm))
5067 return -EPROTO;
5068
5069 icid = le16_to_cpu(cfm->icid);
5070 result = le16_to_cpu(cfm->result);
5071
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005072 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005073
Mat Martineau5f3847a2012-10-23 15:24:12 -07005074 chan = l2cap_get_chan_by_dcid(conn, icid);
5075 if (!chan) {
5076 /* Spec requires a response even if the icid was not found */
5077 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5078 return 0;
5079 }
5080
5081 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5082 if (result == L2CAP_MC_CONFIRMED) {
5083 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005084 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005085 __release_logical_link(chan);
5086 } else {
5087 chan->move_id = chan->local_amp_id;
5088 }
5089
5090 l2cap_move_done(chan);
5091 }
5092
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005093 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5094
Mat Martineau5f3847a2012-10-23 15:24:12 -07005095 l2cap_chan_unlock(chan);
5096
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005097 return 0;
5098}
5099
5100static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005101 struct l2cap_cmd_hdr *cmd,
5102 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005103{
5104 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005105 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005106 u16 icid;
5107
5108 if (cmd_len != sizeof(*rsp))
5109 return -EPROTO;
5110
5111 icid = le16_to_cpu(rsp->icid);
5112
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005113 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005114
Mat Martineau3fd71a02012-10-23 15:24:16 -07005115 chan = l2cap_get_chan_by_scid(conn, icid);
5116 if (!chan)
5117 return 0;
5118
5119 __clear_chan_timer(chan);
5120
5121 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5122 chan->local_amp_id = chan->move_id;
5123
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005124 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005125 __release_logical_link(chan);
5126
5127 l2cap_move_done(chan);
5128 }
5129
5130 l2cap_chan_unlock(chan);
5131
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005132 return 0;
5133}
5134
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005135static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005136 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005137{
5138 u16 max_latency;
5139
5140 if (min > max || min < 6 || max > 3200)
5141 return -EINVAL;
5142
5143 if (to_multiplier < 10 || to_multiplier > 3200)
5144 return -EINVAL;
5145
5146 if (max >= to_multiplier * 8)
5147 return -EINVAL;
5148
5149 max_latency = (to_multiplier * 8 / max) - 1;
5150 if (latency > 499 || latency > max_latency)
5151 return -EINVAL;
5152
5153 return 0;
5154}
5155
5156static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005157 struct l2cap_cmd_hdr *cmd,
5158 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005159{
5160 struct hci_conn *hcon = conn->hcon;
5161 struct l2cap_conn_param_update_req *req;
5162 struct l2cap_conn_param_update_rsp rsp;
5163 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005164 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005165
5166 if (!(hcon->link_mode & HCI_LM_MASTER))
5167 return -EINVAL;
5168
5169 cmd_len = __le16_to_cpu(cmd->len);
5170 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5171 return -EPROTO;
5172
5173 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005174 min = __le16_to_cpu(req->min);
5175 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005176 latency = __le16_to_cpu(req->latency);
5177 to_multiplier = __le16_to_cpu(req->to_multiplier);
5178
5179 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 +01005180 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005181
5182 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005183
5184 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5185 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005186 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005187 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005188 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005189
5190 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005191 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005192
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005193 if (!err)
5194 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5195
Claudio Takahaside731152011-02-11 19:28:55 -02005196 return 0;
5197}
5198
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005199static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005200 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5201 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005202{
5203 int err = 0;
5204
5205 switch (cmd->code) {
5206 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005207 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005208 break;
5209
5210 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005211 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005212 break;
5213
5214 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005215 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005216 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005217 break;
5218
5219 case L2CAP_CONF_REQ:
5220 err = l2cap_config_req(conn, cmd, cmd_len, data);
5221 break;
5222
5223 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005224 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005225 break;
5226
5227 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005228 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005229 break;
5230
5231 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005232 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005233 break;
5234
5235 case L2CAP_ECHO_REQ:
5236 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5237 break;
5238
5239 case L2CAP_ECHO_RSP:
5240 break;
5241
5242 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005243 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005244 break;
5245
5246 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005247 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005248 break;
5249
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005250 case L2CAP_CREATE_CHAN_REQ:
5251 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5252 break;
5253
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005254 case L2CAP_MOVE_CHAN_REQ:
5255 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5256 break;
5257
5258 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005259 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005260 break;
5261
5262 case L2CAP_MOVE_CHAN_CFM:
5263 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5264 break;
5265
5266 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005267 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005268 break;
5269
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005270 default:
5271 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5272 err = -EINVAL;
5273 break;
5274 }
5275
5276 return err;
5277}
5278
5279static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005280 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005281{
5282 switch (cmd->code) {
5283 case L2CAP_COMMAND_REJ:
5284 return 0;
5285
5286 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005287 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005288
5289 case L2CAP_CONN_PARAM_UPDATE_RSP:
5290 return 0;
5291
5292 default:
5293 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5294 return -EINVAL;
5295 }
5296}
5297
Johan Hedbergc5623552013-04-29 19:35:33 +03005298static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5299 struct sk_buff *skb)
5300{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005301 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005302 struct l2cap_cmd_hdr *cmd;
5303 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005304 int err;
5305
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005306 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005307 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005308
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005309 if (skb->len < L2CAP_CMD_HDR_SIZE)
5310 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005311
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005312 cmd = (void *) skb->data;
5313 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005314
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005315 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005316
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005317 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005318
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005319 if (len != skb->len || !cmd->ident) {
5320 BT_DBG("corrupted command");
5321 goto drop;
5322 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005323
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005324 err = l2cap_le_sig_cmd(conn, cmd, skb->data);
5325 if (err) {
5326 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005327
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005328 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005329
Johan Hedberga5211492013-10-16 11:20:49 +03005330 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005331 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5332 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005333 }
5334
Marcel Holtmann3b166292013-10-02 08:28:21 -07005335drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005336 kfree_skb(skb);
5337}
5338
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005339static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005340 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005341{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005342 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005343 u8 *data = skb->data;
5344 int len = skb->len;
5345 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005346 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005347
5348 l2cap_raw_recv(conn, skb);
5349
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005350 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005351 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005352
Linus Torvalds1da177e2005-04-16 15:20:36 -07005353 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005354 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005355 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5356 data += L2CAP_CMD_HDR_SIZE;
5357 len -= L2CAP_CMD_HDR_SIZE;
5358
Al Viro88219a02007-07-29 00:17:25 -07005359 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005360
Gustavo Padovan2d792812012-10-06 10:07:01 +01005361 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5362 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005363
Al Viro88219a02007-07-29 00:17:25 -07005364 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005365 BT_DBG("corrupted command");
5366 break;
5367 }
5368
Johan Hedbergc5623552013-04-29 19:35:33 +03005369 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005370 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005371 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005372
5373 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005374
Johan Hedberga5211492013-10-16 11:20:49 +03005375 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005376 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5377 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005378 }
5379
Al Viro88219a02007-07-29 00:17:25 -07005380 data += cmd_len;
5381 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005382 }
5383
Marcel Holtmann3b166292013-10-02 08:28:21 -07005384drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005385 kfree_skb(skb);
5386}
5387
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005388static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005389{
5390 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005391 int hdr_size;
5392
5393 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5394 hdr_size = L2CAP_EXT_HDR_SIZE;
5395 else
5396 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005397
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005398 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005399 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005400 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5401 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5402
5403 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005404 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005405 }
5406 return 0;
5407}
5408
Mat Martineau6ea00482012-05-17 20:53:52 -07005409static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005410{
Mat Martineaue31f7632012-05-17 20:53:41 -07005411 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005412
Mat Martineaue31f7632012-05-17 20:53:41 -07005413 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005414
Mat Martineaue31f7632012-05-17 20:53:41 -07005415 memset(&control, 0, sizeof(control));
5416 control.sframe = 1;
5417 control.final = 1;
5418 control.reqseq = chan->buffer_seq;
5419 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005420
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005421 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005422 control.super = L2CAP_SUPER_RNR;
5423 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005424 }
5425
Mat Martineaue31f7632012-05-17 20:53:41 -07005426 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5427 chan->unacked_frames > 0)
5428 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005429
Mat Martineaue31f7632012-05-17 20:53:41 -07005430 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005431 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005432
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005433 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005434 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5435 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5436 * send it now.
5437 */
5438 control.super = L2CAP_SUPER_RR;
5439 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005440 }
5441}
5442
Gustavo Padovan2d792812012-10-06 10:07:01 +01005443static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5444 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005445{
Mat Martineau84084a32011-07-22 14:54:00 -07005446 /* skb->len reflects data in skb as well as all fragments
5447 * skb->data_len reflects only data in fragments
5448 */
5449 if (!skb_has_frag_list(skb))
5450 skb_shinfo(skb)->frag_list = new_frag;
5451
5452 new_frag->next = NULL;
5453
5454 (*last_frag)->next = new_frag;
5455 *last_frag = new_frag;
5456
5457 skb->len += new_frag->len;
5458 skb->data_len += new_frag->len;
5459 skb->truesize += new_frag->truesize;
5460}
5461
Mat Martineau4b51dae92012-05-17 20:53:37 -07005462static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5463 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005464{
5465 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005466
Mat Martineau4b51dae92012-05-17 20:53:37 -07005467 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005468 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005469 if (chan->sdu)
5470 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005471
Gustavo Padovan80b98022012-05-27 22:27:51 -03005472 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005473 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005474
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005475 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005476 if (chan->sdu)
5477 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005478
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005479 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005480 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005481
Mat Martineau84084a32011-07-22 14:54:00 -07005482 if (chan->sdu_len > chan->imtu) {
5483 err = -EMSGSIZE;
5484 break;
5485 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005486
Mat Martineau84084a32011-07-22 14:54:00 -07005487 if (skb->len >= chan->sdu_len)
5488 break;
5489
5490 chan->sdu = skb;
5491 chan->sdu_last_frag = skb;
5492
5493 skb = NULL;
5494 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005495 break;
5496
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005497 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005498 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005499 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005500
Mat Martineau84084a32011-07-22 14:54:00 -07005501 append_skb_frag(chan->sdu, skb,
5502 &chan->sdu_last_frag);
5503 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005504
Mat Martineau84084a32011-07-22 14:54:00 -07005505 if (chan->sdu->len >= chan->sdu_len)
5506 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005507
Mat Martineau84084a32011-07-22 14:54:00 -07005508 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005509 break;
5510
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005511 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005512 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005513 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005514
Mat Martineau84084a32011-07-22 14:54:00 -07005515 append_skb_frag(chan->sdu, skb,
5516 &chan->sdu_last_frag);
5517 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005518
Mat Martineau84084a32011-07-22 14:54:00 -07005519 if (chan->sdu->len != chan->sdu_len)
5520 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005521
Gustavo Padovan80b98022012-05-27 22:27:51 -03005522 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005523
Mat Martineau84084a32011-07-22 14:54:00 -07005524 if (!err) {
5525 /* Reassembly complete */
5526 chan->sdu = NULL;
5527 chan->sdu_last_frag = NULL;
5528 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005529 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005530 break;
5531 }
5532
Mat Martineau84084a32011-07-22 14:54:00 -07005533 if (err) {
5534 kfree_skb(skb);
5535 kfree_skb(chan->sdu);
5536 chan->sdu = NULL;
5537 chan->sdu_last_frag = NULL;
5538 chan->sdu_len = 0;
5539 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005540
Mat Martineau84084a32011-07-22 14:54:00 -07005541 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005542}
5543
Mat Martineau32b32732012-10-23 15:24:11 -07005544static int l2cap_resegment(struct l2cap_chan *chan)
5545{
5546 /* Placeholder */
5547 return 0;
5548}
5549
Mat Martineaue3281402011-07-07 09:39:02 -07005550void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005551{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005552 u8 event;
5553
5554 if (chan->mode != L2CAP_MODE_ERTM)
5555 return;
5556
5557 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005558 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005559}
5560
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005561static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5562{
Mat Martineau63838722012-05-17 20:53:45 -07005563 int err = 0;
5564 /* Pass sequential frames to l2cap_reassemble_sdu()
5565 * until a gap is encountered.
5566 */
5567
5568 BT_DBG("chan %p", chan);
5569
5570 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5571 struct sk_buff *skb;
5572 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5573 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5574
5575 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5576
5577 if (!skb)
5578 break;
5579
5580 skb_unlink(skb, &chan->srej_q);
5581 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5582 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5583 if (err)
5584 break;
5585 }
5586
5587 if (skb_queue_empty(&chan->srej_q)) {
5588 chan->rx_state = L2CAP_RX_STATE_RECV;
5589 l2cap_send_ack(chan);
5590 }
5591
5592 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005593}
5594
5595static void l2cap_handle_srej(struct l2cap_chan *chan,
5596 struct l2cap_ctrl *control)
5597{
Mat Martineauf80842a2012-05-17 20:53:46 -07005598 struct sk_buff *skb;
5599
5600 BT_DBG("chan %p, control %p", chan, control);
5601
5602 if (control->reqseq == chan->next_tx_seq) {
5603 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005604 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005605 return;
5606 }
5607
5608 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5609
5610 if (skb == NULL) {
5611 BT_DBG("Seq %d not available for retransmission",
5612 control->reqseq);
5613 return;
5614 }
5615
5616 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5617 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005618 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005619 return;
5620 }
5621
5622 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5623
5624 if (control->poll) {
5625 l2cap_pass_to_tx(chan, control);
5626
5627 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5628 l2cap_retransmit(chan, control);
5629 l2cap_ertm_send(chan);
5630
5631 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5632 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5633 chan->srej_save_reqseq = control->reqseq;
5634 }
5635 } else {
5636 l2cap_pass_to_tx_fbit(chan, control);
5637
5638 if (control->final) {
5639 if (chan->srej_save_reqseq != control->reqseq ||
5640 !test_and_clear_bit(CONN_SREJ_ACT,
5641 &chan->conn_state))
5642 l2cap_retransmit(chan, control);
5643 } else {
5644 l2cap_retransmit(chan, control);
5645 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5646 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5647 chan->srej_save_reqseq = control->reqseq;
5648 }
5649 }
5650 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005651}
5652
5653static void l2cap_handle_rej(struct l2cap_chan *chan,
5654 struct l2cap_ctrl *control)
5655{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005656 struct sk_buff *skb;
5657
5658 BT_DBG("chan %p, control %p", chan, control);
5659
5660 if (control->reqseq == chan->next_tx_seq) {
5661 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005662 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005663 return;
5664 }
5665
5666 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5667
5668 if (chan->max_tx && skb &&
5669 bt_cb(skb)->control.retries >= chan->max_tx) {
5670 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005671 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005672 return;
5673 }
5674
5675 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5676
5677 l2cap_pass_to_tx(chan, control);
5678
5679 if (control->final) {
5680 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5681 l2cap_retransmit_all(chan, control);
5682 } else {
5683 l2cap_retransmit_all(chan, control);
5684 l2cap_ertm_send(chan);
5685 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5686 set_bit(CONN_REJ_ACT, &chan->conn_state);
5687 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005688}
5689
Mat Martineau4b51dae92012-05-17 20:53:37 -07005690static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5691{
5692 BT_DBG("chan %p, txseq %d", chan, txseq);
5693
5694 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5695 chan->expected_tx_seq);
5696
5697 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5698 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005699 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005700 /* See notes below regarding "double poll" and
5701 * invalid packets.
5702 */
5703 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5704 BT_DBG("Invalid/Ignore - after SREJ");
5705 return L2CAP_TXSEQ_INVALID_IGNORE;
5706 } else {
5707 BT_DBG("Invalid - in window after SREJ sent");
5708 return L2CAP_TXSEQ_INVALID;
5709 }
5710 }
5711
5712 if (chan->srej_list.head == txseq) {
5713 BT_DBG("Expected SREJ");
5714 return L2CAP_TXSEQ_EXPECTED_SREJ;
5715 }
5716
5717 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5718 BT_DBG("Duplicate SREJ - txseq already stored");
5719 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5720 }
5721
5722 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5723 BT_DBG("Unexpected SREJ - not requested");
5724 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5725 }
5726 }
5727
5728 if (chan->expected_tx_seq == txseq) {
5729 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5730 chan->tx_win) {
5731 BT_DBG("Invalid - txseq outside tx window");
5732 return L2CAP_TXSEQ_INVALID;
5733 } else {
5734 BT_DBG("Expected");
5735 return L2CAP_TXSEQ_EXPECTED;
5736 }
5737 }
5738
5739 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005740 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005741 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5742 return L2CAP_TXSEQ_DUPLICATE;
5743 }
5744
5745 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5746 /* A source of invalid packets is a "double poll" condition,
5747 * where delays cause us to send multiple poll packets. If
5748 * the remote stack receives and processes both polls,
5749 * sequence numbers can wrap around in such a way that a
5750 * resent frame has a sequence number that looks like new data
5751 * with a sequence gap. This would trigger an erroneous SREJ
5752 * request.
5753 *
5754 * Fortunately, this is impossible with a tx window that's
5755 * less than half of the maximum sequence number, which allows
5756 * invalid frames to be safely ignored.
5757 *
5758 * With tx window sizes greater than half of the tx window
5759 * maximum, the frame is invalid and cannot be ignored. This
5760 * causes a disconnect.
5761 */
5762
5763 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5764 BT_DBG("Invalid/Ignore - txseq outside tx window");
5765 return L2CAP_TXSEQ_INVALID_IGNORE;
5766 } else {
5767 BT_DBG("Invalid - txseq outside tx window");
5768 return L2CAP_TXSEQ_INVALID;
5769 }
5770 } else {
5771 BT_DBG("Unexpected - txseq indicates missing frames");
5772 return L2CAP_TXSEQ_UNEXPECTED;
5773 }
5774}
5775
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005776static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5777 struct l2cap_ctrl *control,
5778 struct sk_buff *skb, u8 event)
5779{
5780 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005781 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005782
5783 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5784 event);
5785
5786 switch (event) {
5787 case L2CAP_EV_RECV_IFRAME:
5788 switch (l2cap_classify_txseq(chan, control->txseq)) {
5789 case L2CAP_TXSEQ_EXPECTED:
5790 l2cap_pass_to_tx(chan, control);
5791
5792 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5793 BT_DBG("Busy, discarding expected seq %d",
5794 control->txseq);
5795 break;
5796 }
5797
5798 chan->expected_tx_seq = __next_seq(chan,
5799 control->txseq);
5800
5801 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005802 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005803
5804 err = l2cap_reassemble_sdu(chan, skb, control);
5805 if (err)
5806 break;
5807
5808 if (control->final) {
5809 if (!test_and_clear_bit(CONN_REJ_ACT,
5810 &chan->conn_state)) {
5811 control->final = 0;
5812 l2cap_retransmit_all(chan, control);
5813 l2cap_ertm_send(chan);
5814 }
5815 }
5816
5817 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5818 l2cap_send_ack(chan);
5819 break;
5820 case L2CAP_TXSEQ_UNEXPECTED:
5821 l2cap_pass_to_tx(chan, control);
5822
5823 /* Can't issue SREJ frames in the local busy state.
5824 * Drop this frame, it will be seen as missing
5825 * when local busy is exited.
5826 */
5827 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5828 BT_DBG("Busy, discarding unexpected seq %d",
5829 control->txseq);
5830 break;
5831 }
5832
5833 /* There was a gap in the sequence, so an SREJ
5834 * must be sent for each missing frame. The
5835 * current frame is stored for later use.
5836 */
5837 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005838 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005839 BT_DBG("Queued %p (queue len %d)", skb,
5840 skb_queue_len(&chan->srej_q));
5841
5842 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5843 l2cap_seq_list_clear(&chan->srej_list);
5844 l2cap_send_srej(chan, control->txseq);
5845
5846 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5847 break;
5848 case L2CAP_TXSEQ_DUPLICATE:
5849 l2cap_pass_to_tx(chan, control);
5850 break;
5851 case L2CAP_TXSEQ_INVALID_IGNORE:
5852 break;
5853 case L2CAP_TXSEQ_INVALID:
5854 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005855 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005856 break;
5857 }
5858 break;
5859 case L2CAP_EV_RECV_RR:
5860 l2cap_pass_to_tx(chan, control);
5861 if (control->final) {
5862 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5863
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005864 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5865 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005866 control->final = 0;
5867 l2cap_retransmit_all(chan, control);
5868 }
5869
5870 l2cap_ertm_send(chan);
5871 } else if (control->poll) {
5872 l2cap_send_i_or_rr_or_rnr(chan);
5873 } else {
5874 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5875 &chan->conn_state) &&
5876 chan->unacked_frames)
5877 __set_retrans_timer(chan);
5878
5879 l2cap_ertm_send(chan);
5880 }
5881 break;
5882 case L2CAP_EV_RECV_RNR:
5883 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5884 l2cap_pass_to_tx(chan, control);
5885 if (control && control->poll) {
5886 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5887 l2cap_send_rr_or_rnr(chan, 0);
5888 }
5889 __clear_retrans_timer(chan);
5890 l2cap_seq_list_clear(&chan->retrans_list);
5891 break;
5892 case L2CAP_EV_RECV_REJ:
5893 l2cap_handle_rej(chan, control);
5894 break;
5895 case L2CAP_EV_RECV_SREJ:
5896 l2cap_handle_srej(chan, control);
5897 break;
5898 default:
5899 break;
5900 }
5901
5902 if (skb && !skb_in_use) {
5903 BT_DBG("Freeing %p", skb);
5904 kfree_skb(skb);
5905 }
5906
5907 return err;
5908}
5909
5910static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5911 struct l2cap_ctrl *control,
5912 struct sk_buff *skb, u8 event)
5913{
5914 int err = 0;
5915 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005916 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005917
5918 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5919 event);
5920
5921 switch (event) {
5922 case L2CAP_EV_RECV_IFRAME:
5923 switch (l2cap_classify_txseq(chan, txseq)) {
5924 case L2CAP_TXSEQ_EXPECTED:
5925 /* Keep frame for reassembly later */
5926 l2cap_pass_to_tx(chan, control);
5927 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005928 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005929 BT_DBG("Queued %p (queue len %d)", skb,
5930 skb_queue_len(&chan->srej_q));
5931
5932 chan->expected_tx_seq = __next_seq(chan, txseq);
5933 break;
5934 case L2CAP_TXSEQ_EXPECTED_SREJ:
5935 l2cap_seq_list_pop(&chan->srej_list);
5936
5937 l2cap_pass_to_tx(chan, control);
5938 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005939 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005940 BT_DBG("Queued %p (queue len %d)", skb,
5941 skb_queue_len(&chan->srej_q));
5942
5943 err = l2cap_rx_queued_iframes(chan);
5944 if (err)
5945 break;
5946
5947 break;
5948 case L2CAP_TXSEQ_UNEXPECTED:
5949 /* Got a frame that can't be reassembled yet.
5950 * Save it for later, and send SREJs to cover
5951 * the missing frames.
5952 */
5953 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005954 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005955 BT_DBG("Queued %p (queue len %d)", skb,
5956 skb_queue_len(&chan->srej_q));
5957
5958 l2cap_pass_to_tx(chan, control);
5959 l2cap_send_srej(chan, control->txseq);
5960 break;
5961 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
5962 /* This frame was requested with an SREJ, but
5963 * some expected retransmitted frames are
5964 * missing. Request retransmission of missing
5965 * SREJ'd frames.
5966 */
5967 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005968 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005969 BT_DBG("Queued %p (queue len %d)", skb,
5970 skb_queue_len(&chan->srej_q));
5971
5972 l2cap_pass_to_tx(chan, control);
5973 l2cap_send_srej_list(chan, control->txseq);
5974 break;
5975 case L2CAP_TXSEQ_DUPLICATE_SREJ:
5976 /* We've already queued this frame. Drop this copy. */
5977 l2cap_pass_to_tx(chan, control);
5978 break;
5979 case L2CAP_TXSEQ_DUPLICATE:
5980 /* Expecting a later sequence number, so this frame
5981 * was already received. Ignore it completely.
5982 */
5983 break;
5984 case L2CAP_TXSEQ_INVALID_IGNORE:
5985 break;
5986 case L2CAP_TXSEQ_INVALID:
5987 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005988 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005989 break;
5990 }
5991 break;
5992 case L2CAP_EV_RECV_RR:
5993 l2cap_pass_to_tx(chan, control);
5994 if (control->final) {
5995 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5996
5997 if (!test_and_clear_bit(CONN_REJ_ACT,
5998 &chan->conn_state)) {
5999 control->final = 0;
6000 l2cap_retransmit_all(chan, control);
6001 }
6002
6003 l2cap_ertm_send(chan);
6004 } else if (control->poll) {
6005 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6006 &chan->conn_state) &&
6007 chan->unacked_frames) {
6008 __set_retrans_timer(chan);
6009 }
6010
6011 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6012 l2cap_send_srej_tail(chan);
6013 } else {
6014 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6015 &chan->conn_state) &&
6016 chan->unacked_frames)
6017 __set_retrans_timer(chan);
6018
6019 l2cap_send_ack(chan);
6020 }
6021 break;
6022 case L2CAP_EV_RECV_RNR:
6023 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6024 l2cap_pass_to_tx(chan, control);
6025 if (control->poll) {
6026 l2cap_send_srej_tail(chan);
6027 } else {
6028 struct l2cap_ctrl rr_control;
6029 memset(&rr_control, 0, sizeof(rr_control));
6030 rr_control.sframe = 1;
6031 rr_control.super = L2CAP_SUPER_RR;
6032 rr_control.reqseq = chan->buffer_seq;
6033 l2cap_send_sframe(chan, &rr_control);
6034 }
6035
6036 break;
6037 case L2CAP_EV_RECV_REJ:
6038 l2cap_handle_rej(chan, control);
6039 break;
6040 case L2CAP_EV_RECV_SREJ:
6041 l2cap_handle_srej(chan, control);
6042 break;
6043 }
6044
6045 if (skb && !skb_in_use) {
6046 BT_DBG("Freeing %p", skb);
6047 kfree_skb(skb);
6048 }
6049
6050 return err;
6051}
6052
Mat Martineau32b32732012-10-23 15:24:11 -07006053static int l2cap_finish_move(struct l2cap_chan *chan)
6054{
6055 BT_DBG("chan %p", chan);
6056
6057 chan->rx_state = L2CAP_RX_STATE_RECV;
6058
6059 if (chan->hs_hcon)
6060 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6061 else
6062 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6063
6064 return l2cap_resegment(chan);
6065}
6066
6067static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6068 struct l2cap_ctrl *control,
6069 struct sk_buff *skb, u8 event)
6070{
6071 int err;
6072
6073 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6074 event);
6075
6076 if (!control->poll)
6077 return -EPROTO;
6078
6079 l2cap_process_reqseq(chan, control->reqseq);
6080
6081 if (!skb_queue_empty(&chan->tx_q))
6082 chan->tx_send_head = skb_peek(&chan->tx_q);
6083 else
6084 chan->tx_send_head = NULL;
6085
6086 /* Rewind next_tx_seq to the point expected
6087 * by the receiver.
6088 */
6089 chan->next_tx_seq = control->reqseq;
6090 chan->unacked_frames = 0;
6091
6092 err = l2cap_finish_move(chan);
6093 if (err)
6094 return err;
6095
6096 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6097 l2cap_send_i_or_rr_or_rnr(chan);
6098
6099 if (event == L2CAP_EV_RECV_IFRAME)
6100 return -EPROTO;
6101
6102 return l2cap_rx_state_recv(chan, control, NULL, event);
6103}
6104
6105static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6106 struct l2cap_ctrl *control,
6107 struct sk_buff *skb, u8 event)
6108{
6109 int err;
6110
6111 if (!control->final)
6112 return -EPROTO;
6113
6114 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6115
6116 chan->rx_state = L2CAP_RX_STATE_RECV;
6117 l2cap_process_reqseq(chan, control->reqseq);
6118
6119 if (!skb_queue_empty(&chan->tx_q))
6120 chan->tx_send_head = skb_peek(&chan->tx_q);
6121 else
6122 chan->tx_send_head = NULL;
6123
6124 /* Rewind next_tx_seq to the point expected
6125 * by the receiver.
6126 */
6127 chan->next_tx_seq = control->reqseq;
6128 chan->unacked_frames = 0;
6129
6130 if (chan->hs_hcon)
6131 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6132 else
6133 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6134
6135 err = l2cap_resegment(chan);
6136
6137 if (!err)
6138 err = l2cap_rx_state_recv(chan, control, skb, event);
6139
6140 return err;
6141}
6142
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006143static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6144{
6145 /* Make sure reqseq is for a packet that has been sent but not acked */
6146 u16 unacked;
6147
6148 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6149 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6150}
6151
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006152static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6153 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006154{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006155 int err = 0;
6156
6157 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6158 control, skb, event, chan->rx_state);
6159
6160 if (__valid_reqseq(chan, control->reqseq)) {
6161 switch (chan->rx_state) {
6162 case L2CAP_RX_STATE_RECV:
6163 err = l2cap_rx_state_recv(chan, control, skb, event);
6164 break;
6165 case L2CAP_RX_STATE_SREJ_SENT:
6166 err = l2cap_rx_state_srej_sent(chan, control, skb,
6167 event);
6168 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006169 case L2CAP_RX_STATE_WAIT_P:
6170 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6171 break;
6172 case L2CAP_RX_STATE_WAIT_F:
6173 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6174 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006175 default:
6176 /* shut it down */
6177 break;
6178 }
6179 } else {
6180 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6181 control->reqseq, chan->next_tx_seq,
6182 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006183 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006184 }
6185
6186 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006187}
6188
6189static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6190 struct sk_buff *skb)
6191{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006192 int err = 0;
6193
6194 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6195 chan->rx_state);
6196
6197 if (l2cap_classify_txseq(chan, control->txseq) ==
6198 L2CAP_TXSEQ_EXPECTED) {
6199 l2cap_pass_to_tx(chan, control);
6200
6201 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6202 __next_seq(chan, chan->buffer_seq));
6203
6204 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6205
6206 l2cap_reassemble_sdu(chan, skb, control);
6207 } else {
6208 if (chan->sdu) {
6209 kfree_skb(chan->sdu);
6210 chan->sdu = NULL;
6211 }
6212 chan->sdu_last_frag = NULL;
6213 chan->sdu_len = 0;
6214
6215 if (skb) {
6216 BT_DBG("Freeing %p", skb);
6217 kfree_skb(skb);
6218 }
6219 }
6220
6221 chan->last_acked_seq = control->txseq;
6222 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6223
6224 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006225}
6226
6227static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6228{
6229 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6230 u16 len;
6231 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006232
Mat Martineaub76bbd62012-04-11 10:48:43 -07006233 __unpack_control(chan, skb);
6234
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006235 len = skb->len;
6236
6237 /*
6238 * We can just drop the corrupted I-frame here.
6239 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006240 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006241 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006242 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006243 goto drop;
6244
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006245 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006246 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006247
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006248 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006249 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006250
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006251 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006252 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006253 goto drop;
6254 }
6255
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006256 if (!control->sframe) {
6257 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006258
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006259 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6260 control->sar, control->reqseq, control->final,
6261 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006262
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006263 /* Validate F-bit - F=0 always valid, F=1 only
6264 * valid in TX WAIT_F
6265 */
6266 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006267 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006268
6269 if (chan->mode != L2CAP_MODE_STREAMING) {
6270 event = L2CAP_EV_RECV_IFRAME;
6271 err = l2cap_rx(chan, control, skb, event);
6272 } else {
6273 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006274 }
6275
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006276 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006277 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006278 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006279 const u8 rx_func_to_event[4] = {
6280 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6281 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6282 };
6283
6284 /* Only I-frames are expected in streaming mode */
6285 if (chan->mode == L2CAP_MODE_STREAMING)
6286 goto drop;
6287
6288 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6289 control->reqseq, control->final, control->poll,
6290 control->super);
6291
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006292 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006293 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006294 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006295 goto drop;
6296 }
6297
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006298 /* Validate F and P bits */
6299 if (control->final && (control->poll ||
6300 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6301 goto drop;
6302
6303 event = rx_func_to_event[control->super];
6304 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006305 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006306 }
6307
6308 return 0;
6309
6310drop:
6311 kfree_skb(skb);
6312 return 0;
6313}
6314
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006315static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6316 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006317{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006318 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006319
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006320 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006321 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006322 if (cid == L2CAP_CID_A2MP) {
6323 chan = a2mp_channel_create(conn, skb);
6324 if (!chan) {
6325 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006326 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006327 }
6328
6329 l2cap_chan_lock(chan);
6330 } else {
6331 BT_DBG("unknown cid 0x%4.4x", cid);
6332 /* Drop packet and return */
6333 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006334 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006335 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006336 }
6337
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006338 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006339
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006340 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006341 goto drop;
6342
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006343 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006344 case L2CAP_MODE_BASIC:
6345 /* If socket recv buffers overflows we drop data here
6346 * which is *bad* because L2CAP has to be reliable.
6347 * But we don't have any other choice. L2CAP doesn't
6348 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006349
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006350 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006351 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006352
Gustavo Padovan80b98022012-05-27 22:27:51 -03006353 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006354 goto done;
6355 break;
6356
6357 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006358 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006359 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006360 goto done;
6361
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006362 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006363 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006364 break;
6365 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006366
6367drop:
6368 kfree_skb(skb);
6369
6370done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006371 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006372}
6373
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006374static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6375 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006376{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006377 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006378 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006379
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006380 if (hcon->type != ACL_LINK)
6381 goto drop;
6382
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006383 chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006384 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006385 goto drop;
6386
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006387 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006388
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006389 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006390 goto drop;
6391
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006392 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006393 goto drop;
6394
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006395 /* Store remote BD_ADDR and PSM for msg_name */
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006396 bacpy(&bt_cb(skb)->bdaddr, &hcon->dst);
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006397 bt_cb(skb)->psm = psm;
6398
Gustavo Padovan80b98022012-05-27 22:27:51 -03006399 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006400 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006401
6402drop:
6403 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006404}
6405
Marcel Holtmann72f78352013-04-23 00:59:00 -07006406static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006407 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006408{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006409 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006410 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006411
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006412 if (hcon->type != LE_LINK)
6413 goto drop;
6414
Johan Hedbergaf1c0132013-04-29 19:35:42 +03006415 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006416 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006417 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006418 goto drop;
6419
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006420 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006421
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07006422 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, hcon->dst_type))
6423 goto drop;
6424
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006425 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006426 goto drop;
6427
Gustavo Padovan80b98022012-05-27 22:27:51 -03006428 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006429 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006430
6431drop:
6432 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006433}
6434
Linus Torvalds1da177e2005-04-16 15:20:36 -07006435static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6436{
6437 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006438 u16 cid, len;
6439 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006440
6441 skb_pull(skb, L2CAP_HDR_SIZE);
6442 cid = __le16_to_cpu(lh->cid);
6443 len = __le16_to_cpu(lh->len);
6444
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006445 if (len != skb->len) {
6446 kfree_skb(skb);
6447 return;
6448 }
6449
Linus Torvalds1da177e2005-04-16 15:20:36 -07006450 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6451
6452 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006453 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006454 l2cap_sig_channel(conn, skb);
6455 break;
6456
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006457 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006458 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006459 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006460 l2cap_conless_channel(conn, psm, skb);
6461 break;
6462
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006463 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006464 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006465 break;
6466
Marcel Holtmanna2877622013-10-02 23:46:54 -07006467 case L2CAP_CID_LE_SIGNALING:
6468 l2cap_le_sig_channel(conn, skb);
6469 break;
6470
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006471 case L2CAP_CID_SMP:
6472 if (smp_sig_channel(conn, skb))
6473 l2cap_conn_del(conn->hcon, EACCES);
6474 break;
6475
Linus Torvalds1da177e2005-04-16 15:20:36 -07006476 default:
6477 l2cap_data_channel(conn, cid, skb);
6478 break;
6479 }
6480}
6481
6482/* ---- L2CAP interface with lower layer (HCI) ---- */
6483
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006484int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006485{
6486 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006487 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006488
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006489 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006490
6491 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006492 read_lock(&chan_list_lock);
6493 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006494 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006495 continue;
6496
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006497 if (!bacmp(&c->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006498 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006499 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006500 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006501 exact++;
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006502 } else if (!bacmp(&c->src, BDADDR_ANY)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006503 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006504 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006505 lm2 |= HCI_LM_MASTER;
6506 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006507 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006508 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006509
6510 return exact ? lm1 : lm2;
6511}
6512
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006513void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006514{
Marcel Holtmann01394182006-07-03 10:02:46 +02006515 struct l2cap_conn *conn;
6516
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006517 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006518
Linus Torvalds1da177e2005-04-16 15:20:36 -07006519 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006520 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006521 if (conn)
6522 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006523 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006524 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006525 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006526}
6527
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006528int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006529{
6530 struct l2cap_conn *conn = hcon->l2cap_data;
6531
6532 BT_DBG("hcon %p", hcon);
6533
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006534 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006535 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006536 return conn->disc_reason;
6537}
6538
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006539void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006540{
6541 BT_DBG("hcon %p reason %d", hcon, reason);
6542
Joe Perchese1750722011-06-29 18:18:29 -07006543 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006544}
6545
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006546static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006547{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006548 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006549 return;
6550
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006551 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006552 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006553 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006554 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006555 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006556 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006557 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006558 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006559 }
6560}
6561
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006562int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006563{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006564 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006565 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006566
Marcel Holtmann01394182006-07-03 10:02:46 +02006567 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006568 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006569
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006570 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006571
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006572 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306573 if (!status && encrypt)
6574 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006575 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006576 }
6577
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006578 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006579
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006580 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006581 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006582
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006583 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6584 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006585
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006586 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6587 l2cap_chan_unlock(chan);
6588 continue;
6589 }
6590
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006591 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006592 if (!status && encrypt) {
6593 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006594 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006595 }
6596
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006597 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006598 continue;
6599 }
6600
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006601 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006602 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006603 continue;
6604 }
6605
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006606 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006607 chan->state == BT_CONFIG)) {
Marcel Holtmannd97c8992013-10-14 02:53:54 -07006608 chan->ops->resume(chan);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006609 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006610 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006611 continue;
6612 }
6613
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006614 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006615 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006616 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006617 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006618 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006619 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006620 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006621 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006622 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006623
6624 if (!status) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07006625 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006626 res = L2CAP_CR_PEND;
6627 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006628 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006629 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02006630 l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006631 res = L2CAP_CR_SUCCESS;
6632 stat = L2CAP_CS_NO_INFO;
6633 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006634 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02006635 l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006636 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006637 res = L2CAP_CR_SEC_BLOCK;
6638 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006639 }
6640
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006641 rsp.scid = cpu_to_le16(chan->dcid);
6642 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006643 rsp.result = cpu_to_le16(res);
6644 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006645 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006646 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006647
6648 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6649 res == L2CAP_CR_SUCCESS) {
6650 char buf[128];
6651 set_bit(CONF_REQ_SENT, &chan->conf_state);
6652 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6653 L2CAP_CONF_REQ,
6654 l2cap_build_conf_req(chan, buf),
6655 buf);
6656 chan->num_conf_req++;
6657 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006658 }
6659
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006660 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006661 }
6662
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006663 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006664
Linus Torvalds1da177e2005-04-16 15:20:36 -07006665 return 0;
6666}
6667
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006668int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006669{
6670 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006671 struct l2cap_hdr *hdr;
6672 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006673
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006674 /* For AMP controller do not create l2cap conn */
6675 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6676 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006677
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006678 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006679 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006680
6681 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006682 goto drop;
6683
6684 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6685
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006686 switch (flags) {
6687 case ACL_START:
6688 case ACL_START_NO_FLUSH:
6689 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006690 if (conn->rx_len) {
6691 BT_ERR("Unexpected start frame (len %d)", skb->len);
6692 kfree_skb(conn->rx_skb);
6693 conn->rx_skb = NULL;
6694 conn->rx_len = 0;
6695 l2cap_conn_unreliable(conn, ECOMM);
6696 }
6697
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006698 /* Start fragment always begin with Basic L2CAP header */
6699 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006700 BT_ERR("Frame is too short (len %d)", skb->len);
6701 l2cap_conn_unreliable(conn, ECOMM);
6702 goto drop;
6703 }
6704
6705 hdr = (struct l2cap_hdr *) skb->data;
6706 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6707
6708 if (len == skb->len) {
6709 /* Complete frame received */
6710 l2cap_recv_frame(conn, skb);
6711 return 0;
6712 }
6713
6714 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6715
6716 if (skb->len > len) {
6717 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006718 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006719 l2cap_conn_unreliable(conn, ECOMM);
6720 goto drop;
6721 }
6722
6723 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006724 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006725 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006726 goto drop;
6727
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006728 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006729 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006730 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006731 break;
6732
6733 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006734 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6735
6736 if (!conn->rx_len) {
6737 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6738 l2cap_conn_unreliable(conn, ECOMM);
6739 goto drop;
6740 }
6741
6742 if (skb->len > conn->rx_len) {
6743 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006744 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006745 kfree_skb(conn->rx_skb);
6746 conn->rx_skb = NULL;
6747 conn->rx_len = 0;
6748 l2cap_conn_unreliable(conn, ECOMM);
6749 goto drop;
6750 }
6751
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006752 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006753 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006754 conn->rx_len -= skb->len;
6755
6756 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006757 /* Complete frame received. l2cap_recv_frame
6758 * takes ownership of the skb so set the global
6759 * rx_skb pointer to NULL first.
6760 */
6761 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006762 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006763 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006764 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006765 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006766 }
6767
6768drop:
6769 kfree_skb(skb);
6770 return 0;
6771}
6772
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006773static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006774{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006775 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006776
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006777 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006778
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006779 list_for_each_entry(c, &chan_list, global_l) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006780 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 -07006781 &c->src, &c->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006782 c->state, __le16_to_cpu(c->psm),
6783 c->scid, c->dcid, c->imtu, c->omtu,
6784 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006785 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006786
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006787 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006788
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006789 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006790}
6791
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006792static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6793{
6794 return single_open(file, l2cap_debugfs_show, inode->i_private);
6795}
6796
6797static const struct file_operations l2cap_debugfs_fops = {
6798 .open = l2cap_debugfs_open,
6799 .read = seq_read,
6800 .llseek = seq_lseek,
6801 .release = single_release,
6802};
6803
6804static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006805
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006806int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006807{
6808 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006809
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006810 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006811 if (err < 0)
6812 return err;
6813
Marcel Holtmann1120e4b2013-10-17 17:24:16 -07006814 if (IS_ERR_OR_NULL(bt_debugfs))
6815 return 0;
6816
6817 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6818 NULL, &l2cap_debugfs_fops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006819
Linus Torvalds1da177e2005-04-16 15:20:36 -07006820 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006821}
6822
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006823void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006824{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006825 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006826 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006827}
6828
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006829module_param(disable_ertm, bool, 0644);
6830MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");